robust_excel_ole 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -2,6 +2,14 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
4
 
5
+ ## [0.6.2] - 2016-04-11
6
+
7
+ ### Changed
8
+ - Excel#focus (was Excel#activate)
9
+ - Book#focus (was Book#activate)
10
+
11
+ ### Added
12
+
5
13
  ## [0.6.1] - 2016-04-09
6
14
 
7
15
  ### Changed
data/README.rdoc CHANGED
@@ -184,12 +184,11 @@ or
184
184
 
185
185
  book.set_nameval("name") = "value"
186
186
 
187
- === Activating a workbook.
187
+ === Bringing a workbook to the focus.
188
188
 
189
- Bring the window of a workbook to the foreground, make it available for keyboard inputs, and make the Excel instance visible.
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
- === Activating a workbook.
271
+ === Bringing a workbook to the focus.
272
272
 
273
- Bring the focus to a workbook. Make it available for keyboard inputs and make the Excel instance visible.
273
+ Make the Excel instance and the workbook visible and make it available for keyboard inputs.
274
274
 
275
- book.activate
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
@@ -1,6 +1,6 @@
1
1
  #require 'lib/robust_excel_ole'
2
2
  include REO
3
- include RobustExcelOle
3
+ #include RobustExcelOle
4
4
  include General
5
5
 
6
6
  require 'irb/completion'
@@ -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 => true,
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] unless options[:visible].nil?
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 ExcelWeakRef, "#{msg.message}"
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 == "12.0" && count == 0
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 == "12.0" && count == 0
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] unless options[:visible].nil?
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 => true
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" if (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 activate
781
- @excel.visible = true
782
- begin
783
- Win32API.new("user32","SetForegroundWindow","I","I").call # Excel 2010
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
- @ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value if @excel.Visible
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
- reused = options[:reuse] && (not stored.nil?)
76
- options = { :displayalerts => :if_visible, :visible => false}.merge(options) unless reused
77
- result.visible = result.Visible
78
- result.DisplayAlerts = result.DisplayAlerts
79
- visible_value = (reused && options[:visible].nil?) ? result.visible : options[:visible]
80
- displayalerts_value = (reused && options[:displayalerts].nil?) ? result.displayalerts : options[:displayalerts]
81
- ole_xl.Visible = visible_value
82
- ole_xl.DisplayAlerts = (displayalerts_value == :if_visible) ? visible_value : displayalerts_value
83
- result.instance_variable_set(:@visible, visible_value)
84
- result.instance_variable_set(:@displayalerts, displayalerts_value)
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 = excels_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
- excel.close(options)
190
+ begin
191
+ excel.close(options)
192
+ rescue UnsavedWorkbooks
193
+ unsaved_workbooks = true
194
+ end
195
+ sleep 0.2
184
196
  end
185
- sleep 0.2
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| puts "#{w.Name} #{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 WIN32OLERuntimeError, "could not save workbook with filename #{file_name.inspect}"
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
- #Win32API.new("user32","SetForegroundWindow","I","I").call(@ole_excel.Hwnd)
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 loval name
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)
@@ -118,4 +118,5 @@ module MethodHelpers
118
118
 
119
119
  end
120
120
 
121
- REO = General
121
+ #REO = General
122
+ REO = RobustExcelOle
@@ -63,9 +63,6 @@ module RobustExcelOle
63
63
  class ExcelDamaged < ExcelError # :nodoc: #
64
64
  end
65
65
 
66
- class ExcelWeakRef < ExcelError # :nodoc: #
67
- end
68
-
69
66
  class UnsavedWorkbooks < ExcelError # :nodoc: #
70
67
  end
71
68
 
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
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(WorkbookNotSaved, /workbook with the same name in a different path is unsaved/)
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(NameNotFound, /file "#{@simple_save_file}" not found/)
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 be_false
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, ==, activate, saved" do
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 activate" do
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, :force_excel => :new, :visible => true)
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 activate a book" do
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
- Excel.current.should == @book.excel
1158
- @book2.activate
1157
+ @book2.focus
1159
1158
  @key_sender.puts "{a}{enter}"
1160
- sleep 1
1159
+ sleep 0.2
1161
1160
  sheet2[3,2].Value.should == "a"
1162
- #Excel.current.should == @book2.excel
1163
- @book.activate
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 1
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).name.should eq @book.sheet(3).name
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