robust_excel_ole 0.6.1 → 0.6.2
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/Changelog +8 -0
- data/README.rdoc +7 -4
- data/README_detail.rdoc +7 -3
- data/lib/reo_console.rb +1 -1
- data/lib/robust_excel_ole.rb +1 -0
- data/lib/robust_excel_ole/book.rb +26 -22
- data/lib/robust_excel_ole/excel.rb +38 -21
- data/lib/robust_excel_ole/general.rb +2 -1
- data/lib/robust_excel_ole/reo_common.rb +0 -3
- data/lib/robust_excel_ole/version.rb +1 -1
- data/spec/book_spec.rb +16 -15
- data/spec/book_specs/book_misc_spec.rb +22 -8
- data/spec/book_specs/book_open_spec.rb +3 -3
- data/spec/book_specs/book_save_spec.rb +1 -1
- data/spec/book_specs/book_sheet_spec.rb +12 -6
- data/spec/book_specs/book_unobtr_spec.rb +5 -11
- data/spec/data/another_workbook.xls +0 -0
- data/spec/data/different_workbook.xls +0 -0
- data/spec/data/workbook.xls +0 -0
- data/spec/excel_spec.rb +247 -102
- data/spec/general_spec.rb +1 -1
- data/spec/reo_common_spec.rb +5 -1
- metadata +4 -4
data/Changelog
CHANGED
data/README.rdoc
CHANGED
@@ -184,12 +184,11 @@ or
|
|
184
184
|
|
185
185
|
book.set_nameval("name") = "value"
|
186
186
|
|
187
|
-
===
|
187
|
+
=== Bringing a workbook to the focus.
|
188
188
|
|
189
|
-
|
190
|
-
|
191
|
-
book.activate
|
189
|
+
Make the Excel instance and the workbook visible and make it available for keyboard inputs.
|
192
190
|
|
191
|
+
book.focus
|
193
192
|
|
194
193
|
=== Making the window of the workbook visible
|
195
194
|
|
@@ -419,6 +418,10 @@ Making all workbooks invisible.
|
|
419
418
|
|
420
419
|
excel1.workbooks_visible false
|
421
420
|
|
421
|
+
=== Bringing an Excel instance to the focus
|
422
|
+
|
423
|
+
Set the window of an Excel instance to the foreground.
|
424
|
+
|
422
425
|
=== Closing an Excel
|
423
426
|
|
424
427
|
excel = Excel.current
|
data/README_detail.rdoc
CHANGED
@@ -268,11 +268,11 @@ or
|
|
268
268
|
|
269
269
|
book.set_nameval("name") = "value"
|
270
270
|
|
271
|
-
===
|
271
|
+
=== Bringing a workbook to the focus.
|
272
272
|
|
273
|
-
|
273
|
+
Make the Excel instance and the workbook visible and make it available for keyboard inputs.
|
274
274
|
|
275
|
-
book.
|
275
|
+
book.focus
|
276
276
|
|
277
277
|
=== Make the window of the workbook visible.
|
278
278
|
|
@@ -496,6 +496,10 @@ Enabling DisplayAlerts whenever the Excel instance is visible.
|
|
496
496
|
|
497
497
|
excel3 = Excel.current(:reuse => true, :displayalerts => :if_visible)
|
498
498
|
|
499
|
+
=== Bringing an Excel instance to the focus
|
500
|
+
|
501
|
+
Set the window of an Excel instance to the foreground.
|
502
|
+
|
499
503
|
=== Closing an Excel
|
500
504
|
|
501
505
|
excel = Excel.current
|
data/lib/reo_console.rb
CHANGED
data/lib/robust_excel_ole.rb
CHANGED
@@ -10,3 +10,4 @@ require File.join(File.dirname(__FILE__), 'robust_excel_ole/range')
|
|
10
10
|
require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
|
11
11
|
#+#require "robust_excel_ole/version"
|
12
12
|
require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
|
13
|
+
#
|
@@ -20,7 +20,7 @@ module RobustExcelOle
|
|
20
20
|
:if_obstructed => :raise,
|
21
21
|
:if_absent => :raise,
|
22
22
|
:read_only => false,
|
23
|
-
:check_compatibility =>
|
23
|
+
:check_compatibility => false,
|
24
24
|
:update_links => :never
|
25
25
|
}
|
26
26
|
|
@@ -92,7 +92,8 @@ module RobustExcelOle
|
|
92
92
|
book.close if (book.alive? && (not book.writable) && (not options[:read_only]))
|
93
93
|
# reopens the book
|
94
94
|
book.ensure_workbook(file,options) unless book.alive?
|
95
|
-
book.visible = options[:visible]
|
95
|
+
book.visible = options[:visible].nil? ? book.excel.visible : options[:visible]
|
96
|
+
#book.visible = options[:visible] unless options[:visible].nil?
|
96
97
|
return book
|
97
98
|
end
|
98
99
|
end
|
@@ -113,7 +114,8 @@ module RobustExcelOle
|
|
113
114
|
if filename
|
114
115
|
book = bookstore.fetch(filename)
|
115
116
|
if book && book.alive?
|
116
|
-
book.visible = opts[:visible] unless opts[:visible].nil?
|
117
|
+
#book.visible = opts[:visible] unless opts[:visible].nil?
|
118
|
+
book.visible = opts[:visible].nil? ? book.excel.visible : opts[:visible]
|
117
119
|
return book
|
118
120
|
end
|
119
121
|
end
|
@@ -183,7 +185,8 @@ module RobustExcelOle
|
|
183
185
|
filename = General::absolute_path(file)
|
184
186
|
ole_workbook = WIN32OLE.connect(filename)
|
185
187
|
workbook = Book.new(ole_workbook)
|
186
|
-
workbook.visible = options[:visible] unless options[:visible].nil?
|
188
|
+
#workbook.visible = options[:visible] unless options[:visible].nil?
|
189
|
+
workbook.visible = options[:visible].nil? ? workbook.excel.visible : options[:visible]
|
187
190
|
update_links_opt =
|
188
191
|
case options[:update_links]
|
189
192
|
when :alert; RobustExcelOle::XlUpdateLinksUserSetting
|
@@ -212,7 +215,7 @@ module RobustExcelOle
|
|
212
215
|
if options[:if_absent] == :create
|
213
216
|
@ole_workbook = excel_class.current.generate_workbook(file)
|
214
217
|
else
|
215
|
-
raise FileNotFound, "file #{file.inspect} not found"
|
218
|
+
raise FileNotFound, "file #{General::absolute_path(file).inspect} not found"
|
216
219
|
end
|
217
220
|
end
|
218
221
|
@ole_workbook = @excel.Workbooks.Item(File.basename(file)) rescue nil
|
@@ -295,13 +298,13 @@ module RobustExcelOle
|
|
295
298
|
raise UnexpectedError, "unknown RuntimeError"
|
296
299
|
end
|
297
300
|
rescue WeakRef::RefError => msg
|
298
|
-
raise
|
301
|
+
raise WeakRef::RefError, "#{msg.message}"
|
299
302
|
end
|
300
303
|
# workaround for linked workbooks for Excel 2007:
|
301
304
|
# opening and closing a dummy workbook if Excel has no workbooks.
|
302
305
|
# delay: with visible: 0.2 sec, without visible almost none
|
303
306
|
count = workbooks.Count
|
304
|
-
if @excel.Version
|
307
|
+
if @excel.Version.split(".").first.to_i >= 12 && count == 0
|
305
308
|
workbooks.Add
|
306
309
|
#@excel.set_calculation(:automatic)
|
307
310
|
end
|
@@ -318,7 +321,7 @@ module RobustExcelOle
|
|
318
321
|
@excel.with_displayalerts(update_links_opt == :alert ? true : @excel.displayalerts) do
|
319
322
|
workbooks.Open(filename, { 'ReadOnly' => options[:read_only] , 'UpdateLinks' => update_links_opt } )
|
320
323
|
end
|
321
|
-
workbooks.Item(1).Close if @excel.Version
|
324
|
+
workbooks.Item(1).Close if @excel.Version.split(".").first.to_i >= 12 && count == 0
|
322
325
|
rescue WIN32OLERuntimeError => msg
|
323
326
|
# trace "WIN32OLERuntimeError: #{msg.message}"
|
324
327
|
if msg.message =~ /800A03EC/
|
@@ -330,7 +333,8 @@ module RobustExcelOle
|
|
330
333
|
begin
|
331
334
|
# workaround for bug in Excel 2010: workbook.Open does not always return the workbook with given file name
|
332
335
|
@ole_workbook = workbooks.Item(File.basename(filename))
|
333
|
-
self.visible = options[:visible]
|
336
|
+
self.visible = options[:visible].nil? ? @excel.visible : options[:visible]
|
337
|
+
#self.visible = options[:visible] unless options[:visible].nil?
|
334
338
|
#@ole_workbook.UpdateLinks = update_links_opt
|
335
339
|
@ole_workbook.CheckCompatibility = options[:check_compatibility]
|
336
340
|
rescue WIN32OLERuntimeError
|
@@ -434,7 +438,7 @@ module RobustExcelOle
|
|
434
438
|
:read_only => false,
|
435
439
|
:readonly_excel => false,
|
436
440
|
:keep_open => false,
|
437
|
-
:check_compatibility =>
|
441
|
+
:check_compatibility => false
|
438
442
|
}.merge(opts)
|
439
443
|
book = bookstore.fetch(file, :prefer_writable => (not options[:read_only]))
|
440
444
|
was_not_alive_or_nil = book.nil? || (not book.alive?)
|
@@ -467,7 +471,8 @@ module RobustExcelOle
|
|
467
471
|
open(file, :force_excel => :new, :read_only => options[:read_only])
|
468
472
|
end
|
469
473
|
end
|
470
|
-
book.excel.visible = options[:visible] unless options[:visible].nil?
|
474
|
+
#book.excel.visible = options[:visible] unless options[:visible].nil?
|
475
|
+
book.visible = options[:visible].nil? ? book.excel.visible : options[:visible]
|
471
476
|
old_check_compatibility = book.CheckCompatibility
|
472
477
|
book.CheckCompatibility = options[:check_compatibility]
|
473
478
|
yield book
|
@@ -525,7 +530,7 @@ module RobustExcelOle
|
|
525
530
|
# @return [Book], the book itself, if successfully saved, raises an exception otherwise
|
526
531
|
def save_as(file, opts = { } )
|
527
532
|
raise FileNameNotGiven, "filename is nil" if file.nil?
|
528
|
-
raise ObjectNotAlive, "workbook is not alive"
|
533
|
+
raise ObjectNotAlive, "workbook is not alive" unless alive?
|
529
534
|
raise WorkbookReadOnly, "Not opened for writing (opened with :read_only option)" if @ole_workbook.ReadOnly
|
530
535
|
options = {
|
531
536
|
:if_exists => :raise,
|
@@ -777,15 +782,10 @@ module RobustExcelOle
|
|
777
782
|
end
|
778
783
|
|
779
784
|
# brings workbook to foreground, makes it available for heyboard inputs, makes the Excel instance visible
|
780
|
-
def
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
SetForegroundWindow.call(@excel.Hwnd)
|
785
|
-
@ole_workbook.Activate # Excel 2007
|
786
|
-
rescue WIN32OLERuntimeError => msg
|
787
|
-
raise UnexpectedError, "cannot activate: #{message.msg}"
|
788
|
-
end
|
785
|
+
def focus
|
786
|
+
self.visible = true
|
787
|
+
@excel.focus
|
788
|
+
@ole_workbook.Activate
|
789
789
|
end
|
790
790
|
|
791
791
|
# returns true, if the workbook is visible, false otherwise
|
@@ -798,7 +798,11 @@ module RobustExcelOle
|
|
798
798
|
def visible= visible_value
|
799
799
|
saved = @ole_workbook.Saved
|
800
800
|
@excel.visible = true if visible_value
|
801
|
-
|
801
|
+
if @excel.Visible
|
802
|
+
if @ole_workbook.Windows.Count > 0
|
803
|
+
@ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value
|
804
|
+
end
|
805
|
+
end
|
802
806
|
@ole_workbook.Saved = saved
|
803
807
|
end
|
804
808
|
|
@@ -65,6 +65,8 @@ module RobustExcelOle
|
|
65
65
|
if stored
|
66
66
|
result = stored
|
67
67
|
else
|
68
|
+
options[:visible] = options[:visible].nil? ? ole_xl.Visible : options[:visible]
|
69
|
+
options[:displayalerts] = options[:displayalerts].nil? ? :if_visible : options[:displayalerts]
|
68
70
|
result = super(options)
|
69
71
|
result.instance_variable_set(:@ole_excel, ole_xl)
|
70
72
|
WIN32OLE.const_load(ole_xl, RobustExcelOle) unless RobustExcelOle.const_defined?(:CONSTANTS)
|
@@ -72,16 +74,19 @@ module RobustExcelOle
|
|
72
74
|
end
|
73
75
|
|
74
76
|
unless options.is_a? WIN32OLE
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
77
|
+
begin
|
78
|
+
reused = options[:reuse] && (not stored.nil?)
|
79
|
+
options = { :displayalerts => :if_visible, :visible => false}.merge(options) unless reused
|
80
|
+
visible_value = (reused && options[:visible].nil?) ? result.Visible : options[:visible]
|
81
|
+
displayalerts_value = (reused && options[:displayalerts].nil?) ?
|
82
|
+
((result.displayalerts == :if_visible) ? :if_visible : result.DisplayAlerts) : options[:displayalerts]
|
83
|
+
ole_xl.Visible = visible_value
|
84
|
+
ole_xl.DisplayAlerts = (displayalerts_value == :if_visible) ? visible_value : displayalerts_value
|
85
|
+
result.instance_variable_set(:@visible, visible_value)
|
86
|
+
result.instance_variable_set(:@displayalerts, displayalerts_value)
|
87
|
+
rescue WIN32OLERuntimeError
|
88
|
+
raise ExcelError, "cannot access Excel"
|
89
|
+
end
|
85
90
|
end
|
86
91
|
result
|
87
92
|
end
|
@@ -156,6 +161,7 @@ module RobustExcelOle
|
|
156
161
|
end
|
157
162
|
|
158
163
|
# closes Excel instances opened via RobustExcelOle
|
164
|
+
# @return [Fixnum] number of closed Excel instances
|
159
165
|
# @param [Hash] options the options
|
160
166
|
# @option options [Symbol] :if_unsaved :raise, :save, :forget, or :alert
|
161
167
|
# @option options [Boolean] :hard
|
@@ -175,15 +181,21 @@ module RobustExcelOle
|
|
175
181
|
:kill_if_timeout => false
|
176
182
|
}.merge(options)
|
177
183
|
timeout = false
|
178
|
-
number =
|
184
|
+
number = @@hwnd2excel.size
|
185
|
+
unsaved_workbooks = false
|
179
186
|
begin
|
180
187
|
status = Timeout::timeout(60) {
|
181
188
|
@@hwnd2excel.each do |hwnd, wr_excel|
|
182
189
|
excel = wr_excel.__getobj__
|
183
|
-
|
190
|
+
begin
|
191
|
+
excel.close(options)
|
192
|
+
rescue UnsavedWorkbooks
|
193
|
+
unsaved_workbooks = true
|
194
|
+
end
|
195
|
+
sleep 0.2
|
184
196
|
end
|
185
|
-
|
186
|
-
free_all_ole_objects if excels_number > 0
|
197
|
+
raise UnsavedWorkbooks, "Excel contains unsaved workbooks" if unsaved_workbooks
|
198
|
+
free_all_ole_objects if excels_number > 0 #&& (not unsaved_workbooks)
|
187
199
|
# close also interactively opened Excels, but for unsaved workbooks: hangs as soon sending a VBA method
|
188
200
|
#while (n = excels_number) > 0 do
|
189
201
|
# ole_xl = current_excel
|
@@ -416,11 +428,12 @@ module RobustExcelOle
|
|
416
428
|
end
|
417
429
|
|
418
430
|
def print_workbooks
|
419
|
-
self.Workbooks.each {|w|
|
431
|
+
self.Workbooks.each {|w| trace "#{w.Name} #{w}"}
|
420
432
|
end
|
421
433
|
|
422
434
|
# generates, saves, and closes empty workbook
|
423
|
-
def generate_workbook file_name
|
435
|
+
def generate_workbook file_name
|
436
|
+
raise FileNameNotGiven, "filename is nil" if file_name.nil?
|
424
437
|
self.Workbooks.Add
|
425
438
|
empty_workbook = self.Workbooks.Item(self.Workbooks.Count)
|
426
439
|
filename = General::absolute_path(file_name).gsub("/","\\")
|
@@ -429,7 +442,7 @@ module RobustExcelOle
|
|
429
442
|
empty_workbook.SaveAs(filename)
|
430
443
|
rescue WIN32OLERuntimeError => msg
|
431
444
|
if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
|
432
|
-
raise
|
445
|
+
raise FileNotFound, "could not save workbook with filename #{file_name.inspect}"
|
433
446
|
else
|
434
447
|
# todo some time: find out when this occurs :
|
435
448
|
raise UnexpectedError, "unknown WIN32OELERuntimeError with filename #{file_name.inspect}: \n#{msg.message}"
|
@@ -475,10 +488,13 @@ module RobustExcelOle
|
|
475
488
|
end
|
476
489
|
end
|
477
490
|
|
478
|
-
|
479
|
-
def foremost_window
|
491
|
+
def focus
|
480
492
|
self.visible = true
|
481
|
-
#
|
493
|
+
#if not Windows10 then
|
494
|
+
Win32API.new("user32","SetForegroundWindow","I","I").call(@ole_excel.Hwnd)
|
495
|
+
#else
|
496
|
+
#Win32API.new("user32","SetForegroundWindow","","I").call
|
497
|
+
#end
|
482
498
|
end
|
483
499
|
|
484
500
|
# sets calculation mode in a block
|
@@ -587,10 +603,11 @@ module RobustExcelOle
|
|
587
603
|
raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect}"
|
588
604
|
end
|
589
605
|
return opts[:default] if (value.nil? && opts[:default])
|
606
|
+
raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect}" if value == -2146826259
|
590
607
|
value
|
591
608
|
end
|
592
609
|
|
593
|
-
# assigns a value to a range given a defined
|
610
|
+
# assigns a value to a range given a defined local name
|
594
611
|
# @param [String] name the range name
|
595
612
|
# @param [Variant] value the assigned value
|
596
613
|
def set_rangeval(name,value)
|
data/spec/book_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe Book do
|
|
33
33
|
|
34
34
|
after do
|
35
35
|
Excel.kill_all
|
36
|
-
rm_tmp(@dir)
|
36
|
+
#rm_tmp(@dir)
|
37
37
|
end
|
38
38
|
|
39
39
|
describe "create file" do
|
@@ -381,7 +381,7 @@ describe Book do
|
|
381
381
|
if :if_obstructed is :close_if_saved" do
|
382
382
|
expect{
|
383
383
|
@new_book = Book.open(@simple_file1, :if_obstructed => :close_if_saved)
|
384
|
-
}.to raise_error(
|
384
|
+
}.to raise_error(WorkbookBlocked, /workbook with the same name in a different path is unsaved/)
|
385
385
|
@book.save
|
386
386
|
@new_book = Book.open(@simple_file1, :if_obstructed => :close_if_saved)
|
387
387
|
@book.should_not be_alive
|
@@ -409,7 +409,7 @@ describe Book do
|
|
409
409
|
File.delete @simple_save_file rescue nil
|
410
410
|
expect {
|
411
411
|
Book.open(@simple_save_file)
|
412
|
-
}.to raise_error(
|
412
|
+
}.to raise_error(FileNotFound, "file #{General::absolute_path(@simple_save_file).gsub("/","\\").inspect} not found")
|
413
413
|
end
|
414
414
|
end
|
415
415
|
|
@@ -901,7 +901,7 @@ describe Book do
|
|
901
901
|
book.excel.should_not == @book.excel
|
902
902
|
book.excel.should_not == new_excel
|
903
903
|
book.excel.visible.should be_false
|
904
|
-
book.excel.displayalerts.should
|
904
|
+
book.excel.displayalerts.should == :if_visible
|
905
905
|
end
|
906
906
|
new_book = Book.open(@simple_file1, :visible => true)
|
907
907
|
sheet = new_book.sheet(1)
|
@@ -1077,7 +1077,7 @@ describe Book do
|
|
1077
1077
|
end
|
1078
1078
|
end
|
1079
1079
|
|
1080
|
-
describe "alive?, filename, ==,
|
1080
|
+
describe "alive?, filename, ==, focus, saved" do
|
1081
1081
|
|
1082
1082
|
context "with alive?" do
|
1083
1083
|
|
@@ -1133,12 +1133,12 @@ describe Book do
|
|
1133
1133
|
end
|
1134
1134
|
end
|
1135
1135
|
|
1136
|
-
context "with
|
1136
|
+
context "with focus" do
|
1137
1137
|
|
1138
1138
|
before do
|
1139
1139
|
@key_sender = IO.popen 'ruby "' + File.join(File.dirname(__FILE__), '/helpers/key_sender.rb') + '" "Microsoft Office Excel" ' , "w"
|
1140
1140
|
@book = Book.open(@simple_file, :visible => true)
|
1141
|
-
@book2 = Book.open(@another_simple_file, :
|
1141
|
+
@book2 = Book.open(@another_simple_file, :visible => true)
|
1142
1142
|
end
|
1143
1143
|
|
1144
1144
|
after do
|
@@ -1147,22 +1147,22 @@ describe Book do
|
|
1147
1147
|
@key_sender.close
|
1148
1148
|
end
|
1149
1149
|
|
1150
|
-
it "should
|
1150
|
+
it "should bring a book to focus" do
|
1151
1151
|
sheet = @book.sheet(2)
|
1152
1152
|
sheet.Activate
|
1153
1153
|
sheet[2,3].Activate
|
1154
1154
|
sheet2 = @book2.sheet(2)
|
1155
1155
|
sheet2.Activate
|
1156
1156
|
sheet2[3,2].Activate
|
1157
|
-
|
1158
|
-
@book2.activate
|
1157
|
+
@book2.focus
|
1159
1158
|
@key_sender.puts "{a}{enter}"
|
1160
|
-
sleep
|
1159
|
+
sleep 0.2
|
1161
1160
|
sheet2[3,2].Value.should == "a"
|
1162
|
-
|
1163
|
-
@book.
|
1161
|
+
@book.focus
|
1162
|
+
@book.Windows(1).Visible.should be_true
|
1163
|
+
@book.Windows(@book.Name).Visible.should be_true
|
1164
1164
|
@key_sender.puts "{a}{enter}"
|
1165
|
-
sleep
|
1165
|
+
sleep 0.2
|
1166
1166
|
sheet[2,3].Value.should == "a"
|
1167
1167
|
Excel.current.should == @book.excel
|
1168
1168
|
end
|
@@ -1198,7 +1198,8 @@ describe Book do
|
|
1198
1198
|
|
1199
1199
|
context "with second argument is {:before => @book.sheet(3), :after => @sheet}" do
|
1200
1200
|
it "should arguments in the first is given priority" do
|
1201
|
-
@book.add_sheet(@sheet, :before => @book.sheet(3), :after => @sheet)
|
1201
|
+
@book.add_sheet(@sheet, :before => @book.sheet(3), :after => @sheet)
|
1202
|
+
@book.Worksheets.Count.should == 4
|
1202
1203
|
end
|
1203
1204
|
end
|
1204
1205
|
end
|