robust_excel_ole 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +73 -26
- data/README_detail.rdoc +92 -27
- data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
- data/examples/edit_sheets/example_concating.rb +12 -12
- data/examples/edit_sheets/example_copying.rb +47 -0
- data/examples/edit_sheets/example_expanding.rb +17 -26
- data/examples/edit_sheets/example_naming.rb +13 -10
- data/examples/edit_sheets/example_ranges.rb +2 -2
- data/examples/edit_sheets/example_saving.rb +8 -14
- data/examples/open_save_close/example_control_to_excel.rb +1 -1
- data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
- data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
- data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
- data/examples/open_save_close/example_if_unsaved_forget.rb +4 -4
- data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
- data/examples/open_save_close/example_read_only.rb +1 -1
- data/examples/open_save_close/example_rename_cells.rb +1 -13
- data/examples/open_save_close/example_simple.rb +1 -1
- data/examples/open_save_close/example_unobtrusively.rb +3 -3
- data/lib/robust_excel_ole.rb +81 -2
- data/lib/robust_excel_ole/book.rb +171 -118
- data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
- data/lib/robust_excel_ole/excel.rb +153 -24
- data/lib/robust_excel_ole/range.rb +2 -2
- data/lib/robust_excel_ole/sheet.rb +84 -35
- data/lib/robust_excel_ole/version.rb +1 -1
- data/reo.bat +3 -0
- data/spec/book_close_spec.rb +179 -0
- data/spec/book_misc_spec.rb +365 -0
- data/spec/book_open_spec.rb +793 -0
- data/spec/book_save_spec.rb +257 -0
- data/spec/book_sheet_spec.rb +160 -0
- data/spec/book_spec.rb +145 -1533
- data/spec/book_subclass_spec.rb +50 -0
- data/spec/book_unobtr_spec.rb +950 -0
- data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
- data/spec/cell_spec.rb +6 -6
- data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
- data/spec/data/different_workbook.xls +0 -0
- data/spec/data/workbook.xls +0 -0
- data/spec/data/workbook.xlsm +0 -0
- data/spec/data/workbook.xlsx +0 -0
- data/spec/data/workbook_linked.xlsm +0 -0
- data/spec/data/workbook_linked_sub.xlsm +0 -0
- data/spec/excel_spec.rb +204 -5
- data/spec/range_spec.rb +6 -6
- data/spec/sheet_spec.rb +122 -34
- metadata +18 -8
- data/spec/data/workbook_connected_sub.xlsm +0 -0
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# -*- coding: utf-8 -*-
|
3
2
|
|
4
3
|
require 'weakref'
|
@@ -11,12 +10,14 @@ module RobustExcelOle
|
|
11
10
|
attr_accessor :stored_filename
|
12
11
|
attr_accessor :options
|
13
12
|
|
13
|
+
|
14
14
|
DEFAULT_OPEN_OPTS = {
|
15
15
|
:excel => :reuse,
|
16
16
|
:default_excel => :reuse,
|
17
|
-
:
|
17
|
+
:if_lockraiseed => :readonly,
|
18
18
|
:if_unsaved => :raise,
|
19
19
|
:if_obstructed => :raise,
|
20
|
+
:if_absent => :raise,
|
20
21
|
:read_only => false
|
21
22
|
}
|
22
23
|
|
@@ -51,8 +52,9 @@ module RobustExcelOle
|
|
51
52
|
# :close_if_saved -> close the old book and open the new book, if the old book is saved,
|
52
53
|
# otherwise raise an exception.
|
53
54
|
# :new_excel -> open the new book in a new Excel
|
54
|
-
# :if_absent :
|
55
|
-
# :
|
55
|
+
# :if_absent :raise (default) -> raises an exception , if the file does not exists
|
56
|
+
# :create -> creates a new Excel file, if it does not exists
|
57
|
+
#
|
56
58
|
# :read_only open in read-only mode (default: false)
|
57
59
|
# :displayalerts enable DisplayAlerts in Excel (default: false)
|
58
60
|
# :visible make visible in Excel (default: false)
|
@@ -63,19 +65,18 @@ module RobustExcelOle
|
|
63
65
|
book = nil
|
64
66
|
if (not (current_options[:force_excel] == :new && (not current_options[:if_locked] == :take_writable)))
|
65
67
|
# if readonly is true, then prefer a book that is given in force_excel if this option is set
|
66
|
-
book =
|
68
|
+
book = bookstore.fetch(file,
|
67
69
|
:prefer_writable => (not current_options[:read_only]),
|
68
|
-
:prefer_excel => (current_options[:read_only] ?
|
70
|
+
:prefer_excel => (current_options[:read_only] ? current_options[:force_excel].excel : nil)) rescue nil
|
69
71
|
if book
|
70
|
-
|
71
|
-
if (((not current_options[:force_excel]) || (Book.excel(current_options[:force_excel]) == book.excel)) &&
|
72
|
+
if (((not current_options[:force_excel]) || (current_options[:force_excel].excel == book.excel)) &&
|
72
73
|
(not (book.alive? && (not book.saved) && (not current_options[:if_unsaved] == :accept))))
|
73
74
|
book.options = DEFAULT_OPEN_OPTS.merge(opts)
|
74
75
|
book.get_excel unless book.excel.alive?
|
75
76
|
# if the book is opened as readonly and should be opened as writable, then close it and open the book with the new readonly mode
|
76
77
|
book.close if (book.alive? && (not book.writable) && (not current_options[:read_only]))
|
77
78
|
# reopen the book
|
78
|
-
book.get_workbook unless book.alive?
|
79
|
+
book.get_workbook(file) unless book.alive?
|
79
80
|
return book
|
80
81
|
end
|
81
82
|
end
|
@@ -86,11 +87,10 @@ module RobustExcelOle
|
|
86
87
|
end
|
87
88
|
|
88
89
|
def initialize(file, opts={ }, &block)
|
89
|
-
@options = DEFAULT_OPEN_OPTS.merge(opts)
|
90
|
-
@file = file
|
90
|
+
@options = DEFAULT_OPEN_OPTS.merge(opts)
|
91
91
|
get_excel
|
92
|
-
get_workbook
|
93
|
-
|
92
|
+
get_workbook file
|
93
|
+
bookstore.store(self)
|
94
94
|
if block
|
95
95
|
begin
|
96
96
|
yield self
|
@@ -99,20 +99,33 @@ module RobustExcelOle
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
102
|
+
|
103
|
+
def self.excel_class
|
104
|
+
@excel_class ||= begin
|
105
|
+
module_name = self.parent_name
|
106
|
+
"#{module_name}::Excel".constantize
|
107
|
+
rescue NameError => e
|
108
|
+
Excel
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def excel_class
|
113
|
+
self.class.excel_class
|
114
|
+
end
|
115
|
+
|
102
116
|
|
103
117
|
def get_excel
|
104
118
|
if @options[:excel] == :reuse
|
105
|
-
@excel =
|
119
|
+
@excel = excel_class.new(:reuse => true)
|
106
120
|
end
|
107
121
|
@excel_options = nil
|
108
122
|
if (not @excel)
|
109
123
|
if @options[:excel] == :new
|
110
124
|
@excel_options = {:displayalerts => false, :visible => false}.merge(@options)
|
111
125
|
@excel_options[:reuse] = false
|
112
|
-
@excel =
|
126
|
+
@excel = excel_class.new(@excel_options)
|
113
127
|
else
|
114
|
-
@excel = @options[:excel]
|
115
|
-
@excel = Book.excel(@options[:excel])
|
128
|
+
@excel = @options[:excel].excel
|
116
129
|
end
|
117
130
|
end
|
118
131
|
# if :excel => :new or (:excel => :reuse but could not reuse)
|
@@ -123,39 +136,46 @@ module RobustExcelOle
|
|
123
136
|
end
|
124
137
|
end
|
125
138
|
|
126
|
-
def get_workbook
|
127
|
-
|
128
|
-
|
139
|
+
def get_workbook file
|
140
|
+
file = @stored_filename ? @stored_filename : file
|
141
|
+
unless File.exist?(file)
|
142
|
+
if @options[:if_absent] == :create
|
143
|
+
@workbook = excel_class.current.generate_workbook(file)
|
144
|
+
else
|
145
|
+
raise ExcelErrorOpen, "file #{file} not found"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
@workbook = @excel.Workbooks.Item(File.basename(file)) rescue nil
|
129
149
|
if @workbook then
|
130
|
-
obstructed_by_other_book = (File.basename(
|
131
|
-
(not (RobustExcelOle::absolute_path(
|
150
|
+
obstructed_by_other_book = (File.basename(file) == File.basename(@workbook.Fullname)) &&
|
151
|
+
(not (RobustExcelOle::absolute_path(file) == @workbook.Fullname))
|
132
152
|
# if book is obstructed by a book with same name and different path
|
133
153
|
if obstructed_by_other_book then
|
134
154
|
case @options[:if_obstructed]
|
135
155
|
when :raise
|
136
|
-
raise ExcelErrorOpen, "blocked by a book with the same name in a different path: #{File.basename(
|
156
|
+
raise ExcelErrorOpen, "blocked by a book with the same name in a different path: #{File.basename(file)}"
|
137
157
|
when :forget
|
138
158
|
@workbook.Close
|
139
159
|
@workbook = nil
|
140
|
-
open_or_create_workbook
|
160
|
+
open_or_create_workbook file
|
141
161
|
when :save
|
142
162
|
save unless @workbook.Saved
|
143
163
|
@workbook.Close
|
144
164
|
@workbook = nil
|
145
|
-
open_or_create_workbook
|
165
|
+
open_or_create_workbook file
|
146
166
|
when :close_if_saved
|
147
167
|
if (not @workbook.Saved) then
|
148
|
-
raise ExcelErrorOpen, "book with the same name in a different path is unsaved: #{File.basename(
|
168
|
+
raise ExcelErrorOpen, "book with the same name in a different path is unsaved: #{File.basename(file)}"
|
149
169
|
else
|
150
170
|
@workbook.Close
|
151
171
|
@workbook = nil
|
152
|
-
open_or_create_workbook
|
172
|
+
open_or_create_workbook file
|
153
173
|
end
|
154
174
|
when :new_excel
|
155
175
|
@excel_options = {:displayalerts => false, :visible => false}.merge(@options)
|
156
176
|
@excel_options[:reuse] = false
|
157
|
-
@excel =
|
158
|
-
open_or_create_workbook
|
177
|
+
@excel = excel_class.new(@excel_options)
|
178
|
+
open_or_create_workbook file
|
159
179
|
else
|
160
180
|
raise ExcelErrorOpen, ":if_obstructed: invalid option: #{@options[:if_obstructed]}"
|
161
181
|
end
|
@@ -164,22 +184,22 @@ module RobustExcelOle
|
|
164
184
|
if (not @workbook.Saved) then
|
165
185
|
case @options[:if_unsaved]
|
166
186
|
when :raise
|
167
|
-
raise ExcelErrorOpen, "book is already open but not saved (#{File.basename(
|
187
|
+
raise ExcelErrorOpen, "book is already open but not saved (#{File.basename(file)})"
|
168
188
|
when :forget
|
169
189
|
@workbook.Close
|
170
190
|
@workbook = nil
|
171
|
-
open_or_create_workbook
|
191
|
+
open_or_create_workbook file
|
172
192
|
when :accept
|
173
193
|
# do nothing
|
174
194
|
when :alert
|
175
195
|
@excel.with_displayalerts true do
|
176
|
-
open_or_create_workbook
|
196
|
+
open_or_create_workbook file
|
177
197
|
end
|
178
198
|
when :new_excel
|
179
199
|
@excel_options = {:displayalerts => false, :visible => false}.merge(@options)
|
180
200
|
@excel_options[:reuse] = false
|
181
|
-
@excel =
|
182
|
-
open_or_create_workbook
|
201
|
+
@excel = excel_class.new(@excel_options)
|
202
|
+
open_or_create_workbook file
|
183
203
|
else
|
184
204
|
raise ExcelErrorOpen, ":if_unsaved: invalid option: #{@options[:if_unsaved]}"
|
185
205
|
end
|
@@ -187,23 +207,24 @@ module RobustExcelOle
|
|
187
207
|
end
|
188
208
|
else
|
189
209
|
# book is not open
|
190
|
-
open_or_create_workbook
|
210
|
+
open_or_create_workbook file
|
191
211
|
end
|
192
212
|
end
|
193
213
|
|
194
|
-
def open_or_create_workbook
|
195
|
-
if (not File.exist?(@file))
|
196
|
-
@workbook = Excel.current.generate_workbook(@file)
|
197
|
-
return
|
198
|
-
end
|
214
|
+
def open_or_create_workbook file
|
199
215
|
if ((not @workbook) || (@options[:if_unsaved] == :alert) || @options[:if_obstructed]) then
|
200
216
|
begin
|
201
|
-
filename = RobustExcelOle::absolute_path(
|
202
|
-
|
217
|
+
filename = RobustExcelOle::absolute_path(file)
|
218
|
+
begin
|
219
|
+
workbooks = @excel.Workbooks
|
220
|
+
rescue RuntimeError => msg
|
221
|
+
puts "RuntimeError: #{msg.message}"
|
222
|
+
raise ExcelErrorOpen, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
|
223
|
+
end
|
203
224
|
workbooks.Open(filename,{ 'ReadOnly' => @options[:read_only] })
|
204
225
|
rescue WIN32OLERuntimeError => msg
|
205
|
-
puts "
|
206
|
-
raise ExcelErrorOpen, "open: user canceled or open error" if msg.message =~ /
|
226
|
+
puts "WIN32OLERuntimeError: #{msg.message}"
|
227
|
+
raise ExcelErrorOpen, "open: user canceled or open error" if msg.message =~ /800A03EC/
|
207
228
|
end
|
208
229
|
begin
|
209
230
|
# workaround for bug in Excel 2010: workbook.Open does not always return
|
@@ -215,20 +236,6 @@ module RobustExcelOle
|
|
215
236
|
end
|
216
237
|
end
|
217
238
|
|
218
|
-
private
|
219
|
-
|
220
|
-
# return an Excel.
|
221
|
-
# return the given instance if it is an Excel and alive. If the given instance is a Book then take the Excel of the Book
|
222
|
-
def self.excel(instance)
|
223
|
-
raise ExcelErrorOpen, "provided instance is neither an Excel nor a Book: #{instance}" \
|
224
|
-
unless instance.is_a?(Excel) || instance.is_a?(Book)
|
225
|
-
excel = instance.is_a?(Book) ? instance.excel : instance
|
226
|
-
raise ExcelErrorOpen, "provided Excel instance is not alive" unless excel.alive?
|
227
|
-
excel
|
228
|
-
end
|
229
|
-
|
230
|
-
public
|
231
|
-
|
232
239
|
# closes the book, if it is alive
|
233
240
|
#
|
234
241
|
# options:
|
@@ -269,91 +276,113 @@ module RobustExcelOle
|
|
269
276
|
|
270
277
|
public
|
271
278
|
|
279
|
+
def self.for_reading(*args, &block)
|
280
|
+
args = args.dup
|
281
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
282
|
+
opts = {:read_only => true}.merge(opts)
|
283
|
+
args.push opts
|
284
|
+
unobtrusively(*args, &block)
|
285
|
+
end
|
286
|
+
|
287
|
+
def self.for_modifying(*args, &block)
|
288
|
+
args = args.dup
|
289
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
290
|
+
opts = {:read_only => false}.merge(opts)
|
291
|
+
args.push opts
|
292
|
+
unobtrusively(*args, &block)
|
293
|
+
end
|
294
|
+
|
272
295
|
# modify a book such that its state (open/close, saved/unsaved, readonly/writable) remains unchanged.
|
273
|
-
# options:
|
274
|
-
# :
|
275
|
-
#
|
276
|
-
#
|
296
|
+
# options:
|
297
|
+
# :reuse (default) : open closed books in the Excel instance of the book, if it exists, reuse another Excel, otherwise
|
298
|
+
# :hidden : open closed books in one separate Excel instance that is not visible and has no displayaslerts
|
299
|
+
# <excel-instance> : open closed books in the given Excel instance
|
277
300
|
# :read_only: Open the book unobtrusively for reading only (default: false)
|
278
|
-
# :
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
301
|
+
# :readonly_excel: if the book is opened only as ReadOnly and shall be modified, then
|
302
|
+
# true: close it and open it as writable in the excel instance where it was open so far
|
303
|
+
# false (default) open it as writable in another running excel instance, if it exists,
|
304
|
+
# otherwise open in a new excel instance.
|
282
305
|
# :keep_open: let the book open after unobtrusively opening (default: false)
|
283
|
-
def self.unobtrusively(file, opts = { })
|
306
|
+
def self.unobtrusively(file, if_closed = nil, opts = { }, &block)
|
307
|
+
if if_closed.is_a? Hash
|
308
|
+
opts = if_closed
|
309
|
+
if_closed = nil
|
310
|
+
end
|
311
|
+
if_closed = :reuse unless if_closed
|
284
312
|
options = {
|
285
|
-
:if_closed => :hidden,
|
286
313
|
:read_only => false,
|
287
|
-
:
|
314
|
+
:readonly_excel => false,
|
288
315
|
:keep_open => false,
|
289
316
|
}.merge(opts)
|
290
|
-
book =
|
317
|
+
book = bookstore.fetch(file, :prefer_writable => (not options[:read_only]))
|
291
318
|
was_not_alive_or_nil = book.nil? || (not book.alive?)
|
292
319
|
was_saved = was_not_alive_or_nil ? true : book.saved
|
293
320
|
was_writable = book.writable unless was_not_alive_or_nil
|
294
321
|
begin
|
295
322
|
book =
|
296
323
|
if was_not_alive_or_nil
|
297
|
-
case
|
298
|
-
when :hidden
|
299
|
-
open(file, :force_excel => book_store.hidden_excel)
|
324
|
+
case if_closed
|
300
325
|
when :reuse
|
301
|
-
open(file)
|
326
|
+
open(file, :read_only => options[:read_only])
|
327
|
+
when :hidden
|
328
|
+
open(file, :force_excel => bookstore.hidden_excel, :read_only => options[:read_only])
|
302
329
|
else
|
303
|
-
open(file, :force_excel => options[:
|
330
|
+
open(file, :force_excel => if_closed, :read_only => options[:read_only])
|
304
331
|
end
|
305
332
|
else
|
306
333
|
if was_writable || options[:read_only]
|
307
334
|
book
|
308
335
|
else
|
309
|
-
options[:
|
336
|
+
options[:readonly_excel] ? open(file, :force_excel => book.excel, :read_only => options[:read_only]) :
|
337
|
+
open(file, :force_excel => :new, :read_only => options[:read_only])
|
310
338
|
end
|
311
339
|
end
|
312
340
|
yield book
|
313
341
|
ensure
|
314
|
-
book.save if (was_not_alive_or_nil || was_saved || ((not was_writable) && (not options[:read_only])
|
342
|
+
book.save if (was_not_alive_or_nil || was_saved || ((not options[:read_only]) && (not was_writable))) && (not options[:read_only]) && book && (not book.saved)
|
315
343
|
# book was open, readonly and shoud be modified
|
316
|
-
if (not was_not_alive_or_nil) && (not options[:read_only]) && (not was_writable) && options[:
|
344
|
+
if (not was_not_alive_or_nil) && (not options[:read_only]) && (not was_writable) && options[:readonly_excel]
|
317
345
|
open(file, :force_excel => book.excel, :if_obstructed => :new_excel, :read_only => true)
|
318
346
|
end
|
319
347
|
book.close if (was_not_alive_or_nil && (not opts[:keep_open]) && book)
|
320
348
|
end
|
321
349
|
end
|
322
350
|
|
351
|
+
def reopen
|
352
|
+
self.class.open(self.stored_filename)
|
353
|
+
end
|
354
|
+
|
323
355
|
# rename a range
|
324
356
|
def rename_range(name,new_name)
|
325
357
|
begin
|
326
|
-
p "name: #{name}"
|
327
|
-
p "new_name: #{new_name}"
|
328
358
|
item = self.Names.Item(name)
|
329
|
-
p "nil" if item.nil?
|
330
359
|
rescue WIN32OLERuntimeError
|
331
|
-
raise
|
360
|
+
raise ExcelError, "name #{name} not in #{File.basename(self.stored_filename)}"
|
332
361
|
end
|
333
362
|
begin
|
334
363
|
item.Name = new_name
|
335
364
|
rescue WIN32OLERuntimeError
|
336
|
-
raise
|
365
|
+
raise ExcelError, "name error in #{File.basename(self.stored_filename)}"
|
337
366
|
end
|
338
367
|
end
|
339
368
|
|
340
369
|
# returns the contents of a range with given name
|
341
|
-
|
370
|
+
# if no contents could returned, then return default value, if a default value was provided
|
371
|
+
# raise an error, otherwise
|
372
|
+
def nvalue(name, opts = {:default => nil})
|
342
373
|
begin
|
343
374
|
item = self.Names.Item(name)
|
344
375
|
rescue WIN32OLERuntimeError
|
345
|
-
|
376
|
+
return opts[:default] if opts[:default]
|
377
|
+
raise ExcelErrorNValue, "name #{name} not in #{File.basename(self.stored_filename)}"
|
346
378
|
end
|
347
379
|
begin
|
348
|
-
|
349
|
-
rescue
|
350
|
-
|
351
|
-
|
352
|
-
begin
|
353
|
-
referstorange.Value
|
354
|
-
rescue WIN32OLERuntimeError
|
355
|
-
raise ExcelErrorNValue, "value error in #{File.basename(self.stored_filename)}"
|
380
|
+
value = item.RefersToRange.Value
|
381
|
+
rescue WIN32OLERuntimeError
|
382
|
+
return opts[:default] if opts[:default]
|
383
|
+
raise ExcelErrorNValue, "RefersToRange error of name #{name} in #{File.basename(self.stored_filename)}"
|
356
384
|
end
|
385
|
+
value
|
357
386
|
end
|
358
387
|
|
359
388
|
# set the contents of a range with given name
|
@@ -364,14 +393,19 @@ module RobustExcelOle
|
|
364
393
|
raise ExcelErrorNValue, "name #{name} not in #{File.basename(self.stored_filename)}"
|
365
394
|
end
|
366
395
|
begin
|
367
|
-
|
396
|
+
item.RefersToRange.Value = value
|
368
397
|
rescue WIN32OLERuntimeError
|
369
|
-
raise ExcelErrorNValue, "
|
398
|
+
raise ExcelErrorNValue, "RefersToRange error of name #{name} in #{File.basename(self.stored_filename)}"
|
370
399
|
end
|
400
|
+
end
|
401
|
+
|
402
|
+
def activate
|
403
|
+
@excel.visible = true
|
371
404
|
begin
|
372
|
-
|
405
|
+
self.Activate
|
406
|
+
self.ActiveSheet.Activate
|
373
407
|
rescue WIN32OLERuntimeError
|
374
|
-
raise
|
408
|
+
raise ExcelError, "cannot activate"
|
375
409
|
end
|
376
410
|
end
|
377
411
|
|
@@ -474,7 +508,7 @@ module RobustExcelOle
|
|
474
508
|
when '.xlsm': RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
|
475
509
|
end
|
476
510
|
@workbook.SaveAs(RobustExcelOle::absolute_path(file), file_format)
|
477
|
-
|
511
|
+
bookstore.store(self)
|
478
512
|
rescue WIN32OLERuntimeError => msg
|
479
513
|
if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
|
480
514
|
if @opts[:if_exists] == :alert then
|
@@ -491,9 +525,24 @@ module RobustExcelOle
|
|
491
525
|
|
492
526
|
public
|
493
527
|
|
494
|
-
|
495
|
-
|
496
|
-
|
528
|
+
# returns a sheet, if a name of a sheet or a number is given
|
529
|
+
# returns the value of the range, if a global name of a range in the book is given
|
530
|
+
def [] name
|
531
|
+
name += 1 if name.is_a? Numeric
|
532
|
+
begin
|
533
|
+
RobustExcelOle::Sheet.new(@workbook.Worksheets.Item(name))
|
534
|
+
rescue WIN32OLERuntimeError => msg
|
535
|
+
if msg.message =~ /8002000B/
|
536
|
+
nvalue(name)
|
537
|
+
else
|
538
|
+
raise ExcelError, "could neither return a sheet nor a value of a range when giving the name #{name}"
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
# set the value of a range given its name
|
544
|
+
def []= (name, value)
|
545
|
+
set_nvalue(name,value)
|
497
546
|
end
|
498
547
|
|
499
548
|
def each
|
@@ -507,35 +556,40 @@ module RobustExcelOle
|
|
507
556
|
opts = sheet
|
508
557
|
sheet = nil
|
509
558
|
end
|
510
|
-
|
511
559
|
new_sheet_name = opts.delete(:as)
|
512
|
-
|
513
560
|
ws = @workbook.Worksheets
|
514
|
-
after_or_before, base_sheet = opts.to_a.first ||
|
515
|
-
|
516
|
-
base_sheet = base_sheet.sheet
|
561
|
+
after_or_before, base_sheet = opts.to_a.first || [:after, Sheet.new(ws.Item(ws.Count))]
|
562
|
+
base_sheet = base_sheet.worksheet
|
517
563
|
sheet ? sheet.Copy({ after_or_before.to_s => base_sheet }) : @workbook.WorkSheets.Add({ after_or_before.to_s => base_sheet })
|
518
564
|
new_sheet = RobustExcelOle::Sheet.new(@excel.Activesheet)
|
519
565
|
begin
|
520
566
|
new_sheet.name = new_sheet_name if new_sheet_name
|
521
567
|
rescue WIN32OLERuntimeError => msg
|
522
|
-
if msg.message =~ /
|
568
|
+
if msg.message =~ /800A03EC/
|
523
569
|
raise ExcelErrorSheet, "sheet name already exists"
|
570
|
+
else
|
571
|
+
puts "#{msg.message}"
|
572
|
+
raise ExcelErrorSheetUnknown
|
524
573
|
end
|
525
574
|
end
|
526
575
|
new_sheet
|
527
|
-
end
|
576
|
+
end
|
528
577
|
|
529
|
-
def
|
578
|
+
def self.bookstore
|
579
|
+
@@bookstore ||= Bookstore.new
|
530
580
|
end
|
531
581
|
|
532
|
-
def
|
533
|
-
|
582
|
+
def bookstore
|
583
|
+
self.class.bookstore
|
584
|
+
end
|
585
|
+
|
586
|
+
def to_s
|
587
|
+
"<#BOOK:" + "#{"not alive " unless alive?}" + "#{File.basename(@stored_filename)}" + " #{@workbook} #{@excel}" + ">"
|
534
588
|
end
|
535
589
|
|
536
|
-
def
|
537
|
-
self.
|
538
|
-
end
|
590
|
+
def inspect
|
591
|
+
self.to_s
|
592
|
+
end
|
539
593
|
|
540
594
|
private
|
541
595
|
|
@@ -577,10 +631,7 @@ public
|
|
577
631
|
class ExcelErrorSaveUnknown < ExcelErrorSave # :nodoc: #
|
578
632
|
end
|
579
633
|
|
580
|
-
class
|
581
|
-
end
|
582
|
-
|
583
|
-
class ExcelErrorNValue < WIN32OLERuntimeError # :nodoc: #
|
634
|
+
class ExcelErrorNValue < ExcelError # :nodoc: #
|
584
635
|
end
|
585
636
|
|
586
637
|
class ExcelUserCanceled < RuntimeError # :nodoc: #
|
@@ -589,4 +640,6 @@ public
|
|
589
640
|
class ExcelErrorSheet < ExcelError # :nodoc: #
|
590
641
|
end
|
591
642
|
|
643
|
+
class ExcelErrorSheetUnknown < ExcelErrorSheet # :nodoc: #
|
644
|
+
end
|
592
645
|
end
|