robust_excel_ole 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +12 -1
- data/README.rdoc +114 -276
- data/README_detail.rdoc +31 -14
- data/lib/robust_excel_ole/book.rb +89 -113
- data/lib/robust_excel_ole/excel.rb +38 -10
- data/lib/robust_excel_ole/sheet.rb +2 -2
- data/lib/robust_excel_ole/version.rb +1 -1
- data/spec/book_spec.rb +23 -20
- data/spec/book_specs/book_misc_spec.rb +6 -12
- data/spec/book_specs/book_open_spec.rb +22 -63
- data/spec/book_specs/book_unobtr_spec.rb +174 -231
- data/spec/data/another_workbook.xls +0 -0
- data/spec/data/different_workbook.xls +0 -0
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/data/workbook.xls +0 -0
- data/spec/excel_spec.rb +32 -5
- metadata +4 -4
data/README_detail.rdoc
CHANGED
@@ -5,7 +5,7 @@ It supports simultaneously running Excel instances and user interactions.
|
|
5
5
|
RobustExcelOle deals with various cases of Excel and user behaviour,
|
6
6
|
and implements workarounds for some Excel bugs.
|
7
7
|
The gem provides convenient methods for common tasks, and facilitates referenced libraries.
|
8
|
-
It supports Excel 2010
|
8
|
+
It supports Excel 2010.
|
9
9
|
|
10
10
|
RobustExcelOle works by sending VBA methods via Win32OLE.
|
11
11
|
Moreover, it implements a management system and keeps track of Excel files and Excel instances.
|
@@ -42,7 +42,7 @@ Options are the following:
|
|
42
42
|
|
43
43
|
+:force+:: no matter whether the workbook was open before, use the properties stated in +:force+
|
44
44
|
|
45
|
-
+:excel+ and +:visible+ are options stated in +:default+
|
45
|
+
+:excel+ and +:visible+ are options stated in +:default+ or +:force+
|
46
46
|
|
47
47
|
+:excel+:: specifies the Excel instance.
|
48
48
|
+:visible+:: makes the workbook visible or invisible
|
@@ -115,6 +115,10 @@ If you want to open the workbook and make its window visible, then use
|
|
115
115
|
|
116
116
|
book = Book.open('workbook.xls', :force => {:visible => true})
|
117
117
|
|
118
|
+
or
|
119
|
+
|
120
|
+
book = Book.open('workbook.xls', :visible => true)
|
121
|
+
|
118
122
|
You can combine options, e.g.
|
119
123
|
|
120
124
|
Book.open('workbook.xls', :force => {:excel => :new, :visible => true})
|
@@ -216,15 +220,13 @@ If a workbook blocks the workbook that should be saved, then the former one can
|
|
216
220
|
|
217
221
|
=== Unobtrusively modifying a workbook
|
218
222
|
|
219
|
-
The method +unobtrusively+ enables the user to read or modify a workbook, no matter if it is open in some Excel instance, if it is saved or unsaved, and if it is writable or not. When opening a workbook unobtrusively, its status remains unchanged. This status includes, whether the workbook is opened or closed, saved or unsaved, readonly or writable.
|
223
|
+
The method +unobtrusively+ enables the user to read or modify a workbook, no matter if it is open in some Excel instance, if it is saved or unsaved, and if it is writable or not. When opening a workbook unobtrusively, its status remains unchanged. This status includes, whether the workbook is opened or closed, saved or unsaved, readonly or writable, visible or invisible, calculation mode is automatic or manual, and checking compatibility is turned on or off.
|
220
224
|
|
221
|
-
One option chooses the Excel instance in which a closed workbook is opened. The option +:current+ (or +:active+, or +:reuse) (default) indicates that the closed workbook is opened in the Excel instance of the workbook, if it exists, or that another Excel instance is reused.
|
225
|
+
One option chooses the Excel instance in which a closed workbook is opened. The option +:current+ (or +:active+, or +:reuse) (default) indicates that the closed workbook is opened in the Excel instance of the workbook, if it exists, or that another Excel instance is reused. Moreover, an Excel instance can be given directly where to open the closed workbook.
|
222
226
|
|
223
227
|
Options are the following:
|
224
228
|
|
225
229
|
+:current+ (or +:active, or +:reuse+:): (default) : open a closed workbook in the Excel instance where it was opened most recently, if such an Excel instance exists, otherwise open it in the current (first opened) Excel instance
|
226
|
-
+:hidden+:: : open a closed workbook in one separate Excel instance that is not visible and has no displayalerts
|
227
|
-
<excel-instance> : open a closed workbooks in the given Excel instance
|
228
230
|
|
229
231
|
+:read_only+:: Open the workbook unobtrusively for reading only (default: false)
|
230
232
|
+:readonly_excel+:: if the workbook is opened only as ReadOnly and shall be modified, then
|
@@ -232,8 +234,6 @@ Options are the following:
|
|
232
234
|
false (default) open it as writable in another running excel instance, if it exists,
|
233
235
|
otherwise open in a new excel instance
|
234
236
|
+:keep_open+:: let the workbook open after unobtrusively opening (default: false)
|
235
|
-
+:visible+:: make the window of the workbook visible (default: false)
|
236
|
-
+:check_compatibility+:: checks compatibility when saving
|
237
237
|
|
238
238
|
Book.unobtrusively('workbook.xls') do |book|
|
239
239
|
# some modification
|
@@ -404,13 +404,13 @@ or
|
|
404
404
|
|
405
405
|
=== Getting and setting the contents of a named range in a Worksheet directly
|
406
406
|
|
407
|
-
You get the value of a range with
|
407
|
+
You get the value of a range of a locally defined name with
|
408
408
|
|
409
409
|
sheet.rangeval(name)
|
410
410
|
|
411
|
-
and set the value of
|
411
|
+
and set the value of this range by
|
412
412
|
|
413
|
-
|
413
|
+
sheet.set_rangeval(name,value)
|
414
414
|
|
415
415
|
=== Adding and copying a worksheet.
|
416
416
|
|
@@ -464,7 +464,7 @@ The option +:calculation+ specifies, whether the calculation mode is being force
|
|
464
464
|
|
465
465
|
You can also promote an Excel instance represented as WIN32OLE object to an Excel object.
|
466
466
|
|
467
|
-
excel = Excel.new(win32ole_object)
|
467
|
+
excel = Excel.new(win32ole_object, :visible => true)
|
468
468
|
|
469
469
|
=== Making a Excel visible or invisible
|
470
470
|
|
@@ -510,6 +510,14 @@ You can turn off and off DisplayAlerts in a block.
|
|
510
510
|
|
511
511
|
excel1.workbooks_visible false
|
512
512
|
|
513
|
+
=== Setting options
|
514
|
+
|
515
|
+
You can set all options in a given Excel instance
|
516
|
+
|
517
|
+
e1 = Excel.current
|
518
|
+
|
519
|
+
e1.set_options(:visible => true, :displayalerts => true)
|
520
|
+
|
513
521
|
=== Bringing an Excel instance to the foreground
|
514
522
|
|
515
523
|
excel1.focus
|
@@ -591,13 +599,21 @@ or
|
|
591
599
|
|
592
600
|
excel.set_nameval(name,value)
|
593
601
|
|
602
|
+
=== Retaining the saved-status of all workbooks
|
603
|
+
|
604
|
+
You can operate in some Excel instance and retain the saved-status of all workbooks.
|
605
|
+
|
606
|
+
excel.retain_saved_workbooks do
|
607
|
+
...
|
608
|
+
end
|
609
|
+
|
594
610
|
=== Getting and setting the contents of a named range in an Excel application directly
|
595
611
|
|
596
|
-
You can get the value of a range
|
612
|
+
You can get the value of a range of a locally defined name by
|
597
613
|
|
598
614
|
excel.rangeval(name)
|
599
615
|
|
600
|
-
and set the value of
|
616
|
+
and set the value of this range with
|
601
617
|
|
602
618
|
excel.set_rangeval(name,value)
|
603
619
|
|
@@ -768,6 +784,7 @@ Some features in RobustExcelOle that are not compatible with wrap_excel:
|
|
768
784
|
* +save_as+ instead of +save+.
|
769
785
|
* position of cells and number of sheets are based on 1 instead of 0
|
770
786
|
|
787
|
+
Excel 2007 was supported until version 0.3.6.
|
771
788
|
|
772
789
|
=== Want to do more things
|
773
790
|
|
@@ -212,6 +212,7 @@ module RobustExcelOle
|
|
212
212
|
|
213
213
|
public
|
214
214
|
|
215
|
+
=begin
|
215
216
|
# work in progress#
|
216
217
|
def self.open_in_current_excel(file, opts = { }) # :nodoc: #
|
217
218
|
options = DEFAULT_OPEN_OPTS.merge(opts)
|
@@ -230,6 +231,7 @@ module RobustExcelOle
|
|
230
231
|
workbook.CheckCompatibility = options[:check_compatibility]
|
231
232
|
workbook
|
232
233
|
end
|
234
|
+
=end
|
233
235
|
|
234
236
|
def ensure_excel(options) # :nodoc: #
|
235
237
|
if @excel && @excel.alive?
|
@@ -249,6 +251,7 @@ module RobustExcelOle
|
|
249
251
|
def ensure_workbook(file, options) # :nodoc: #
|
250
252
|
file = @stored_filename ? @stored_filename : file
|
251
253
|
raise(FileNameNotGiven, "filename is nil") if file.nil?
|
254
|
+
raise(FileNotFound, "file #{General::absolute_path(file).inspect} is a directory") if File.directory?(file)
|
252
255
|
unless File.exist?(file)
|
253
256
|
if options[:if_absent] == :create
|
254
257
|
@ole_workbook = excel_class.current.generate_workbook(file)
|
@@ -303,8 +306,7 @@ module RobustExcelOle
|
|
303
306
|
when :alert, :excel
|
304
307
|
@excel.with_displayalerts(true) { open_or_create_workbook(file,options) }
|
305
308
|
when :new_excel
|
306
|
-
|
307
|
-
@excel = excel_class.new(excel_options)
|
309
|
+
@excel = excel_class.new(:reuse => false)
|
308
310
|
open_or_create_workbook(file, options)
|
309
311
|
else
|
310
312
|
raise OptionInvalid, ":if_unsaved: invalid option: #{options[:if_unsaved].inspect}"
|
@@ -333,16 +335,15 @@ module RobustExcelOle
|
|
333
335
|
end
|
334
336
|
end
|
335
337
|
begin
|
336
|
-
with_workaround_linked_workbooks_excel2007(options) do
|
338
|
+
with_workaround_linked_workbooks_excel2007(options) do
|
337
339
|
workbooks.Open(filename, { 'ReadOnly' => options[:read_only] ,
|
338
340
|
'UpdateLinks' => updatelinks_vba(options[:update_links]) })
|
339
341
|
end
|
340
342
|
rescue WIN32OLERuntimeError => msg
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
end
|
343
|
+
# for Excel2007: for option :if_unsaved => :alert and user cancels: this error appears?
|
344
|
+
# if yes: distinguish these events
|
345
|
+
#raise
|
346
|
+
trace "WIN32OLERuntimeError: #{msg.message}"
|
346
347
|
end
|
347
348
|
begin
|
348
349
|
# workaround for bug in Excel 2010: workbook.Open does not always return the workbook when given file name
|
@@ -386,8 +387,9 @@ module RobustExcelOle
|
|
386
387
|
# opening and closing a dummy workbook if Excel has no workbooks.
|
387
388
|
# delay: with visible: 0.2 sec, without visible almost none
|
388
389
|
def with_workaround_linked_workbooks_excel2007(options)
|
390
|
+
old_visible_value = @excel.Visible
|
389
391
|
workbooks = @excel.Workbooks
|
390
|
-
workaround_condition = @excel.Version.split(".").first.to_i
|
392
|
+
workaround_condition = @excel.Version.split(".").first.to_i == 12 && workbooks.Count == 0
|
391
393
|
if workaround_condition
|
392
394
|
workbooks.Add
|
393
395
|
@excel.calculation = options[:calculation].nil? ? @excel.calculation : options[:calculation]
|
@@ -396,7 +398,8 @@ module RobustExcelOle
|
|
396
398
|
#@excel.with_displayalerts(update_links_opt == :alert ? true : @excel.displayalerts) do
|
397
399
|
yield self
|
398
400
|
ensure
|
399
|
-
@excel.with_displayalerts(false){workbooks.Item(1).Close} if workaround_condition
|
401
|
+
@excel.with_displayalerts(false){workbooks.Item(1).Close} if workaround_condition
|
402
|
+
@excel.visible = old_visible_value
|
400
403
|
end
|
401
404
|
end
|
402
405
|
|
@@ -473,87 +476,65 @@ module RobustExcelOle
|
|
473
476
|
unobtrusively(*args, &block)
|
474
477
|
end
|
475
478
|
|
476
|
-
# allows to modify a workbook such that its state
|
479
|
+
# allows to read or modify a workbook such that its state remains unchanged
|
480
|
+
# state comprises: open, saved, writable, visible, calculation mode, check compatibility
|
477
481
|
# @param [String] file the file name
|
478
|
-
# @param [Hash] if_closed an option
|
479
482
|
# @param [Hash] opts the options
|
480
|
-
# @option opts [Variant] :if_closed :current (
|
481
|
-
# @option opts [Boolean] :read_only whether the
|
483
|
+
# @option opts [Variant] :if_closed :current (default), :new or an Excel instance
|
484
|
+
# @option opts [Boolean] :read_only whether the workbook is opened for read-only
|
482
485
|
# @option opts [Boolean] :readonly_excel behaviour when workbook is opened read-only and shall be modified
|
483
|
-
#
|
484
|
-
#
|
485
|
-
#
|
486
|
-
#
|
487
|
-
# :current (or :active, :reuse) -> the Excel instance of the workbook, if it exists,
|
488
|
-
# reuse another Excel, otherwise
|
489
|
-
# :hidden -> a separate Excel instance that is not visible and has no displayalerts
|
490
|
-
# <excel-instance> -> the given Excel instance
|
491
|
-
# :readonly_excel: if the workbook is opened only as ReadOnly and shall be modified, then
|
492
|
-
# true: closes it and open it as writable in the Excel instance where it was open so far
|
493
|
-
# false (default) opens it as writable in another running excel instance, if it exists,
|
494
|
-
# otherwise open in a new Excel instance.
|
495
|
-
# :visible, :read_only, :update_links, :check_compatibility : see options in #open
|
486
|
+
# true: closes it and open it as writable in the Excel instance where it was open so far
|
487
|
+
# false (default) opens it as writable in another running excel instance, if it exists,
|
488
|
+
# otherwise open in a new Excel instance.
|
489
|
+
# @option opts [Boolean] :keep_open whether the workbook shall be kept open after unobtrusively opening
|
496
490
|
# @return [Book] a workbook
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
opts = {:readonly_excel => false,:keep_open => false}.merge(opts)
|
491
|
+
|
492
|
+
# state = [:open, :saved, :writable, :visible, :calculation, :check_compatibility]
|
493
|
+
|
494
|
+
def self.unobtrusively(file, opts = { }, &block)
|
495
|
+
options = {:if_closed => :current,
|
496
|
+
:read_only => false,
|
497
|
+
:readonly_excel => false,
|
498
|
+
:keep_open => false}.merge(opts)
|
506
499
|
book = bookstore.fetch(file, :prefer_writable => (not options[:read_only]))
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
500
|
+
was_open = book && book.alive?
|
501
|
+
if was_open
|
502
|
+
was_saved = book.saved
|
503
|
+
was_writable = book.writable
|
504
|
+
was_visible = book.visible
|
505
|
+
was_calculation = book.calculation
|
506
|
+
was_check_compatibility = book.check_compatibility
|
507
|
+
end
|
512
508
|
begin
|
513
509
|
book =
|
514
|
-
if
|
515
|
-
|
516
|
-
|
517
|
-
open(file, :default => {:excel => :current}, :read_only => options[:read_only])
|
518
|
-
when :hidden
|
519
|
-
open(file, :force => {:excel => bookstore.hidden_excel}, :read_only => options[:read_only])
|
520
|
-
else
|
521
|
-
open(file, :force => {:excel => if_closed}, :read_only => options[:read_only])
|
522
|
-
end
|
523
|
-
else
|
524
|
-
if was_writable || options[:read_only]
|
525
|
-
book
|
510
|
+
if was_open
|
511
|
+
if (not was_writable) && (not options[:read_only])
|
512
|
+
open(file, :force => {:excel => (options[:readonly_excel] ? book.excel : :new)}, :read_only => false)
|
526
513
|
else
|
527
|
-
|
528
|
-
open(file, :force => {:excel => :new}, :read_only => options[:read_only])
|
514
|
+
book
|
529
515
|
end
|
530
|
-
end
|
531
|
-
#book.excel.visible = options[:force][:visible] unless options[:force].nil? or options[:force][:visible].nil?
|
532
|
-
options = process_options(options)
|
533
|
-
if options[:force][:visible].nil? && (not options[:default][:visible].nil?)
|
534
|
-
if book.excel.created
|
535
|
-
book.visible = options[:default][:visible]
|
536
516
|
else
|
537
|
-
|
517
|
+
open(file, :force => {:excel => options[:if_closed]}, :read_only => false)
|
538
518
|
end
|
539
|
-
else
|
540
|
-
book.visible = options[:force][:visible] unless options[:force][:visible].nil?
|
541
|
-
end
|
542
|
-
book.CheckCompatibility = options[:check_compatibility] unless options[:check_compatibility].nil?
|
543
519
|
yield book
|
544
520
|
ensure
|
545
|
-
if book && book.alive?
|
521
|
+
if book && book.alive?
|
546
522
|
unless book.saved
|
547
523
|
book.save unless options[:read_only]
|
548
|
-
book.Saved = true if was_saved && options[:read_only]
|
549
|
-
book.Saved = false
|
524
|
+
book.Saved = true if (was_saved || (not was_open)) && options[:read_only]
|
525
|
+
book.Saved = false if (not was_saved) && (not options[:read_only]) && was_open
|
550
526
|
end
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
527
|
+
if was_open
|
528
|
+
if (not was_writable) && (not options[:read_only]) && options[:readonly_excel]
|
529
|
+
book.close
|
530
|
+
open(file, :force => {:excel => book.excel}, :if_obstructed => :new_excel, :read_only => true)
|
531
|
+
end
|
532
|
+
book.excel.calculation = was_calculation
|
533
|
+
book.CheckCompatibility = was_check_compatibility
|
534
|
+
#book.visible = was_visible # not necessary
|
535
|
+
end
|
536
|
+
|
537
|
+
book.close unless was_open || options[:keep_open]
|
557
538
|
end
|
558
539
|
end
|
559
540
|
end
|
@@ -851,40 +832,6 @@ module RobustExcelOle
|
|
851
832
|
@ole_workbook.Activate
|
852
833
|
end
|
853
834
|
|
854
|
-
# returns true, if the workbook is visible, false otherwise
|
855
|
-
def visible
|
856
|
-
@excel.visible && @ole_workbook.Windows(@ole_workbook.Name).Visible
|
857
|
-
end
|
858
|
-
|
859
|
-
# makes both the Excel instance and the window of the workbook visible, or the window invisible
|
860
|
-
# @param [Boolean] visible_value determines whether the workbook shall be visible
|
861
|
-
def visible= visible_value
|
862
|
-
@excel.visible = true if visible_value
|
863
|
-
self.window_visible = visible_value
|
864
|
-
end
|
865
|
-
|
866
|
-
# returns true, if the window of the workbook is set to visible, false otherwise
|
867
|
-
def window_visible
|
868
|
-
return @ole_workbook.Windows(@ole_workbook.Name).Visible
|
869
|
-
end
|
870
|
-
|
871
|
-
# makes the window of the workbook visible or invisible
|
872
|
-
# @param [Boolean] visible_value determines whether the window of the workbook shall be visible
|
873
|
-
def window_visible= visible_value
|
874
|
-
retain_saved do
|
875
|
-
@ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value if @ole_workbook.Windows.Count > 0
|
876
|
-
end
|
877
|
-
end
|
878
|
-
|
879
|
-
# def visible= visible_value
|
880
|
-
# retain_saved do
|
881
|
-
# @excel.visible = true if visible_value
|
882
|
-
# if @ole_workbook.Windows.Count > 0
|
883
|
-
# @ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value
|
884
|
-
# end
|
885
|
-
# end
|
886
|
-
# end
|
887
|
-
|
888
835
|
# returns true, if the workbook reacts to methods, false otherwise
|
889
836
|
def alive?
|
890
837
|
begin
|
@@ -910,6 +857,39 @@ module RobustExcelOle
|
|
910
857
|
@ole_workbook.Saved if @ole_workbook
|
911
858
|
end
|
912
859
|
|
860
|
+
def calculation
|
861
|
+
@excel.calculation if @ole_workbook
|
862
|
+
end
|
863
|
+
|
864
|
+
def check_compatibility
|
865
|
+
@ole_workbook.CheckCompatibility if @ole_workbook
|
866
|
+
end
|
867
|
+
|
868
|
+
# returns true, if the workbook is visible, false otherwise
|
869
|
+
def visible
|
870
|
+
@excel.visible && @ole_workbook.Windows(@ole_workbook.Name).Visible
|
871
|
+
end
|
872
|
+
|
873
|
+
# makes both the Excel instance and the window of the workbook visible, or the window invisible
|
874
|
+
# @param [Boolean] visible_value determines whether the workbook shall be visible
|
875
|
+
def visible= visible_value
|
876
|
+
@excel.visible = true if visible_value
|
877
|
+
self.window_visible = visible_value
|
878
|
+
end
|
879
|
+
|
880
|
+
# returns true, if the window of the workbook is set to visible, false otherwise
|
881
|
+
def window_visible
|
882
|
+
return @ole_workbook.Windows(@ole_workbook.Name).Visible
|
883
|
+
end
|
884
|
+
|
885
|
+
# makes the window of the workbook visible or invisible
|
886
|
+
# @param [Boolean] visible_value determines whether the window of the workbook shall be visible
|
887
|
+
def window_visible= visible_value
|
888
|
+
retain_saved do
|
889
|
+
@ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value if @ole_workbook.Windows.Count > 0
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
913
893
|
# @return [Boolean] true, if the full book names and excel Instances are identical, false otherwise
|
914
894
|
def == other_book
|
915
895
|
other_book.is_a?(Book) &&
|
@@ -941,10 +921,6 @@ module RobustExcelOle
|
|
941
921
|
"#<Book: " + "#{"not alive " unless alive?}" + "#{File.basename(self.filename) if alive?}" + " #{@ole_workbook} #{@excel}" + ">"
|
942
922
|
end
|
943
923
|
|
944
|
-
def self.in_context(klass) # :nodoc: #
|
945
|
-
|
946
|
-
end
|
947
|
-
|
948
924
|
def self.excel_class # :nodoc: #
|
949
925
|
@excel_class ||= begin
|
950
926
|
module_name = self.parent_name
|
@@ -47,7 +47,7 @@ module RobustExcelOle
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# returns an Excel instance
|
50
|
-
#
|
50
|
+
# @param [Win32Ole] (optional) a WIN32OLE object representing an Excel instance
|
51
51
|
# @param [Hash] options the options
|
52
52
|
# @option options [Boolean] :reuse
|
53
53
|
# @option options [Boolean] :visible
|
@@ -63,13 +63,14 @@ module RobustExcelOle
|
|
63
63
|
# or is not being forced (default: nil)
|
64
64
|
# :screenupdating turns on or off screen updating (default: true)
|
65
65
|
# @return [Excel] an Excel instance
|
66
|
-
def self.new(options = {})
|
67
|
-
if
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
def self.new(win32ole_excel = nil, options = { })
|
67
|
+
if win32ole_excel.is_a? Hash
|
68
|
+
options = win32ole_excel
|
69
|
+
win32ole_excel = nil
|
70
|
+
end
|
71
|
+
ole_xl = win32ole_excel unless win32ole_excel.nil?
|
72
|
+
options = {:reuse => true}.merge(options)
|
73
|
+
ole_xl = current_excel if options[:reuse] == true
|
73
74
|
ole_xl ||= WIN32OLE.new('Excel.Application')
|
74
75
|
hwnd = ole_xl.HWnd
|
75
76
|
stored = hwnd2excel(hwnd)
|
@@ -136,6 +137,10 @@ module RobustExcelOle
|
|
136
137
|
self
|
137
138
|
end
|
138
139
|
|
140
|
+
def set_options(options)
|
141
|
+
self.class.new(@ole_excel, options)
|
142
|
+
end
|
143
|
+
|
139
144
|
private
|
140
145
|
|
141
146
|
# returns a Win32OLE object that represents a Excel instance to which Excel connects
|
@@ -156,6 +161,21 @@ module RobustExcelOle
|
|
156
161
|
|
157
162
|
public
|
158
163
|
|
164
|
+
# retain the saved status of all workbooks
|
165
|
+
def retain_saved_workbooks
|
166
|
+
saved = []
|
167
|
+
@ole_excel.Workbooks.each {|w| saved << w.Saved}
|
168
|
+
begin
|
169
|
+
yield self
|
170
|
+
ensure
|
171
|
+
i = 0
|
172
|
+
@ole_excel.Workbooks.each do |w|
|
173
|
+
w.Saved = saved[i] if saved[i]
|
174
|
+
i = i + 1
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
159
179
|
def self.contains_unsaved_workbooks?
|
160
180
|
excel = begin
|
161
181
|
Excel.current
|
@@ -513,14 +533,22 @@ module RobustExcelOle
|
|
513
533
|
end
|
514
534
|
|
515
535
|
# sets calculation mode
|
536
|
+
# retains the saved-status of the workbooks when set to manual
|
516
537
|
def calculation= calculation_mode
|
517
538
|
return if calculation_mode.nil?
|
518
539
|
@calculation = calculation_mode
|
519
540
|
calc_mode_changable = @ole_excel.Workbooks.Count > 0 && @ole_excel.Calculation.is_a?(Fixnum)
|
520
541
|
if calc_mode_changable
|
542
|
+
if calculation_mode == :manual then
|
543
|
+
saved = []
|
544
|
+
(1..@ole_excel.Workbooks.Count).each {|i| saved << @ole_excel.Workbooks(i).Saved}
|
545
|
+
end
|
521
546
|
@ole_excel.CalculateBeforeSave = false
|
522
547
|
@ole_excel.Calculation =
|
523
548
|
(calculation_mode == :automatic) ? XlCalculationAutomatic : XlCalculationManual
|
549
|
+
if calculation_mode == :manual then
|
550
|
+
(1..@ole_excel.Workbooks.Count).each {|i| @ole_excel.Workbooks(i).Saved = true if saved[i-1]}
|
551
|
+
end
|
524
552
|
end
|
525
553
|
end
|
526
554
|
|
@@ -630,7 +658,7 @@ module RobustExcelOle
|
|
630
658
|
end
|
631
659
|
end
|
632
660
|
|
633
|
-
# returns the contents of a range with a defined
|
661
|
+
# returns the contents of a range with a locally defined name
|
634
662
|
# evaluates the formula if the contents is a formula
|
635
663
|
# if no contents could be returned, then return default value, if provided, raise error otherwise
|
636
664
|
# @param [String] name the range name
|
@@ -655,7 +683,7 @@ module RobustExcelOle
|
|
655
683
|
value
|
656
684
|
end
|
657
685
|
|
658
|
-
# assigns a value to a range given a defined
|
686
|
+
# assigns a value to a range given a locally defined name
|
659
687
|
# @param [String] name the range name
|
660
688
|
# @param [Variant] value the assigned value
|
661
689
|
def set_rangeval(name,value)
|