robust_excel_ole 1.16 → 1.18.3
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.
- checksums.yaml +4 -4
- data/Changelog +23 -0
- data/README.rdoc +17 -0
- data/benchmarking/Gemfile +7 -0
- data/benchmarking/README.md +131 -0
- data/benchmarking/creek_example.rb +33 -0
- data/benchmarking/generating_excel_files.rb +28 -0
- data/benchmarking/reo_example.rb +26 -0
- data/benchmarking/reo_example1.rb +31 -0
- data/benchmarking/reo_example2.rb +26 -0
- data/benchmarking/roo_example.rb +33 -0
- data/benchmarking/ruby_xl_example.rb +36 -0
- data/benchmarking/sample_excel_files/xlsx_500_rows.xlsx +0 -0
- data/benchmarking/simple_xlsx_reader_example.rb +33 -0
- data/benchmarking/spreadsheet_example.rb +36 -0
- data/bin/jreo.bat +3 -0
- data/bin/reo.bat +3 -0
- data/docs/README_excel.rdoc +6 -0
- data/docs/README_open.rdoc +4 -0
- data/docs/README_ranges.rdoc +15 -0
- data/examples/example_ruby_library.rb +27 -0
- data/lib/robust_excel_ole.rb +4 -3
- data/lib/robust_excel_ole/{address.rb → address_tool.rb} +23 -22
- data/lib/robust_excel_ole/{reo_common.rb → base.rb} +2 -90
- data/lib/robust_excel_ole/bookstore.rb +2 -2
- data/lib/robust_excel_ole/cell.rb +30 -18
- data/lib/robust_excel_ole/excel.rb +65 -30
- data/lib/robust_excel_ole/general.rb +7 -5
- data/lib/robust_excel_ole/range.rb +38 -15
- data/lib/robust_excel_ole/range_owners.rb +26 -11
- data/lib/robust_excel_ole/vba_objects.rb +30 -0
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +136 -147
- data/lib/robust_excel_ole/worksheet.rb +47 -15
- data/lib/rubygems_plugin.rb +3 -0
- data/robust_excel_ole.gemspec +1 -1
- data/spec/address_tool_spec.rb +175 -0
- data/spec/{reo_common_spec.rb → base_spec.rb} +10 -29
- data/spec/cell_spec.rb +67 -25
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +41 -273
- data/spec/general_spec.rb +15 -19
- data/spec/range_spec.rb +57 -3
- data/spec/workbook_spec.rb +7 -75
- data/spec/workbook_specs/workbook_misc_spec.rb +10 -10
- data/spec/workbook_specs/workbook_open_spec.rb +228 -14
- data/spec/workbook_specs/workbook_unobtr_spec.rb +31 -31
- data/spec/worksheet_spec.rb +42 -0
- metadata +27 -8
- data/spec/address_spec.rb +0 -174
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module RobustExcelOle
|
4
|
+
|
5
|
+
class VbaObjects < Base
|
6
|
+
|
7
|
+
def to_reo
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def address_tool
|
13
|
+
excel.address_tool
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# @private
|
19
|
+
class RangeNotEvaluatable < MiscREOError
|
20
|
+
end
|
21
|
+
|
22
|
+
# @private
|
23
|
+
class OptionInvalid < MiscREOError
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
class ObjectNotAlive < MiscREOError
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -22,7 +22,7 @@ module RobustExcelOle
|
|
22
22
|
CORE_DEFAULT_OPEN_OPTS = {
|
23
23
|
:default => {:excel => :current},
|
24
24
|
:force => {},
|
25
|
-
:update_links => :never
|
25
|
+
:update_links => :never
|
26
26
|
}.freeze
|
27
27
|
|
28
28
|
DEFAULT_OPEN_OPTS = {
|
@@ -85,7 +85,7 @@ module RobustExcelOle
|
|
85
85
|
# :check_compatibility true -> check compatibility when saving
|
86
86
|
# :update_links true -> user is being asked how to update links, false -> links are never updated
|
87
87
|
# @return [Workbook] a representation of a workbook
|
88
|
-
def self.new(file_or_workbook, opts = { }
|
88
|
+
def self.new(file_or_workbook, opts = { })
|
89
89
|
process_options(opts)
|
90
90
|
case file_or_workbook
|
91
91
|
when NilClass
|
@@ -93,7 +93,7 @@ module RobustExcelOle
|
|
93
93
|
when WIN32OLE
|
94
94
|
file = file_or_workbook.Fullname.tr('\\','/')
|
95
95
|
when Workbook
|
96
|
-
|
96
|
+
file = file_or_workbook.Fullname.tr('\\','/')
|
97
97
|
when String
|
98
98
|
file = file_or_workbook
|
99
99
|
raise FileNotFound, "file #{General.absolute_path(file).inspect} is a directory" if File.directory?(file)
|
@@ -105,9 +105,12 @@ module RobustExcelOle
|
|
105
105
|
book = nil
|
106
106
|
if opts[:force][:excel] != :new
|
107
107
|
# if readonly is true, then prefer a book that is given in force_excel if this option is set
|
108
|
-
forced_excel =
|
108
|
+
forced_excel = begin
|
109
109
|
(opts[:force][:excel].nil? || opts[:force][:excel] == :current) ?
|
110
|
-
(excel_class.new(:reuse => true) if !::CONNECT_JRUBY_BUG) :
|
110
|
+
(excel_class.new(:reuse => true) if !::CONNECT_JRUBY_BUG) : opts[:force][:excel].to_reo.excel
|
111
|
+
rescue NoMethodError
|
112
|
+
raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
|
113
|
+
end
|
111
114
|
begin
|
112
115
|
book = if File.exists?(file)
|
113
116
|
bookstore.fetch(file, :prefer_writable => !(opts[:read_only]),
|
@@ -115,7 +118,7 @@ module RobustExcelOle
|
|
115
118
|
end
|
116
119
|
rescue
|
117
120
|
raise
|
118
|
-
trace "#{$!.message}"
|
121
|
+
#trace "#{$!.message}"
|
119
122
|
end
|
120
123
|
if book
|
121
124
|
set_was_open opts, book.alive?
|
@@ -125,12 +128,12 @@ module RobustExcelOle
|
|
125
128
|
!(book.alive? && !book.saved && (opts[:if_unsaved] != :accept))
|
126
129
|
opts[:force][:excel] = book.excel if book.excel && book.excel.alive?
|
127
130
|
book.ensure_workbook(file,opts)
|
128
|
-
book.
|
131
|
+
book.send :apply_options, file, opts
|
129
132
|
return book
|
130
133
|
end
|
131
134
|
end
|
132
135
|
end
|
133
|
-
super(file_or_workbook, opts
|
136
|
+
super(file_or_workbook, opts)
|
134
137
|
end
|
135
138
|
|
136
139
|
singleton_class.send :alias_method, :open, :new
|
@@ -141,25 +144,23 @@ module RobustExcelOle
|
|
141
144
|
# @param [Hash] opts
|
142
145
|
# @option opts [Symbol] see above
|
143
146
|
# @return [Workbook] a workbook
|
144
|
-
def initialize(file_or_workbook,
|
147
|
+
def initialize(file_or_workbook, opts)
|
145
148
|
if file_or_workbook.is_a? WIN32OLE
|
146
149
|
@ole_workbook = file_or_workbook
|
147
|
-
ole_excel = begin
|
148
|
-
|
149
|
-
rescue
|
150
|
+
ole_excel = begin
|
151
|
+
@ole_workbook.Application
|
152
|
+
rescue WIN32OLERuntimeError
|
150
153
|
raise ExcelREOError, 'could not determine the Excel instance'
|
151
154
|
end
|
152
155
|
@excel = excel_class.new(ole_excel)
|
153
|
-
filename =
|
156
|
+
filename = @ole_workbook.Fullname.tr('\\','/')
|
154
157
|
else
|
155
158
|
filename = file_or_workbook
|
156
|
-
ensure_workbook(filename,
|
159
|
+
ensure_workbook(filename, opts)
|
157
160
|
end
|
158
|
-
|
161
|
+
apply_options(filename, opts)
|
159
162
|
store_myself
|
160
|
-
|
161
|
-
address_class.new(r1c1_letters)
|
162
|
-
if block
|
163
|
+
if block_given?
|
163
164
|
begin
|
164
165
|
yield self
|
165
166
|
ensure
|
@@ -170,28 +171,21 @@ module RobustExcelOle
|
|
170
171
|
|
171
172
|
private
|
172
173
|
|
173
|
-
# @private
|
174
174
|
def self.set_was_open(hash, value)
|
175
175
|
hash[:was_open] = value if hash.has_key?(:was_open)
|
176
176
|
end
|
177
177
|
|
178
|
-
# @private
|
179
178
|
def set_was_open(hash, value)
|
180
179
|
self.class.set_was_open(hash, value)
|
181
180
|
end
|
182
181
|
|
183
|
-
# @private
|
184
|
-
# translates abbreviations and synonyms and merges with default options
|
185
182
|
def self.process_options(opts, proc_opts = {:use_defaults => true})
|
186
183
|
translate(opts)
|
187
184
|
default_opts = (proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS : CORE_DEFAULT_OPEN_OPTS).dup
|
188
185
|
translate(default_opts)
|
189
|
-
opts.merge!(default_opts) {|key, v1, v2| v1 }
|
190
|
-
opts[:default] = default_opts[:default].merge(opts[:default]) unless opts[:default].nil?
|
191
|
-
opts[:force] = default_opts[:force].merge(opts[:force]) unless opts[:force].nil?
|
186
|
+
opts.merge!(default_opts) { |key, v1, v2| !v2.is_a?(Hash) ? v1 : v2.merge(v1 || {}) }
|
192
187
|
end
|
193
188
|
|
194
|
-
# @private
|
195
189
|
def self.translate(opts)
|
196
190
|
erg = {}
|
197
191
|
opts.each do |key,value|
|
@@ -219,34 +213,26 @@ module RobustExcelOle
|
|
219
213
|
opts[:force][:excel] = :current if opts[:force][:excel] == :reuse || opts[:force][:excel] == :active
|
220
214
|
end
|
221
215
|
|
222
|
-
# returns an Excel object when given Excel, Workbook or Win32ole object representing a Workbook or an Excel
|
223
|
-
# @private
|
224
|
-
def self.excel_of(object)
|
225
|
-
begin
|
226
|
-
object = object.to_reo if object.is_a? WIN32OLE
|
227
|
-
object.excel
|
228
|
-
rescue
|
229
|
-
raise TypeREOError, 'given object is neither an Excel, a Workbook, nor a Win32ole'
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
216
|
public
|
234
217
|
|
235
218
|
# @private
|
236
219
|
# ensures an excel but not for jruby if current Excel shall be used
|
237
220
|
def ensure_excel(options)
|
238
221
|
return if @excel && @excel.alive?
|
239
|
-
excel_option = options[:force][:excel]
|
222
|
+
excel_option = options[:force][:excel] || options[:default][:excel] || :current
|
240
223
|
@excel = if excel_option == :new
|
241
224
|
excel_class.new(:reuse => false)
|
242
|
-
elsif excel_option
|
225
|
+
elsif excel_option == :current
|
243
226
|
excel_class.new(:reuse => true)
|
227
|
+
elsif excel_option.respond_to?(:to_reo)
|
228
|
+
excel_option.to_reo.excel
|
244
229
|
else
|
245
|
-
|
230
|
+
raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
|
246
231
|
end
|
247
|
-
raise ExcelREOError, "
|
232
|
+
raise ExcelREOError, "Excel is not alive" unless @excel && @excel.alive?
|
248
233
|
end
|
249
234
|
|
235
|
+
|
250
236
|
# @private
|
251
237
|
def ensure_workbook(filename, options)
|
252
238
|
set_was_open options, true
|
@@ -263,12 +249,12 @@ module RobustExcelOle
|
|
263
249
|
workbooks = @excel.Workbooks
|
264
250
|
@ole_workbook = workbooks.Item(File.basename(filename)) rescue nil if @ole_workbook.nil?
|
265
251
|
if @ole_workbook && alive?
|
266
|
-
set_was_open options, true
|
252
|
+
set_was_open options, true
|
267
253
|
manage_blocking_or_unsaved_workbook(filename,options)
|
268
254
|
open_or_create_workbook(filename,options) if @ole_workbook.ReadOnly != options[:read_only]
|
269
255
|
else
|
270
|
-
if excel_option.nil? || excel_option == :current &&
|
271
|
-
(
|
256
|
+
if (excel_option.nil? || excel_option == :current) &&
|
257
|
+
!(::CONNECT_JRUBY_BUG && filename[0] == '/')
|
272
258
|
connect(filename,options)
|
273
259
|
else
|
274
260
|
open_or_create_workbook(filename,options)
|
@@ -276,11 +262,14 @@ module RobustExcelOle
|
|
276
262
|
end
|
277
263
|
end
|
278
264
|
|
279
|
-
|
280
|
-
|
281
|
-
|
265
|
+
private
|
266
|
+
|
267
|
+
# applies options to workbook named with filename
|
268
|
+
def apply_options(filename, options)
|
269
|
+
# changing read-only mode
|
270
|
+
#ensure_workbook(filename, options) if options[:read_only] && options[:read_only] != @ole_workbook.ReadOnly
|
282
271
|
if (!options[:read_only].nil?) && options[:read_only] != @ole_workbook.ReadOnly
|
283
|
-
ensure_workbook(filename, options)
|
272
|
+
ensure_workbook(filename, options)
|
284
273
|
end
|
285
274
|
retain_saved do
|
286
275
|
self.visible = options[:force][:visible].nil? ? @excel.Visible : options[:force][:visible]
|
@@ -289,36 +278,32 @@ module RobustExcelOle
|
|
289
278
|
end
|
290
279
|
end
|
291
280
|
|
292
|
-
private
|
293
|
-
|
294
|
-
# @private
|
295
281
|
# connects to an unknown workbook
|
296
|
-
def connect(filename,options)
|
282
|
+
def connect(filename, options)
|
297
283
|
workbooks_number = excel_class.excels_number==0 ? 0 : excel_class.current.Workbooks.Count
|
298
284
|
@ole_workbook = begin
|
299
285
|
WIN32OLE.connect(General.absolute_path(filename))
|
300
286
|
rescue
|
301
287
|
if $!.message =~ /moniker/
|
302
|
-
raise WorkbookConnectingBlockingError
|
303
|
-
else
|
304
|
-
raise WorkbookConnectingUnknownError
|
288
|
+
raise WorkbookConnectingBlockingError, "some workbook is blocking when connecting"
|
289
|
+
else
|
290
|
+
raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
|
305
291
|
end
|
306
292
|
end
|
307
293
|
ole_excel = begin
|
308
294
|
@ole_workbook.Application
|
309
295
|
rescue
|
310
296
|
if $!.message =~ /dispid/
|
311
|
-
raise WorkbookConnectingUnsavedError
|
312
|
-
else
|
313
|
-
raise WorkbookConnectingUnknownError
|
297
|
+
raise WorkbookConnectingUnsavedError, "workbook is unsaved when connecting"
|
298
|
+
else
|
299
|
+
raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
|
314
300
|
end
|
315
301
|
end
|
316
302
|
set_was_open options, (ole_excel.Workbooks.Count == workbooks_number)
|
317
303
|
@excel = excel_class.new(ole_excel)
|
318
304
|
end
|
319
305
|
|
320
|
-
|
321
|
-
def manage_nonexisting_file(filename,options)
|
306
|
+
def manage_nonexisting_file(filename, options)
|
322
307
|
return if File.exist?(filename)
|
323
308
|
abs_filename = General.absolute_path(filename)
|
324
309
|
if options[:if_absent] == :create
|
@@ -336,8 +321,7 @@ module RobustExcelOle
|
|
336
321
|
end
|
337
322
|
end
|
338
323
|
|
339
|
-
|
340
|
-
def manage_blocking_or_unsaved_workbook(filename,options)
|
324
|
+
def manage_blocking_or_unsaved_workbook(filename, options)
|
341
325
|
filename = General.absolute_path(filename)
|
342
326
|
filename = General.canonize(filename)
|
343
327
|
previous_file = General.canonize(@ole_workbook.Fullname)
|
@@ -354,8 +338,7 @@ module RobustExcelOle
|
|
354
338
|
end
|
355
339
|
end
|
356
340
|
|
357
|
-
|
358
|
-
def manage_blocking_workbook(filename,options)
|
341
|
+
def manage_blocking_workbook(filename, options)
|
359
342
|
case options[:if_obstructed]
|
360
343
|
when :raise
|
361
344
|
raise WorkbookBlocked, "can't open workbook #{filename},
|
@@ -369,7 +352,8 @@ module RobustExcelOle
|
|
369
352
|
manage_saving_workbook(filename, options)
|
370
353
|
when :close_if_saved
|
371
354
|
if !@ole_workbook.Saved
|
372
|
-
raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}"
|
355
|
+
raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}" +
|
356
|
+
"\nHint: Use the option :if_blocked => :save to save the workbook"
|
373
357
|
else
|
374
358
|
manage_forgetting_workbook(filename, options)
|
375
359
|
end
|
@@ -381,15 +365,14 @@ module RobustExcelOle
|
|
381
365
|
end
|
382
366
|
end
|
383
367
|
|
384
|
-
|
385
|
-
def manage_unsaved_workbook(filename,options)
|
368
|
+
def manage_unsaved_workbook(filename, options)
|
386
369
|
case options[:if_unsaved]
|
387
370
|
when :raise
|
388
371
|
raise WorkbookNotSaved, "workbook is already open but not saved: #{File.basename(filename).inspect}" +
|
389
372
|
"\nHint: Save the workbook or open the workbook using option :if_unsaved with values :forget and :accept to
|
390
373
|
close the unsaved workbook and reopen it, or to let the unsaved workbook open, respectively"
|
391
374
|
when :forget
|
392
|
-
manage_forgetting_workbook(filename,options)
|
375
|
+
manage_forgetting_workbook(filename, options)
|
393
376
|
when :accept
|
394
377
|
# do nothing
|
395
378
|
when :save
|
@@ -404,27 +387,23 @@ module RobustExcelOle
|
|
404
387
|
end
|
405
388
|
end
|
406
389
|
|
407
|
-
# @private
|
408
390
|
def manage_forgetting_workbook(filename, options)
|
409
391
|
@excel.with_displayalerts(false) { @ole_workbook.Close }
|
410
392
|
@ole_workbook = nil
|
411
393
|
open_or_create_workbook(filename, options)
|
412
394
|
end
|
413
395
|
|
414
|
-
# @private
|
415
396
|
def manage_saving_workbook(filename, options)
|
416
397
|
save unless @ole_workbook.Saved
|
417
398
|
manage_forgetting_workbook(filename, options)
|
418
399
|
end
|
419
400
|
|
420
|
-
# @private
|
421
401
|
def manage_new_excel(filename, options)
|
422
402
|
@excel = excel_class.new(:reuse => false)
|
423
403
|
@ole_workbook = nil
|
424
404
|
open_or_create_workbook(filename, options)
|
425
405
|
end
|
426
406
|
|
427
|
-
# @private
|
428
407
|
def open_or_create_workbook(filename, options)
|
429
408
|
return if @ole_workbook && options[:if_unsaved] != :alert && options[:if_unsaved] != :excel &&
|
430
409
|
(options[:read_only].nil? || options[:read_only]==@ole_workbook.ReadOnly )
|
@@ -460,7 +439,6 @@ module RobustExcelOle
|
|
460
439
|
end
|
461
440
|
end
|
462
441
|
|
463
|
-
# @private
|
464
442
|
# translating the option UpdateLinks from REO to VBA
|
465
443
|
# setting UpdateLinks works only if calculation mode is automatic,
|
466
444
|
# parameter 'UpdateLinks' has no effect
|
@@ -473,7 +451,6 @@ module RobustExcelOle
|
|
473
451
|
end
|
474
452
|
end
|
475
453
|
|
476
|
-
# @private
|
477
454
|
# workaround for linked workbooks for Excel 2007:
|
478
455
|
# opening and closing a dummy workbook if Excel has no workbooks.
|
479
456
|
# delay: with visible: 0.2 sec, without visible almost none
|
@@ -537,13 +514,10 @@ module RobustExcelOle
|
|
537
514
|
else
|
538
515
|
close_workbook
|
539
516
|
end
|
540
|
-
# trace "close: canceled by user" if alive? &&
|
541
|
-
# (opts[:if_unsaved] == :alert || opts[:if_unsaved] == :excel) && (not @ole_workbook.Saved)
|
542
517
|
end
|
543
518
|
|
544
519
|
private
|
545
520
|
|
546
|
-
# @private
|
547
521
|
def close_workbook
|
548
522
|
@ole_workbook.Close if alive?
|
549
523
|
@ole_workbook = nil unless alive?
|
@@ -596,7 +570,8 @@ module RobustExcelOle
|
|
596
570
|
self.class.unobtrusively_opening(file, opts, alive?, &block)
|
597
571
|
end
|
598
572
|
|
599
|
-
|
573
|
+
private
|
574
|
+
|
600
575
|
def self.unobtrusively_opening(file, opts, book_is_alive, &block)
|
601
576
|
process_options(opts)
|
602
577
|
opts = {:if_closed => :current, :keep_open => false}.merge(opts)
|
@@ -620,15 +595,15 @@ module RobustExcelOle
|
|
620
595
|
was_saved = book.saved
|
621
596
|
was_check_compatibility = book.check_compatibility
|
622
597
|
was_calculation = book.excel.properties[:calculation]
|
623
|
-
book.
|
598
|
+
book.send :apply_options, file, opts
|
624
599
|
yield book
|
625
600
|
ensure
|
626
601
|
if book && book.alive?
|
627
602
|
do_not_write = opts[:read_only] || opts[:writable]==false
|
628
603
|
book.save unless book.saved || do_not_write || !book.writable
|
629
604
|
if (opts[:read_only] && was_writable) || (!opts[:read_only] && !was_writable)
|
630
|
-
book.
|
631
|
-
|
605
|
+
book.send :apply_options, file, opts.merge({:read_only => !was_writable,
|
606
|
+
:if_unsaved => (opts[:writable]==false ? :forget : :save)})
|
632
607
|
end
|
633
608
|
was_open = open_opts[:was_open]
|
634
609
|
if was_open
|
@@ -642,6 +617,8 @@ module RobustExcelOle
|
|
642
617
|
end
|
643
618
|
end
|
644
619
|
|
620
|
+
public
|
621
|
+
|
645
622
|
# reopens a closed workbook
|
646
623
|
# @options options
|
647
624
|
def reopen(options = { })
|
@@ -655,10 +632,6 @@ module RobustExcelOle
|
|
655
632
|
def save(opts = { }) # option opts is deprecated #
|
656
633
|
raise ObjectNotAlive, 'workbook is not alive' unless alive?
|
657
634
|
raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
|
658
|
-
# if you have open the workbook with :read_only => true,
|
659
|
-
# then you could close the workbook and open it again with option :read_only => false
|
660
|
-
# otherwise the workbook may already be open writable in an another Excel instance
|
661
|
-
# then you could use this workbook or close the workbook there
|
662
635
|
begin
|
663
636
|
@ole_workbook.Save
|
664
637
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
@@ -748,12 +721,6 @@ module RobustExcelOle
|
|
748
721
|
|
749
722
|
private
|
750
723
|
|
751
|
-
def store_myself
|
752
|
-
bookstore.store(self)
|
753
|
-
@stored_filename = filename
|
754
|
-
end
|
755
|
-
|
756
|
-
# @private
|
757
724
|
def save_as_workbook(file, options)
|
758
725
|
dirname, basename = File.split(file)
|
759
726
|
file_format =
|
@@ -773,6 +740,11 @@ module RobustExcelOle
|
|
773
740
|
end
|
774
741
|
end
|
775
742
|
|
743
|
+
def store_myself
|
744
|
+
bookstore.store(self)
|
745
|
+
@stored_filename = filename
|
746
|
+
end
|
747
|
+
|
776
748
|
public
|
777
749
|
|
778
750
|
# closes a given file if it is open
|
@@ -811,12 +783,22 @@ module RobustExcelOle
|
|
811
783
|
raise NameNotFound, "could not return a sheet with name #{name.inspect}"
|
812
784
|
end
|
813
785
|
|
786
|
+
def worksheets_count
|
787
|
+
@ole_workbook.Worksheets.Count
|
788
|
+
end
|
789
|
+
|
814
790
|
def each
|
815
791
|
@ole_workbook.Worksheets.each do |sheet|
|
816
792
|
yield worksheet_class.new(sheet)
|
817
793
|
end
|
818
794
|
end
|
819
795
|
|
796
|
+
def worksheets
|
797
|
+
result = []
|
798
|
+
each { |worksheet| result << worksheet }
|
799
|
+
result
|
800
|
+
end
|
801
|
+
|
820
802
|
def each_with_index(offset = 0)
|
821
803
|
i = offset
|
822
804
|
@ole_workbook.Worksheets.each do |sheet|
|
@@ -841,36 +823,18 @@ module RobustExcelOle
|
|
841
823
|
new_sheet_name = opts.delete(:as)
|
842
824
|
last_sheet_local = last_sheet
|
843
825
|
after_or_before, base_sheet = opts.to_a.first || [:after, last_sheet_local]
|
826
|
+
base_sheet_ole = base_sheet.ole_worksheet
|
844
827
|
begin
|
845
|
-
if !::COPYSHEETS_JRUBY_BUG
|
846
|
-
|
847
|
-
sheet.Copy({ after_or_before.to_s => base_sheet.ole_worksheet })
|
848
|
-
else
|
849
|
-
@ole_workbook.Worksheets.Add({ after_or_before.to_s => base_sheet.ole_worksheet })
|
850
|
-
#@ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
|
851
|
-
end
|
828
|
+
if !::COPYSHEETS_JRUBY_BUG
|
829
|
+
add_or_copy_sheet_simple(sheet, { after_or_before.to_s => base_sheet_ole })
|
852
830
|
else
|
853
831
|
if after_or_before == :before
|
854
|
-
|
855
|
-
sheet.Copy(base_sheet.ole_worksheet)
|
856
|
-
else
|
857
|
-
ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
|
858
|
-
end
|
832
|
+
add_or_copy_sheet_simple(sheet, base_sheet_ole)
|
859
833
|
else
|
860
|
-
#not_given = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_NULL)
|
861
|
-
#ole_workbook.Worksheets.Add(not_given,base_sheet.ole_worksheet)
|
862
834
|
if base_sheet.name != last_sheet_local.name
|
863
|
-
|
864
|
-
sheet.Copy(base_sheet.Next)
|
865
|
-
else
|
866
|
-
ole_workbook.Worksheets.Add(base_sheet.Next)
|
867
|
-
end
|
835
|
+
add_or_copy_sheet_simple(sheet, base_sheet.Next)
|
868
836
|
else
|
869
|
-
|
870
|
-
sheet.Copy(base_sheet.ole_worksheet)
|
871
|
-
else
|
872
|
-
ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
|
873
|
-
end
|
837
|
+
add_or_copy_sheet_simple(sheet, base_sheet_ole)
|
874
838
|
base_sheet.Move(ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count-1))
|
875
839
|
ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
|
876
840
|
end
|
@@ -879,12 +843,23 @@ module RobustExcelOle
|
|
879
843
|
rescue WIN32OLERuntimeError, NameNotFound, Java::OrgRacobCom::ComFailException
|
880
844
|
raise WorksheetREOError, "could not add given worksheet #{sheet.inspect}"
|
881
845
|
end
|
882
|
-
|
883
|
-
new_sheet = worksheet_class.new(ole_sheet)
|
846
|
+
new_sheet = worksheet_class.new(ole_workbook.Activesheet)
|
884
847
|
new_sheet.name = new_sheet_name if new_sheet_name
|
885
848
|
new_sheet
|
886
849
|
end
|
887
850
|
|
851
|
+
private
|
852
|
+
|
853
|
+
def add_or_copy_sheet_simple(sheet, base_sheet_ole_or_hash)
|
854
|
+
if sheet
|
855
|
+
sheet.Copy(base_sheet_ole_or_hash)
|
856
|
+
else
|
857
|
+
ole_workbook.Worksheets.Add(base_sheet_ole_or_hash)
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
public
|
862
|
+
|
888
863
|
# for compatibility to older versions
|
889
864
|
def add_sheet(sheet = nil, opts = { })
|
890
865
|
add_or_copy_sheet(sheet, opts)
|
@@ -914,7 +889,7 @@ module RobustExcelOle
|
|
914
889
|
# @param [String] name the name of the range
|
915
890
|
# @param [Variant] value the contents of the range
|
916
891
|
def []= (name, value)
|
917
|
-
set_namevalue_glob(name,value
|
892
|
+
set_namevalue_glob(name, value, :color => 42)
|
918
893
|
end
|
919
894
|
|
920
895
|
# sets options
|
@@ -922,19 +897,7 @@ module RobustExcelOle
|
|
922
897
|
def for_this_workbook(opts)
|
923
898
|
return unless alive?
|
924
899
|
self.class.process_options(opts, :use_defaults => false)
|
925
|
-
|
926
|
-
check_compatibility_before = check_compatibility
|
927
|
-
unless opts[:read_only].nil?
|
928
|
-
# if the ReadOnly status shall be changed, then close and reopen it
|
929
|
-
if (!writable && !(opts[:read_only])) || (writable && opts[:read_only])
|
930
|
-
opts[:check_compatibility] = check_compatibility if opts[:check_compatibility].nil?
|
931
|
-
close(:if_unsaved => true)
|
932
|
-
open_or_create_workbook(@stored_filename, opts)
|
933
|
-
end
|
934
|
-
end
|
935
|
-
self.visible = opts[:force][:visible].nil? ? visible_before : opts[:force][:visible]
|
936
|
-
self.CheckCompatibility = opts[:check_compatibility].nil? ? check_compatibility_before : opts[:check_compatibility]
|
937
|
-
@excel.calculation = opts[:calculation] unless opts[:calculation].nil?
|
900
|
+
self.send :apply_options, @stored_filename, opts
|
938
901
|
end
|
939
902
|
|
940
903
|
# brings workbook to foreground, makes it available for heyboard inputs, makes the Excel instance visible
|
@@ -950,7 +913,6 @@ module RobustExcelOle
|
|
950
913
|
true
|
951
914
|
rescue
|
952
915
|
@ole_workbook = nil # dead object won't be alive again
|
953
|
-
# t $!.message
|
954
916
|
false
|
955
917
|
end
|
956
918
|
|
@@ -1012,6 +974,7 @@ module RobustExcelOle
|
|
1012
974
|
self.filename == other_book.filename
|
1013
975
|
end
|
1014
976
|
|
977
|
+
# @private
|
1015
978
|
def self.books
|
1016
979
|
bookstore.books
|
1017
980
|
end
|
@@ -1062,16 +1025,6 @@ module RobustExcelOle
|
|
1062
1025
|
end
|
1063
1026
|
end
|
1064
1027
|
|
1065
|
-
# @private
|
1066
|
-
def self.address_class
|
1067
|
-
@address_class ||= begin
|
1068
|
-
module_name = self.parent_name
|
1069
|
-
"#{module_name}::Address".constantize
|
1070
|
-
rescue NameError => e
|
1071
|
-
Address
|
1072
|
-
end
|
1073
|
-
end
|
1074
|
-
|
1075
1028
|
# @private
|
1076
1029
|
def excel_class
|
1077
1030
|
self.class.excel_class
|
@@ -1082,11 +1035,6 @@ module RobustExcelOle
|
|
1082
1035
|
self.class.worksheet_class
|
1083
1036
|
end
|
1084
1037
|
|
1085
|
-
# @private
|
1086
|
-
def address_class
|
1087
|
-
self.class.address_class
|
1088
|
-
end
|
1089
|
-
|
1090
1038
|
include MethodHelpers
|
1091
1039
|
|
1092
1040
|
private
|
@@ -1116,6 +1064,47 @@ module RobustExcelOle
|
|
1116
1064
|
|
1117
1065
|
public
|
1118
1066
|
|
1067
|
+
# @private
|
1068
|
+
class WorkbookBlocked < WorkbookREOError
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
# @private
|
1072
|
+
class WorkbookNotSaved < WorkbookREOError
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
# @private
|
1076
|
+
class WorkbookReadOnly < WorkbookREOError
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
# @private
|
1080
|
+
class WorkbookBeingUsed < WorkbookREOError
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
# @private
|
1084
|
+
class WorkbookConnectingUnsavedError < WorkbookREOError
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
# @private
|
1088
|
+
class WorkbookConnectingBlockingError < WorkbookREOError
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
# @private
|
1092
|
+
class WorkbookConnectingUnknownError < WorkbookREOError
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
# @private
|
1096
|
+
class FileAlreadyExists < FileREOError
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
# @private
|
1100
|
+
class FileNameNotGiven < FileREOError
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
# @private
|
1104
|
+
class FileNotFound < FileREOError
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
|
1119
1108
|
Book = Workbook
|
1120
1109
|
|
1121
1110
|
end
|