robust_excel_ole 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|