robust_excel_ole 0.6 → 0.6.1

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.
Files changed (35) hide show
  1. data/Changelog +12 -0
  2. data/README.rdoc +5 -3
  3. data/README_detail.rdoc +1 -1
  4. data/examples/edit_sheets/example_adding_sheets.rb +1 -1
  5. data/examples/edit_sheets/example_expanding.rb +1 -1
  6. data/examples/open_save_close/example_control_to_excel.rb +2 -2
  7. data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +1 -1
  8. data/examples/open_save_close/example_if_obstructed_forget.rb +1 -1
  9. data/examples/open_save_close/example_if_unsaved_accept.rb +2 -2
  10. data/examples/open_save_close/example_read_only.rb +1 -1
  11. data/examples/open_save_close/example_simple.rb +1 -1
  12. data/lib/robust_excel_ole/book.rb +89 -111
  13. data/lib/robust_excel_ole/excel.rb +49 -50
  14. data/lib/robust_excel_ole/general.rb +3 -3
  15. data/lib/robust_excel_ole/reo_common.rb +78 -1
  16. data/lib/robust_excel_ole/sheet.rb +16 -23
  17. data/lib/robust_excel_ole/version.rb +1 -1
  18. data/spec/book_spec.rb +7 -7
  19. data/spec/book_specs/book_close_spec.rb +24 -5
  20. data/spec/book_specs/book_misc_spec.rb +16 -7
  21. data/spec/book_specs/book_open_spec.rb +15 -20
  22. data/spec/book_specs/book_save_spec.rb +21 -21
  23. data/spec/book_specs/book_sheet_spec.rb +3 -3
  24. data/spec/book_specs/book_unobtr_spec.rb +1 -1
  25. data/spec/data/book_with_blank.xls +0 -0
  26. data/spec/data/different_workbook.xls +0 -0
  27. data/spec/data/refed_wb.xls +0 -0
  28. data/spec/data/reference_workbook.xls +0 -0
  29. data/spec/data/referencing_wb.xls +0 -0
  30. data/spec/data/workbook.xls +0 -0
  31. data/spec/excel_spec.rb +87 -125
  32. data/spec/general_spec.rb +2 -2
  33. data/spec/reo_common_spec.rb +1 -1
  34. data/spec/sheet_spec.rb +13 -17
  35. metadata +7 -3
@@ -58,26 +58,24 @@ module RobustExcelOle
58
58
  ole_xl = current_excel
59
59
  end
60
60
  end
61
- #puts "options: #{options}"
62
- if not (ole_xl)
63
- ole_xl = WIN32OLE.new('Excel.Application')
64
- options = {
65
- :displayalerts => :if_visible,
66
- :visible => false,
67
- }.merge(options)
68
- end
61
+ ole_xl = WIN32OLE.new('Excel.Application') unless ole_xl
62
+
69
63
  hwnd = ole_xl.HWnd
70
64
  stored = hwnd2excel(hwnd)
71
65
  if stored
72
66
  result = stored
73
- else
67
+ else
74
68
  result = super(options)
75
69
  result.instance_variable_set(:@ole_excel, ole_xl)
76
70
  WIN32OLE.const_load(ole_xl, RobustExcelOle) unless RobustExcelOle.const_defined?(:CONSTANTS)
77
71
  @@hwnd2excel[hwnd] = WeakRef.new(result)
78
72
  end
73
+
79
74
  unless options.is_a? WIN32OLE
80
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
81
79
  visible_value = (reused && options[:visible].nil?) ? result.visible : options[:visible]
82
80
  displayalerts_value = (reused && options[:displayalerts].nil?) ? result.displayalerts : options[:displayalerts]
83
81
  ole_xl.Visible = visible_value
@@ -157,7 +155,7 @@ module RobustExcelOle
157
155
  close_excel(options) if managed_unsaved_workbooks(options)
158
156
  end
159
157
 
160
- # closes all Excel instances
158
+ # closes Excel instances opened via RobustExcelOle
161
159
  # @param [Hash] options the options
162
160
  # @option options [Symbol] :if_unsaved :raise, :save, :forget, or :alert
163
161
  # @option options [Boolean] :hard
@@ -170,8 +168,6 @@ module RobustExcelOle
170
168
  # :alert -> give control to Excel
171
169
  # :hard closes Excel instances soft (default: false), or, additionally kills the Excel processes hard (true)
172
170
  # :kill_if_timeout: kills Excel instances hard if the closing process exceeds a certain time limit (default: false)
173
- # @raise ExcelError if time limit has exceeded, some Excel instance cannot be closed, or
174
- # unsaved workbooks exist and option :if_unsaved is :raise
175
171
  def self.close_all(options={})
176
172
  options = {
177
173
  :if_unsaved => :raise,
@@ -181,18 +177,25 @@ module RobustExcelOle
181
177
  timeout = false
182
178
  number = excels_number
183
179
  begin
184
- status = Timeout::timeout(15) {
185
- while (excels_number > 0) do
186
- ole_xl = current_excel
187
- begin
188
- (Excel.new(ole_xl).close(options); Excel.new(ole_xl).close(options)) if ole_xl # two times necessary ?!
189
- rescue RuntimeError => msg
190
- raise msg unless msg.message =~ /failed to get Dispatch Interface/
191
- end
180
+ status = Timeout::timeout(60) {
181
+ @@hwnd2excel.each do |hwnd, wr_excel|
182
+ excel = wr_excel.__getobj__
183
+ excel.close(options)
192
184
  end
185
+ sleep 0.2
186
+ free_all_ole_objects if excels_number > 0
187
+ # close also interactively opened Excels, but for unsaved workbooks: hangs as soon sending a VBA method
188
+ #while (n = excels_number) > 0 do
189
+ # ole_xl = current_excel
190
+ # begin
191
+ # Excel.new(ole_xl).close(options) if ole_xl
192
+ # rescue RuntimeError => msg
193
+ # raise msg unless msg.message =~ /failed to get Dispatch Interface/
194
+ # end
195
+ #end
193
196
  }
194
197
  rescue Timeout::Error
195
- raise ExcelError, "close_all: timeout" unless options[:kill_if_timeout]
198
+ raise TimeOut, "close_all: timeout" unless options[:kill_if_timeout]
196
199
  timeout = true
197
200
  end
198
201
  kill_all if options[:hard] || (timeout && options[:kill_if_timeout])
@@ -203,13 +206,9 @@ module RobustExcelOle
203
206
  def close_excel(options) # :nodoc:
204
207
  ole_xl = @ole_excel
205
208
  begin
206
- if options[:if_unsaved] == :alert
207
- with_displayalerts(true) {ole_xl.Workbooks.Close}
208
- else
209
- ole_xl.Workbooks.Close
210
- end
209
+ with_displayalerts(options[:if_unsaved] == :alert) { ole_xl.Workbooks.Close }
211
210
  rescue WIN32OLERuntimeError => msg
212
- raise ExcelUserCanceled, "close: canceled by user" if msg.message =~ /80020009/ &&
211
+ trace "close: canceled by user" if msg.message =~ /80020009/ &&
213
212
  options[:if_unsaved] == :alert && (not unsaved_workbooks.empty?)
214
213
  end
215
214
  excel_hwnd = ole_xl.HWnd
@@ -245,12 +244,12 @@ module RobustExcelOle
245
244
  @ole_excel.Workbooks.each {|w| unsaved_workbooks << w unless (w.Saved || w.ReadOnly)}
246
245
  rescue RuntimeError => msg
247
246
  trace "RuntimeError: #{msg.message}"
248
- raise ExcelErrorOpen, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
247
+ raise ExcelDamaged, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
249
248
  end
250
249
  unless unsaved_workbooks.empty?
251
250
  case options[:if_unsaved]
252
251
  when :raise
253
- raise ExcelErrorClose, "Excel contains unsaved workbooks"
252
+ raise UnsavedWorkbooks, "Excel contains unsaved workbooks"
254
253
  when :save
255
254
  unsaved_workbooks.each do |workbook|
256
255
  workbook.Save
@@ -263,7 +262,7 @@ module RobustExcelOle
263
262
  when :keep_open
264
263
  return false
265
264
  else
266
- raise ExcelErrorClose, ":if_unsaved: invalid option: #{options[:if_unsaved].inspect}"
265
+ raise OptionInvalid, ":if_unsaved: invalid option: #{options[:if_unsaved].inspect}"
267
266
  end
268
267
  end
269
268
  return true
@@ -318,7 +317,6 @@ module RobustExcelOle
318
317
  WIN32OLE.connect("winmgmts:\\\\.").InstancesOf("win32_process").select{|p| (p.name == "EXCEL.EXE")}.size
319
318
  end
320
319
 
321
- =begin
322
320
  # provide Excel objects
323
321
  # (so far restricted to all Excel instances opened with RobustExcelOle,
324
322
  # not for Excel instances opened by the user)
@@ -347,7 +345,6 @@ module RobustExcelOle
347
345
  end
348
346
  result
349
347
  end
350
- =end
351
348
 
352
349
  def excel # :nodoc: #
353
350
  self
@@ -413,7 +410,7 @@ module RobustExcelOle
413
410
  self.Workbooks.each {|w| result << w unless (w.Saved || w.ReadOnly)}
414
411
  rescue RuntimeError => msg
415
412
  trace "RuntimeError: #{msg.message}"
416
- raise ExcelErrorOpen, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
413
+ raise ExcelDamaged, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
417
414
  end
418
415
  result
419
416
  end
@@ -432,10 +429,10 @@ module RobustExcelOle
432
429
  empty_workbook.SaveAs(filename)
433
430
  rescue WIN32OLERuntimeError => msg
434
431
  if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
435
- raise ExcelErrorSave, "could not save workbook with filename #{file_name.inspect}"
432
+ raise WIN32OLERuntimeError, "could not save workbook with filename #{file_name.inspect}"
436
433
  else
437
434
  # todo some time: find out when this occurs :
438
- raise ExcelErrorSaveUnknown, "unknown WIN32OELERuntimeError with filename #{file_name.inspect}: \n#{msg.message}"
435
+ raise UnexpectedError, "unknown WIN32OELERuntimeError with filename #{file_name.inspect}: \n#{msg.message}"
439
436
  end
440
437
  end
441
438
  end
@@ -474,10 +471,16 @@ module RobustExcelOle
474
471
  end
475
472
  rescue RuntimeError => msg
476
473
  trace "RuntimeError: #{msg.message}"
477
- raise ExcelErrorOpen, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
474
+ raise ExcelDamaged, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
478
475
  end
479
476
  end
480
477
 
478
+
479
+ def foremost_window
480
+ self.visible = true
481
+ #Win32API.new("user32","SetForegroundWindow","I","I").call(@ole_excel.Hwnd)
482
+ end
483
+
481
484
  # sets calculation mode in a block
482
485
  def with_calculation(calculation_mode = :automatic)
483
486
  if @ole_excel.Workbooks.Count > 0
@@ -522,13 +525,12 @@ module RobustExcelOle
522
525
  # @param [String] name the range name
523
526
  # @param [Hash] opts the options
524
527
  # @option opts [Variant] :default default value (default: nil)
525
- # @raise ExcelError if name is not defined or if value of the range cannot be evaluated
526
528
  def nameval(name, opts = {:default => nil})
527
529
  begin
528
530
  name_obj = self.Names.Item(name)
529
531
  rescue WIN32OLERuntimeError
530
532
  return opts[:default] if opts[:default]
531
- raise ExcelError, "cannot find name #{name.inspect}"
533
+ raise NameNotFound, "cannot find name #{name.inspect}"
532
534
  end
533
535
  begin
534
536
  value = name_obj.RefersToRange.Value
@@ -537,12 +539,12 @@ module RobustExcelOle
537
539
  value = self.Evaluate(name_obj.Name)
538
540
  rescue WIN32OLERuntimeError
539
541
  return opts[:default] if opts[:default]
540
- raise ExcelError, "cannot evaluate name #{name.inspect}"
542
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect}"
541
543
  end
542
544
  end
543
545
  if value == -2146826259
544
546
  return opts[:default] if opts[:default]
545
- raise ExcelError, "cannot evaluate name #{name.inspect}"
547
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect}"
546
548
  end
547
549
  return opts[:default] if (value.nil? && opts[:default])
548
550
  value
@@ -551,17 +553,16 @@ module RobustExcelOle
551
553
  # assigns a value to a range with given name
552
554
  # @param [String] name the range name
553
555
  # @param [Variant] value the assigned value
554
- # @raise ExcelError if name is not in the sheet or the value cannot be assigned
555
556
  def set_nameval(name,value)
556
557
  begin
557
558
  name_obj = self.Names.Item(name)
558
559
  rescue WIN32OLERuntimeError
559
- raise ExcelError, "cannot find name #{name.inspect}"
560
+ raise NameNotFound, "cannot find name #{name.inspect}"
560
561
  end
561
562
  begin
562
563
  name_obj.RefersToRange.Value = value
563
564
  rescue WIN32OLERuntimeError
564
- raise ExcelError, "cannot assign value to range named #{name.inspect}"
565
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect}"
565
566
  end
566
567
  end
567
568
 
@@ -571,20 +572,19 @@ module RobustExcelOle
571
572
  # @param [String] name the range name
572
573
  # @param [Hash] opts the options
573
574
  # @option opts [Symbol] :default the default value that is provided if no contents could be returned
574
- # @raise ExcelError if range name is not definied in the worksheet or if range value could not be evaluated
575
575
  # @return [Variant] the contents of a range with given name
576
576
  def rangeval(name, opts = {:default => nil})
577
577
  begin
578
578
  range = self.Range(name)
579
579
  rescue WIN32OLERuntimeError
580
580
  return opts[:default] if opts[:default]
581
- raise ExcelError, "cannot find name #{name.inspect}"
581
+ raise NameNotFound, "cannot find name #{name.inspect}"
582
582
  end
583
583
  begin
584
584
  value = range.Value
585
585
  rescue WIN32OLERuntimeError
586
586
  return opts[:default] if opts[:default]
587
- raise ExcelError, "cannot determine value of range named #{name.inspect}"
587
+ raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect}"
588
588
  end
589
589
  return opts[:default] if (value.nil? && opts[:default])
590
590
  value
@@ -593,17 +593,16 @@ module RobustExcelOle
593
593
  # assigns a value to a range given a defined loval name
594
594
  # @param [String] name the range name
595
595
  # @param [Variant] value the assigned value
596
- # @raise ExcelError if name is not in the sheet or the value cannot be assigned
597
596
  def set_rangeval(name,value)
598
597
  begin
599
598
  range = self.Range(name)
600
599
  rescue WIN32OLERuntimeError
601
- raise ExcelError, "cannot find name #{name.inspect}"
600
+ raise NameNotFound, "cannot find name #{name.inspect}"
602
601
  end
603
602
  begin
604
603
  range.Value = value
605
604
  rescue WIN32OLERuntimeError
606
- raise ExcelError, "cannot assign value to range named #{name.inspect} in #{self.name}"
605
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.name}"
607
606
  end
608
607
  end
609
608
 
@@ -635,7 +634,7 @@ module RobustExcelOle
635
634
  def method_missing(name, *args) # :nodoc: #
636
635
  if name.to_s[0,1] =~ /[A-Z]/
637
636
  begin
638
- raise ExcelError, "method missing: Excel not alive" unless alive?
637
+ raise ObjectNotAlive, "method missing: Excel not alive" unless alive?
639
638
  @ole_excel.send(name, *args)
640
639
  rescue WIN32OLERuntimeError => msg
641
640
  if msg.message =~ /unknown property or method/
@@ -9,7 +9,7 @@ module General
9
9
  end
10
10
 
11
11
  def canonize(filename) # :nodoc: #
12
- raise ExcelError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
12
+ raise TypeErrorREO, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
13
13
  normalize(filename).downcase
14
14
  end
15
15
 
@@ -42,7 +42,7 @@ class ::String # :nodoc: #
42
42
  begin
43
43
  File.join self, path_part
44
44
  rescue TypeError
45
- raise "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
45
+ raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
46
46
  end
47
47
  end
48
48
  end
@@ -108,7 +108,7 @@ end
108
108
  module MethodHelpers
109
109
 
110
110
  def respond_to?(meth_name, include_private = false) # :nodoc: #
111
- raise ExcelError, "respond_to?: #{self.class.name} not alive" unless alive?
111
+ raise ObjectNotAlive, "respond_to?: #{self.class.name} not alive" unless alive?
112
112
  super
113
113
  end
114
114
 
@@ -7,7 +7,7 @@ File.delete REO_LOG_FILE rescue nil
7
7
  class REOCommon
8
8
 
9
9
  def excel
10
- raise ExcelError, "receiver instance is neither an Excel nor a Book"
10
+ raise TypeErrorREO, "receiver instance is neither an Excel nor a Book"
11
11
  end
12
12
 
13
13
  def own_methods
@@ -39,3 +39,80 @@ class REOCommon
39
39
  end
40
40
  end
41
41
  end
42
+
43
+ module RobustExcelOle
44
+
45
+ class REOError < RuntimeError # :nodoc: #
46
+ end
47
+
48
+ class ExcelError < REOError # :nodoc: #
49
+ end
50
+
51
+ class WorkbookError < REOError # :nodoc: #
52
+ end
53
+
54
+ class FileError < REOError # :nodoc: #
55
+ end
56
+
57
+ class NamesError < REOError # :nodoc: #
58
+ end
59
+
60
+ class MiscError < REOError # :nodoc: #
61
+ end
62
+
63
+ class ExcelDamaged < ExcelError # :nodoc: #
64
+ end
65
+
66
+ class ExcelWeakRef < ExcelError # :nodoc: #
67
+ end
68
+
69
+ class UnsavedWorkbooks < ExcelError # :nodoc: #
70
+ end
71
+
72
+ class WorkbookBlocked < WorkbookError # :nodoc: #
73
+ end
74
+
75
+ class WorkbookNotSaved < WorkbookError # :nodoc: #
76
+ end
77
+
78
+ class WorkbookReadOnly < WorkbookError # :nodoc: #
79
+ end
80
+
81
+ class WorkbookBeingUsed < WorkbookError # :nodoc: #
82
+ end
83
+
84
+ class FileNotFound < FileError # :nodoc: #
85
+ end
86
+
87
+ class FileNameNotGiven < FileError # :nodoc: #
88
+ end
89
+
90
+ class FileAlreadyExists < FileError # :nodoc: #
91
+ end
92
+
93
+ class NameNotFound < NamesError # :nodoc: #
94
+ end
95
+
96
+ class NameAlreadyExists < NamesError # :nodoc: #
97
+ end
98
+
99
+ class RangeNotEvaluatable < MiscError # :nodoc: #
100
+ end
101
+
102
+ class OptionInvalid < MiscError # :nodoc: #
103
+ end
104
+
105
+ class ObjectNotAlive < MiscError # :nodoc: #
106
+ end
107
+
108
+ class TypeErrorREO < REOError # :nodoc: #
109
+ end
110
+
111
+ class TimeOut < REOError # :nodoc: #
112
+ end
113
+
114
+ class UnexpectedError < REOError # :nodoc: #
115
+ end
116
+
117
+ end
118
+
@@ -34,10 +34,10 @@ module RobustExcelOle
34
34
  @worksheet.Name = new_name
35
35
  rescue WIN32OLERuntimeError => msg
36
36
  if msg.message =~ /800A03EC/
37
- raise ExcelErrorSheet, "sheet name #{new_name.inspect} already exists"
37
+ raise NameAlreadyExists, "sheet name #{new_name.inspect} already exists"
38
38
  else
39
39
  trace "#{msg.message}"
40
- raise ExcelErrorSheetUnknown
40
+ raise UnexpectedError
41
41
  end
42
42
  end
43
43
  end
@@ -54,10 +54,10 @@ module RobustExcelOle
54
54
  name = p1
55
55
  begin
56
56
  nameval(name)
57
- rescue SheetError
57
+ rescue REOError
58
58
  begin
59
59
  book_class.new(self.Parent).nameval(name)
60
- rescue ExcelError
60
+ rescue REOError
61
61
  rangeval(name)
62
62
  end
63
63
  end
@@ -74,10 +74,10 @@ module RobustExcelOle
74
74
  name, value = p1, p2
75
75
  begin
76
76
  set_nameval(name, value)
77
- rescue SheetError
77
+ rescue REOError
78
78
  begin
79
79
  workbook.set_nameval(name, value)
80
- rescue ExcelError
80
+ rescue REOError
81
81
  set_rangeval(name, value)
82
82
  end
83
83
  end
@@ -136,13 +136,12 @@ module RobustExcelOle
136
136
  # @param [String] name the name of a range
137
137
  # @param [Hash] opts the options
138
138
  # @option opts [Variant] :default default value (default: nil)
139
- # @raise SheetError if name is not defined or if value of the range cannot be evaluated
140
139
  def nameval(name, opts = {:default => nil})
141
140
  begin
142
141
  name_obj = self.Names.Item(name)
143
142
  rescue WIN32OLERuntimeError
144
143
  return opts[:default] if opts[:default]
145
- raise SheetError, "name #{name.inspect} not in #{self.Name}"
144
+ raise NameNotFound, "name #{name.inspect} not in #{self.Name}"
146
145
  end
147
146
  begin
148
147
  value = name_obj.RefersToRange.Value
@@ -151,12 +150,12 @@ module RobustExcelOle
151
150
  value = self.Evaluate(name_obj.Name)
152
151
  rescue WIN32OLERuntimeError
153
152
  return opts[:default] if opts[:default]
154
- raise SheetError, "cannot evaluate name #{name.inspect} in #{self.Name}"
153
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{self.Name}"
155
154
  end
156
155
  end
157
156
  if value == RobustExcelOle::XlErrName # -2146826259
158
157
  return opts[:default] if opts[:default]
159
- raise SheetError, "cannot evaluate name #{name.inspect} in #{self.Name}"
158
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{self.Name}"
160
159
  end
161
160
  return opts[:default] if (value.nil? && opts[:default])
162
161
  value
@@ -165,17 +164,16 @@ module RobustExcelOle
165
164
  # assigns a value to a range
166
165
  # @param [String] name the name of a range
167
166
  # @param [Variant] value the assigned value
168
- # @raise SheetError if name is not in the sheet or the value cannot be assigned
169
167
  def set_nameval(name,value)
170
168
  begin
171
169
  name_obj = self.Names.Item(name)
172
170
  rescue WIN32OLERuntimeError
173
- raise SheetError, "name #{name.inspect} not in #{self.name}"
171
+ raise NameNotFound, "name #{name.inspect} not in #{self.name}"
174
172
  end
175
173
  begin
176
174
  name_obj.RefersToRange.Value = value
177
175
  rescue WIN32OLERuntimeError
178
- raise SheetError, "cannot assign value to range named #{name.inspect} in #{self.name}"
176
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.name}"
179
177
  end
180
178
  end
181
179
 
@@ -185,20 +183,19 @@ module RobustExcelOle
185
183
  # @param [String] name the name of a range
186
184
  # @param [Hash] opts the options
187
185
  # @option opts [Symbol] :default the default value that is provided if no contents could be returned
188
- # @raise SheetError if range name is not definied in the worksheet or if range value could not be evaluated
189
186
  # @return [Variant] the contents of a range with given name
190
187
  def rangeval(name, opts = {:default => nil})
191
188
  begin
192
189
  range = self.Range(name)
193
190
  rescue WIN32OLERuntimeError
194
191
  return opts[:default] if opts[:default]
195
- raise SheetError, "name #{name.inspect} not in #{self.name}"
192
+ raise NameNotFound, "name #{name.inspect} not in #{self.name}"
196
193
  end
197
194
  begin
198
195
  value = range.Value
199
196
  rescue WIN32OLERuntimeError
200
197
  return opts[:default] if opts[:default]
201
- raise SheetError, "cannot determine value of range named #{name.inspect} in #{self.name}"
198
+ raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.name}"
202
199
  end
203
200
  return opts[:default] if (value.nil? && opts[:default])
204
201
  value
@@ -207,17 +204,16 @@ module RobustExcelOle
207
204
  # assigns a value to a range given a defined local name
208
205
  # @param [String] name the name of a range
209
206
  # @param [Variant] value the assigned value
210
- # @raise SheetError if name is not in the sheet or the value cannot be assigned
211
207
  def set_rangeval(name,value)
212
208
  begin
213
209
  range = self.Range(name)
214
210
  rescue WIN32OLERuntimeError
215
- raise SheetError, "name #{name.inspect} not in #{self.name}"
211
+ raise NameNotFound, "name #{name.inspect} not in #{self.name}"
216
212
  end
217
213
  begin
218
214
  range.Value = value
219
215
  rescue WIN32OLERuntimeError
220
- raise SheetError, "cannot assign value to range named #{name.inspect} in #{self.name}"
216
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.name}"
221
217
  end
222
218
  end
223
219
 
@@ -236,7 +232,7 @@ module RobustExcelOle
236
232
  end
237
233
  rescue WIN32OLERuntimeError => msg
238
234
  trace "WIN32OLERuntimeError: #{msg.message}"
239
- raise SheetError, "cannot add name #{name.inspect} to cell with row #{row.inspect} and column #{column.inspect}"
235
+ raise RangeNotEvaluatable, "cannot add name #{name.inspect} to cell with row #{row.inspect} and column #{column.inspect}"
240
236
  end
241
237
  end
242
238
 
@@ -297,7 +293,4 @@ module RobustExcelOle
297
293
 
298
294
  public
299
295
 
300
- class SheetError < RuntimeError # :nodoc: #
301
- end
302
-
303
296
  end
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "0.6"
2
+ VERSION = "0.6.1"
3
3
  end
data/spec/book_spec.rb CHANGED
@@ -277,7 +277,7 @@ describe Book do
277
277
  it "should raise an error, if :if_unsaved is :raise" do
278
278
  expect {
279
279
  @new_book = Book.open(@simple_file, :if_unsaved => :raise)
280
- }.to raise_error(ExcelErrorOpen, /workbook is already open but not saved: "workbook.xls"/)
280
+ }.to raise_error(WorkbookNotSaved, /workbook is already open but not saved: "workbook.xls"/)
281
281
  end
282
282
 
283
283
  it "should let the book open, if :if_unsaved is :accept" do
@@ -316,7 +316,7 @@ describe Book do
316
316
  @key_sender.puts "{right}{enter}"
317
317
  expect{
318
318
  Book.open(@simple_file, :if_unsaved => :alert)
319
- }.to raise_error(ExcelErrorOpen, "open: user canceled or open error")
319
+ }.to raise_error(WorkbookError, "open: user canceled or open error")
320
320
  @book.should be_alive
321
321
  end
322
322
 
@@ -338,7 +338,7 @@ describe Book do
338
338
  @key_sender.puts "{right}{enter}"
339
339
  expect{
340
340
  Book.open(@simple_file, :if_unsaved => :excel)
341
- }.to raise_error(ExcelErrorOpen, "open: user canceled or open error")
341
+ }.to raise_error(WorkbookError, "open: user canceled or open error")
342
342
  @book.should be_alive
343
343
  end
344
344
 
@@ -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(ExcelErrorOpen, /workbook with the same name in a different path is unsaved/)
384
+ }.to raise_error(WorkbookNotSaved, /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(ExcelErrorOpen, /file "#{@simple_save_file}" not found/)
412
+ }.to raise_error(NameNotFound, /file "#{@simple_save_file}" not found/)
413
413
  end
414
414
  end
415
415
 
@@ -569,7 +569,7 @@ describe Book do
569
569
  begin
570
570
  @excel1.close
571
571
  @excel2.close
572
- rescue ExcelErrorOpen => msg
572
+ rescue ExcelError => msg
573
573
  puts "ExcelError: #{msg.message}" if msg.message =~ /Excel instance not alive or damaged/
574
574
  end
575
575
  end
@@ -1025,7 +1025,7 @@ describe Book do
1025
1025
  it "should raise error by default" do
1026
1026
  expect{
1027
1027
  @book.close(:if_unsaved => :raise)
1028
- }.to raise_error(ExcelErrorClose, /workbook is unsaved: "workbook.xls"/)
1028
+ }.to raise_error(WorkbookNotSaved, /workbook is unsaved: "workbook.xls"/)
1029
1029
  end
1030
1030
 
1031
1031
  it "should save the book before close with option :save" do
@@ -82,13 +82,13 @@ describe Book do
82
82
  it "should raise error with option :raise" do
83
83
  expect{
84
84
  @book.close(:if_unsaved => :raise)
85
- }.to raise_error(ExcelErrorClose, /workbook is unsaved: "workbook.xls"/)
85
+ }.to raise_error(WorkbookNotSaved, /workbook is unsaved: "workbook.xls"/)
86
86
  end
87
87
 
88
88
  it "should raise error by default" do
89
89
  expect{
90
90
  @book.close(:if_unsaved => :raise)
91
- }.to raise_error(ExcelErrorClose, /workbook is unsaved: "workbook.xls"/)
91
+ }.to raise_error(WorkbookNotSaved, /workbook is unsaved: "workbook.xls"/)
92
92
  end
93
93
 
94
94
  it "should keep the book open" do
@@ -118,10 +118,29 @@ describe Book do
118
118
  end
119
119
  end
120
120
 
121
+ it "should close the book and leave its file untouched with option :forget even with displayalerts true" do
122
+ ole_workbook = @book.ole_workbook
123
+ excel = @book.excel
124
+ excel.displayalerts = true
125
+ excel.Workbooks.Count.should == 1
126
+ @book.close(:if_unsaved => :forget)
127
+ excel.Workbooks.Count.should == 0
128
+ @book.ole_workbook.should == nil
129
+ @book.should_not be_alive
130
+ expect{
131
+ ole_workbook.Name}.to raise_error(WIN32OLERuntimeError)
132
+ new_book = Book.open(@simple_file1)
133
+ begin
134
+ new_book.ole_workbook.Worksheets.Count.should == @sheet_count
135
+ ensure
136
+ new_book.close
137
+ end
138
+ end
139
+
121
140
  it "should raise an error for invalid option" do
122
141
  expect {
123
142
  @book.close(:if_unsaved => :invalid_option)
124
- }.to raise_error(ExcelErrorClose, ":if_unsaved: invalid option: :invalid_option")
143
+ }.to raise_error(OptionInvalid, ":if_unsaved: invalid option: :invalid_option")
125
144
  end
126
145
 
127
146
 
@@ -163,7 +182,7 @@ describe Book do
163
182
  if answer == :cancel then
164
183
  expect {
165
184
  @book.close(:if_unsaved => :alert)
166
- }.to raise_error(ExcelUserCanceled, "close: canceled by user")
185
+ }.to_not raise_error
167
186
  @book.ole_workbook.Saved.should be_false
168
187
  @book.ole_workbook.should_not == nil
169
188
  @book.should be_alive
@@ -206,7 +225,7 @@ describe Book do
206
225
  if answer == :cancel then
207
226
  expect {
208
227
  @book.close(:if_unsaved => :excel)
209
- }.to raise_error(ExcelUserCanceled, "close: canceled by user")
228
+ }.to_not raise_error
210
229
  @book.ole_workbook.Saved.should be_false
211
230
  @book.ole_workbook.should_not == nil
212
231
  @book.should be_alive