robust_excel_ole 1.15 → 1.18.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog +27 -0
  3. data/README.rdoc +18 -1
  4. data/___dummy_workbook.xls +0 -0
  5. data/docs/README_excel.rdoc +6 -0
  6. data/docs/README_open.rdoc +18 -2
  7. data/docs/README_ranges.rdoc +11 -2
  8. data/examples/example_ruby_library.rb +27 -0
  9. data/extconf.rb +13 -0
  10. data/lib/robust_excel_ole.rb +4 -3
  11. data/lib/robust_excel_ole/{address.rb → address_tool.rb} +23 -22
  12. data/lib/robust_excel_ole/{reo_common.rb → base.rb} +2 -90
  13. data/lib/robust_excel_ole/bookstore.rb +14 -77
  14. data/lib/robust_excel_ole/cell.rb +30 -18
  15. data/lib/robust_excel_ole/excel.rb +71 -41
  16. data/lib/robust_excel_ole/general.rb +39 -14
  17. data/lib/robust_excel_ole/range.rb +42 -19
  18. data/lib/robust_excel_ole/range_owners.rb +40 -25
  19. data/lib/robust_excel_ole/vba_objects.rb +30 -0
  20. data/lib/robust_excel_ole/version.rb +1 -1
  21. data/lib/robust_excel_ole/workbook.rb +241 -235
  22. data/lib/robust_excel_ole/worksheet.rb +42 -21
  23. data/lib/rubygems_plugin.rb +3 -0
  24. data/robust_excel_ole.gemspec +1 -0
  25. data/spec/address_tool_spec.rb +175 -0
  26. data/spec/{reo_common_spec.rb → base_spec.rb} +11 -30
  27. data/spec/bookstore_spec.rb +3 -3
  28. data/spec/cell_spec.rb +67 -25
  29. data/spec/data/more_data/workbook.xls +0 -0
  30. data/spec/excel_spec.rb +41 -275
  31. data/spec/general_spec.rb +17 -23
  32. data/spec/range_spec.rb +57 -3
  33. data/spec/workbook_spec.rb +7 -75
  34. data/spec/workbook_specs/workbook_misc_spec.rb +11 -21
  35. data/spec/workbook_specs/workbook_open_spec.rb +570 -30
  36. data/spec/workbook_specs/workbook_unobtr_spec.rb +33 -33
  37. data/spec/worksheet_spec.rb +36 -4
  38. metadata +10 -6
  39. data/spec/address_spec.rb +0 -174
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RobustExcelOle
4
4
 
5
- class RangeOwners < REOCommon
5
+ class RangeOwners < VbaObjects
6
6
 
7
7
  # returns the contents of a range with given name
8
8
  # if the name could not be found or the value could not be determined,
@@ -22,12 +22,13 @@ module RobustExcelOle
22
22
  raise
23
23
  end
24
24
  ole_range = name_obj.RefersToRange
25
+ worksheet = self if self.is_a?(Worksheet)
25
26
  value = begin
26
27
  #name_obj.RefersToRange.Value
27
- if !::JRUBY_BUG_RANGES
28
+ if !::RANGES_JRUBY_BUG
28
29
  ole_range.Value
29
30
  else
30
- values = RobustExcelOle::Range.new(ole_range).v
31
+ values = RobustExcelOle::Range.new(ole_range, worksheet).v
31
32
  (values.size==1 && values.first.size==1) ? values.first.first : values
32
33
  end
33
34
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
@@ -39,10 +40,10 @@ module RobustExcelOle
39
40
  #sheet.Evaluate(name_obj.Name).Value
40
41
  # does it result in a range?
41
42
  ole_range = sheet.Evaluate(name_obj.Name)
42
- if !::JRUBY_BUG_RANGES
43
+ if !::RANGES_JRUBY_BUG
43
44
  ole_range.Value
44
45
  else
45
- values = RobustExcelOle::Range.new(ole_range).v
46
+ values = RobustExcelOle::Range.new(ole_range, worksheet).v
46
47
  (values.size==1 && values.first.size==1) ? values.first.first : values
47
48
  end
48
49
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
@@ -61,7 +62,8 @@ module RobustExcelOle
61
62
  # sets the contents of a range
62
63
  # @param [String] name the name of a range
63
64
  # @param [Variant] value the contents of the range
64
- def set_namevalue_glob(name, value, opts = { }) # opts is deprecated
65
+ # @option opts [Symbol] :color the color of the cell when set
66
+ def set_namevalue_glob(name, value, opts = { })
65
67
  begin
66
68
  name_obj = begin
67
69
  name_object(name)
@@ -69,13 +71,12 @@ module RobustExcelOle
69
71
  raise
70
72
  end
71
73
  ole_range = name_object(name).RefersToRange
72
- workbook.color_if_modified = opts[:color] unless opts[:color].nil?
73
- ole_range.Interior.ColorIndex = workbook.color_if_modified unless workbook.color_if_modified.nil?
74
- if !::JRUBY_BUG_RANGES
74
+ ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
75
+ if !::RANGES_JRUBY_BUG
75
76
  ole_range.Value = value
76
77
  else
77
78
  address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
78
- row, col = Address.int_range(address_r1c1)
79
+ row, col = address_tool.as_integer_ranges(address_r1c1)
79
80
  row.each_with_index do |r,i|
80
81
  col.each_with_index do |c,j|
81
82
  ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value )
@@ -105,11 +106,12 @@ module RobustExcelOle
105
106
  raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
106
107
  end
107
108
  begin
109
+ worksheet = self if self.is_a?(Worksheet)
108
110
  #value = ole_range.Value
109
- value = if !::JRUBY_BUG_RANGES
111
+ value = if !::RANGES_JRUBY_BUG
110
112
  ole_range.Value
111
113
  else
112
- values = RobustExcelOle::Range.new(ole_range).v
114
+ values = RobustExcelOle::Range.new(ole_range, worksheet).v
113
115
  (values.size==1 && values.first.size==1) ? values.first.first : values
114
116
  end
115
117
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
@@ -127,21 +129,21 @@ module RobustExcelOle
127
129
  # assigns a value to a range given a locally defined name
128
130
  # @param [String] name the name of a range
129
131
  # @param [Variant] value the assigned value
130
- def set_namevalue(name, value, opts = { }) # opts is deprecated
132
+ # @option opts [Symbol] :color the color of the cell when set
133
+ def set_namevalue(name, value, opts = { })
131
134
  begin
132
- return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook) # opts deprecated
135
+ return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
133
136
  ole_range = self.Range(name)
134
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
137
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
135
138
  raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
136
139
  end
137
140
  begin
138
- workbook.color_if_modified = opts[:color] unless opts[:color].nil?
139
- ole_range.Interior.ColorIndex = workbook.color_if_modified unless workbook.color_if_modified.nil?
140
- if !::JRUBY_BUG_RANGES
141
+ ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
142
+ if !::RANGES_JRUBY_BUG
141
143
  ole_range.Value = value
142
144
  else
143
145
  address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
144
- row, col = Address.int_range(address_r1c1)
146
+ row, col = address_tool.as_integer_ranges(address_r1c1)
145
147
  row.each_with_index do |r,i|
146
148
  col.each_with_index do |c,j|
147
149
  ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value)
@@ -180,10 +182,11 @@ module RobustExcelOle
180
182
  # @return [Range] a range
181
183
  def range(name_or_address, address2 = :__not_provided)
182
184
  begin
185
+ worksheet = self if self.is_a?(Worksheet)
183
186
  if address2 == :__not_provided
184
187
  range = if name_or_address.is_a?(String)
185
188
  begin
186
- RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange)
189
+ RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange, worksheet)
187
190
  rescue NameNotFound
188
191
  nil
189
192
  end
@@ -192,8 +195,8 @@ module RobustExcelOle
192
195
  if self.is_a?(Worksheet) && (range.nil? || (address2 != :__not_provided))
193
196
  address = name_or_address
194
197
  address = [name_or_address,address2] unless address2 == :__not_provided
195
- self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' + Address.r1c1(address))
196
- range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange)
198
+ self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' + address_tool.as_r1c1(address))
199
+ range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange, worksheet)
197
200
  self.Names.Item('__dummy001').Delete
198
201
  workbook = self.is_a?(Workbook) ? self : self.workbook
199
202
  workbook.save
@@ -216,7 +219,7 @@ module RobustExcelOle
216
219
  def add_name(name, addr, addr_deprecated = :__not_provided)
217
220
  addr = [addr,addr_deprecated] unless addr_deprecated == :__not_provided
218
221
  begin
219
- self.Names.Add(name, nil, true, nil, nil, nil, nil, nil, nil, '=' + Address.r1c1(addr))
222
+ self.Names.Add(name, nil, true, nil, nil, nil, nil, nil, nil, '=' + address_tool.as_r1c1(addr))
220
223
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
221
224
  raise RangeNotEvaluatable, "cannot add name #{name.inspect} to range #{addr.inspect}"
222
225
  end
@@ -257,13 +260,13 @@ module RobustExcelOle
257
260
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
258
261
  raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
259
262
  end
260
- end
263
+ end
261
264
 
262
265
  private
263
266
 
264
267
  def name_object(name)
265
268
  self.Names.Item(name)
266
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
269
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
267
270
  begin
268
271
  self.Parent.Names.Item(name)
269
272
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
@@ -273,4 +276,16 @@ module RobustExcelOle
273
276
 
274
277
  end
275
278
 
279
+ # @private
280
+ class NameNotFound < NamesREOError
281
+ end
282
+
283
+ # @private
284
+ class NameAlreadyExists < NamesREOError
285
+ end
286
+
287
+ # @private
288
+ class RangeNotCreated < MiscREOError
289
+ end
290
+
276
291
  end
@@ -0,0 +1,30 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module RobustExcelOle
4
+
5
+ class VbaObjects < Base
6
+
7
+ def to_reo
8
+ self
9
+ end
10
+
11
+ # @private
12
+ def address_tool
13
+ excel.address_tool
14
+ end
15
+
16
+ end
17
+
18
+ # @private
19
+ class RangeNotEvaluatable < MiscREOError
20
+ end
21
+
22
+ # @private
23
+ class OptionInvalid < MiscREOError
24
+ end
25
+
26
+ # @private
27
+ class ObjectNotAlive < MiscREOError
28
+ end
29
+
30
+ end
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "1.15"
2
+ VERSION = "1.18.2"
3
3
  end
@@ -12,32 +12,33 @@ module RobustExcelOle
12
12
  class Workbook < RangeOwners
13
13
 
14
14
  #include General
15
-
16
- attr_accessor :excel
17
- attr_accessor :ole_workbook
18
- attr_accessor :stored_filename
19
- attr_accessor :color_if_modified
20
- attr_accessor :was_open
15
+
16
+ attr_reader :ole_workbook
17
+ attr_reader :excel
18
+ attr_reader :stored_filename
21
19
 
22
20
  alias ole_object ole_workbook
23
21
 
24
- DEFAULT_OPEN_OPTS = {
25
- :default => {:excel => :current},
22
+ CORE_DEFAULT_OPEN_OPTS = {
23
+ :default => {:excel => :current},
26
24
  :force => {},
27
- :update_links => :never,
25
+ :update_links => :never
26
+ }.freeze
27
+
28
+ DEFAULT_OPEN_OPTS = {
28
29
  :if_unsaved => :raise,
29
30
  :if_obstructed => :raise,
30
31
  :if_absent => :raise,
31
32
  :if_exists => :raise
32
- #:check_compatibility => false
33
- }.freeze
33
+ }.merge(CORE_DEFAULT_OPEN_OPTS).freeze
34
34
 
35
- CORE_DEFAULT_OPEN_OPTS = {
36
- :default => {:excel => :current}, :force => {}, :update_links => :never
37
- }.freeze
38
-
39
- ABBREVIATIONS = [[:default,:d], [:force, :f], [:excel, :e], [:visible, :v],
40
- [:if_obstructed, :if_blocked]].freeze
35
+ ABBREVIATIONS = [
36
+ [:default,:d],
37
+ [:force, :f],
38
+ [:excel, :e],
39
+ [:visible, :v],
40
+ [:if_obstructed, :if_blocked]
41
+ ].freeze
41
42
 
42
43
 
43
44
  # opens a workbook.
@@ -83,51 +84,59 @@ module RobustExcelOle
83
84
  # :visible true -> makes the workbook visible
84
85
  # :check_compatibility true -> check compatibility when saving
85
86
  # :update_links true -> user is being asked how to update links, false -> links are never updated
86
- # @return [Workbook] a representation of a workbook
87
- def self.new(file_or_workbook, opts = { }, &block)
88
- options = process_options(opts)
89
- if file_or_workbook.is_a? WIN32OLE
87
+ # @return [Workbook] a representation of a workbook
88
+ def self.new(file_or_workbook, opts = { })
89
+ process_options(opts)
90
+ case file_or_workbook
91
+ when NilClass
92
+ raise FileNameNotGiven, 'filename is nil'
93
+ when WIN32OLE
90
94
  file = file_or_workbook.Fullname.tr('\\','/')
91
- else
95
+ when Workbook
96
+ file = file_or_workbook.Fullname.tr('\\','/')
97
+ when String
92
98
  file = file_or_workbook
93
- raise(FileNameNotGiven, 'filename is nil') if file.nil?
94
- raise(FileNotFound, "file #{General.absolute_path(file).inspect} is a directory") if File.directory?(file)
99
+ raise FileNotFound, "file #{General.absolute_path(file).inspect} is a directory" if File.directory?(file)
100
+ else
101
+ raise TypeREOError, 'given object is neither a filename, a Win32ole, nor a Workbook object'
95
102
  end
96
103
  # try to fetch the workbook from the bookstore
104
+ set_was_open opts, file_or_workbook.is_a?(WIN32OLE)
97
105
  book = nil
98
- if options[:force][:excel] != :new
106
+ if opts[:force][:excel] != :new
99
107
  # if readonly is true, then prefer a book that is given in force_excel if this option is set
100
- forced_excel =
101
- (options[:force][:excel].nil? || options[:force][:excel] == :current) ?
102
- (excel_class.new(:reuse => true) if !::JRUBY_BUG_CONNECT) : excel_of(options[:force][:excel])
108
+ forced_excel = begin
109
+ (opts[:force][:excel].nil? || opts[:force][:excel] == :current) ?
110
+ (excel_class.new(:reuse => true) if !::CONNECT_JRUBY_BUG) : opts[:force][:excel].to_reo.excel
111
+ rescue NoMethodError
112
+ raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
113
+ end
103
114
  begin
104
115
  book = if File.exists?(file)
105
- bookstore.fetch(file, :prefer_writable => !(options[:read_only]),
106
- :prefer_excel => (options[:read_only] ? forced_excel : nil))
116
+ bookstore.fetch(file, :prefer_writable => !(opts[:read_only]),
117
+ :prefer_excel => (opts[:read_only] ? forced_excel : nil))
107
118
  end
108
119
  rescue
109
- trace "#{$!.message}"
120
+ raise
121
+ #trace "#{$!.message}"
110
122
  end
111
123
  if book
112
- # hack (unless condition): calling Worksheet[]= causes calling Worksheet#workbook which calls Workbook#new(ole_workbook)
113
- book.was_open = book.alive? unless file_or_workbook.is_a? WIN32OLE
124
+ set_was_open opts, book.alive?
114
125
  # drop the fetched workbook if it shall be opened in another Excel instance
115
126
  # or the workbook is an unsaved workbook that should not be accepted
116
- if (options[:force][:excel].nil? || options[:force][:excel] == :current || forced_excel == book.excel) &&
117
- !(book.alive? && !book.saved && (options[:if_unsaved] != :accept))
118
- options[:force][:excel] = book.excel if book.excel && book.excel.alive?
119
- book.ensure_workbook(file,options)
120
- book.set_options(file,options)
127
+ if (opts[:force][:excel].nil? || opts[:force][:excel] == :current || forced_excel == book.excel) &&
128
+ !(book.alive? && !book.saved && (opts[:if_unsaved] != :accept))
129
+ opts[:force][:excel] = book.excel if book.excel && book.excel.alive?
130
+ book.ensure_workbook(file,opts)
131
+ book.send :apply_options, file, opts
121
132
  return book
122
133
  end
123
134
  end
124
135
  end
125
- super(file_or_workbook, options, &block)
136
+ super(file_or_workbook, opts)
126
137
  end
127
138
 
128
- def self.open(file_or_workbook, opts = { }, &block)
129
- new(file_or_workbook, opts, &block)
130
- end
139
+ singleton_class.send :alias_method, :open, :new
131
140
 
132
141
  # creates a new Workbook object, if a file name is given
133
142
  # Promotes the win32ole workbook to a Workbook object, if a win32ole-workbook is given
@@ -135,25 +144,23 @@ module RobustExcelOle
135
144
  # @param [Hash] opts
136
145
  # @option opts [Symbol] see above
137
146
  # @return [Workbook] a workbook
138
- def initialize(file_or_workbook, options = { }, &block)
147
+ def initialize(file_or_workbook, opts)
139
148
  if file_or_workbook.is_a? WIN32OLE
140
149
  @ole_workbook = file_or_workbook
141
- ole_excel = begin
142
- WIN32OLE.connect(@ole_workbook.Fullname).Application
143
- rescue
150
+ ole_excel = begin
151
+ @ole_workbook.Application
152
+ rescue WIN32OLERuntimeError
144
153
  raise ExcelREOError, 'could not determine the Excel instance'
145
154
  end
146
155
  @excel = excel_class.new(ole_excel)
147
- filename = file_or_workbook.Fullname.tr('\\','/')
156
+ filename = @ole_workbook.Fullname.tr('\\','/')
148
157
  else
149
158
  filename = file_or_workbook
150
- ensure_workbook(filename, options)
159
+ ensure_workbook(filename, opts)
151
160
  end
152
- set_options(filename, options)
153
- bookstore.store(self)
154
- r1c1_letters = @ole_workbook.Worksheets.Item(1).Cells.Item(1,1).Address(true,true,XlR1C1).gsub(/[0-9]/,'') #('ReferenceStyle' => XlR1C1).gsub(/[0-9]/,'')
155
- address_class.new(r1c1_letters)
156
- if block
161
+ apply_options(filename, opts)
162
+ store_myself
163
+ if block_given?
157
164
  begin
158
165
  yield self
159
166
  ensure
@@ -164,52 +171,46 @@ module RobustExcelOle
164
171
 
165
172
  private
166
173
 
167
- # translates abbreviations and synonyms and merges with default options
168
- def self.process_options(options, proc_opts = {:use_defaults => true})
169
- translator = proc do |opts|
170
- erg = {}
171
- opts.each do |key,value|
172
- new_key = key
173
- ABBREVIATIONS.each { |long,short| new_key = long if key == short }
174
- if value.is_a?(Hash)
175
- erg[new_key] = {}
176
- value.each do |k,v|
177
- new_k = k
178
- ABBREVIATIONS.each { |l,s| new_k = l if k == s }
179
- erg[new_key][new_k] = v
180
- end
181
- else
182
- erg[new_key] = value
183
- end
184
- end
185
- erg[:default] ||= {}
186
- erg[:force] ||= {}
187
- force_list = [:visible, :excel]
188
- erg.each { |key,value| erg[:force][key] = value if force_list.include?(key) }
189
- erg[:default][:excel] = erg[:default_excel] unless erg[:default_excel].nil?
190
- erg[:force][:excel] = erg[:force_excel] unless erg[:force_excel].nil?
191
- erg[:default][:excel] = :current if erg[:default][:excel] == :reuse || erg[:default][:excel] == :active
192
- erg[:force][:excel] = :current if erg[:force][:excel] == :reuse || erg[:force][:excel] == :active
193
- erg
194
- end
195
- opts = translator.call(options)
196
- default_open_opts = proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS : CORE_DEFAULT_OPEN_OPTS
197
- default_opts = translator.call(default_open_opts)
198
- opts = default_opts.merge(opts)
199
- opts[:default] = default_opts[:default].merge(opts[:default]) unless opts[:default].nil?
200
- opts[:force] = default_opts[:force].merge(opts[:force]) unless opts[:force].nil?
201
- opts
174
+ def self.set_was_open(hash, value)
175
+ hash[:was_open] = value if hash.has_key?(:was_open)
202
176
  end
203
177
 
204
- # returns an Excel object when given Excel, Workbook or Win32ole object representing a Workbook or an Excel
205
- # @private
206
- def self.excel_of(object)
207
- begin
208
- object = object.to_reo if object.is_a? WIN32OLE
209
- object.excel
210
- rescue
211
- raise TypeREOError, 'given object is neither an Excel, a Workbook, nor a Win32ole'
178
+ def set_was_open(hash, value)
179
+ self.class.set_was_open(hash, value)
180
+ end
181
+
182
+ def self.process_options(opts, proc_opts = {:use_defaults => true})
183
+ translate(opts)
184
+ default_opts = (proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS : CORE_DEFAULT_OPEN_OPTS).dup
185
+ translate(default_opts)
186
+ opts.merge!(default_opts) { |key, v1, v2| !v2.is_a?(Hash) ? v1 : v2.merge(v1 || {}) }
187
+ end
188
+
189
+ def self.translate(opts)
190
+ erg = {}
191
+ opts.each do |key,value|
192
+ new_key = key
193
+ ABBREVIATIONS.each { |long,short| new_key = long if key == short }
194
+ if value.is_a?(Hash)
195
+ erg[new_key] = {}
196
+ value.each do |k,v|
197
+ new_k = k
198
+ ABBREVIATIONS.each { |l,s| new_k = l if k == s }
199
+ erg[new_key][new_k] = v
200
+ end
201
+ else
202
+ erg[new_key] = value
203
+ end
212
204
  end
205
+ opts.merge!(erg)
206
+ opts[:default] ||= {}
207
+ opts[:force] ||= {}
208
+ force_list = [:visible, :excel]
209
+ opts.each { |key,value| opts[:force][key] = value if force_list.include?(key) }
210
+ opts[:default][:excel] = opts[:default_excel] unless opts[:default_excel].nil?
211
+ opts[:force][:excel] = opts[:force_excel] unless opts[:force_excel].nil?
212
+ opts[:default][:excel] = :current if opts[:default][:excel] == :reuse || opts[:default][:excel] == :active
213
+ opts[:force][:excel] = :current if opts[:force][:excel] == :reuse || opts[:force][:excel] == :active
213
214
  end
214
215
 
215
216
  public
@@ -218,20 +219,25 @@ module RobustExcelOle
218
219
  # ensures an excel but not for jruby if current Excel shall be used
219
220
  def ensure_excel(options)
220
221
  return if @excel && @excel.alive?
221
- excel_option = options[:force][:excel].nil? ? options[:default][:excel] : options[:force][:excel]
222
+ excel_option = options[:force][:excel] || options[:default][:excel] || :current
222
223
  @excel = if excel_option == :new
223
224
  excel_class.new(:reuse => false)
224
- elsif excel_option.nil? || excel_option == :current
225
+ elsif excel_option == :current
225
226
  excel_class.new(:reuse => true)
227
+ elsif excel_option.respond_to?(:to_reo)
228
+ excel_option.to_reo.excel
226
229
  else
227
- self.class.excel_of(excel_option)
230
+ raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
228
231
  end
229
- raise ExcelREOError, "excel is not alive" unless @excel && @excel.alive?
232
+ raise ExcelREOError, "Excel is not alive" unless @excel && @excel.alive?
230
233
  end
231
234
 
235
+
232
236
  # @private
233
237
  def ensure_workbook(filename, options)
238
+ set_was_open options, true
234
239
  return if (@ole_workbook && alive? && (options[:read_only].nil? || @ole_workbook.ReadOnly == options[:read_only]))
240
+ set_was_open options, false
235
241
  if options[:if_unsaved]==:accept &&
236
242
  ((options[:read_only]==true && self.ReadOnly==false) || (options[:read_only]==false && self.ReadOnly==true))
237
243
  raise OptionInvalid, ":if_unsaved:accept and change of read-only mode is not possible"
@@ -242,27 +248,28 @@ module RobustExcelOle
242
248
  ensure_excel(options)
243
249
  workbooks = @excel.Workbooks
244
250
  @ole_workbook = workbooks.Item(File.basename(filename)) rescue nil if @ole_workbook.nil?
245
- if @ole_workbook
246
- @was_open = true if @was_open.nil? # necessary?
251
+ if @ole_workbook && alive?
252
+ set_was_open options, true
247
253
  manage_blocking_or_unsaved_workbook(filename,options)
248
254
  open_or_create_workbook(filename,options) if @ole_workbook.ReadOnly != options[:read_only]
249
255
  else
250
- if excel_option.nil? || excel_option == :current &&
251
- (!::JRUBY_BUG_CONNECT || filename[0] != '/')
252
- workbooks_number_before_connect = @excel.Workbooks.Count
256
+ if (excel_option.nil? || excel_option == :current) &&
257
+ !(::CONNECT_JRUBY_BUG && filename[0] == '/')
253
258
  connect(filename,options)
254
- @was_open = @excel.Workbooks.Count == workbooks_number_before_connect
255
259
  else
256
260
  open_or_create_workbook(filename,options)
257
261
  end
258
262
  end
259
263
  end
260
264
 
261
- # @private
262
- def set_options(filename, options)
263
- # changing read-only mode
265
+ private
266
+
267
+ # applies options to workbook named with filename
268
+ def apply_options(filename, options)
269
+ # changing read-only mode
270
+ #ensure_workbook(filename, options) if options[:read_only] && options[:read_only] != @ole_workbook.ReadOnly
264
271
  if (!options[:read_only].nil?) && options[:read_only] != @ole_workbook.ReadOnly
265
- ensure_workbook(filename, options)
272
+ ensure_workbook(filename, options)
266
273
  end
267
274
  retain_saved do
268
275
  self.visible = options[:force][:visible].nil? ? @excel.Visible : options[:force][:visible]
@@ -271,40 +278,32 @@ module RobustExcelOle
271
278
  end
272
279
  end
273
280
 
274
- private
275
-
276
- # @private
277
281
  # connects to an unknown workbook
278
- def connect(filename,options)
279
- excels_number = excel_class.excels_number
280
- workbooks_number = if excels_number>0
281
- excel_class.current.Workbooks.Count
282
- else 0
283
- end
284
- abs_filename = General.absolute_path(filename)
282
+ def connect(filename, options)
283
+ workbooks_number = excel_class.excels_number==0 ? 0 : excel_class.current.Workbooks.Count
285
284
  @ole_workbook = begin
286
- WIN32OLE.connect(abs_filename)
285
+ WIN32OLE.connect(General.absolute_path(filename))
287
286
  rescue
288
287
  if $!.message =~ /moniker/
289
- raise WorkbookConnectingBlockingError
290
- else
291
- raise WorkbookConnectingUnknownError
288
+ raise WorkbookConnectingBlockingError, "some workbook is blocking when connecting"
289
+ else
290
+ raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
292
291
  end
293
292
  end
294
293
  ole_excel = begin
295
294
  @ole_workbook.Application
296
295
  rescue
297
296
  if $!.message =~ /dispid/
298
- raise WorkbookConnectingUnsavedError
299
- else
300
- raise WorkbookConnectingUnknownError
297
+ raise WorkbookConnectingUnsavedError, "workbook is unsaved when connecting"
298
+ else
299
+ raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
301
300
  end
302
301
  end
302
+ set_was_open options, (ole_excel.Workbooks.Count == workbooks_number)
303
303
  @excel = excel_class.new(ole_excel)
304
304
  end
305
305
 
306
- # @private
307
- def manage_nonexisting_file(filename,options)
306
+ def manage_nonexisting_file(filename, options)
308
307
  return if File.exist?(filename)
309
308
  abs_filename = General.absolute_path(filename)
310
309
  if options[:if_absent] == :create
@@ -322,11 +321,12 @@ module RobustExcelOle
322
321
  end
323
322
  end
324
323
 
325
- # @private
326
- def manage_blocking_or_unsaved_workbook(filename,options)
327
- obstructed_by_other_book = if (File.basename(filename) == File.basename(@ole_workbook.Fullname))
328
- General.absolute_path(filename) != @ole_workbook.Fullname
329
- end
324
+ def manage_blocking_or_unsaved_workbook(filename, options)
325
+ filename = General.absolute_path(filename)
326
+ filename = General.canonize(filename)
327
+ previous_file = General.canonize(@ole_workbook.Fullname)
328
+ obstructed_by_other_book = (File.basename(filename) == File.basename(previous_file)) &&
329
+ (File.dirname(filename) != File.dirname(previous_file))
330
330
  if obstructed_by_other_book
331
331
  # workbook is being obstructed by a workbook with same name and different path
332
332
  manage_blocking_workbook(filename,options)
@@ -338,8 +338,7 @@ module RobustExcelOle
338
338
  end
339
339
  end
340
340
 
341
- # @private
342
- def manage_blocking_workbook(filename,options)
341
+ def manage_blocking_workbook(filename, options)
343
342
  case options[:if_obstructed]
344
343
  when :raise
345
344
  raise WorkbookBlocked, "can't open workbook #{filename},
@@ -353,7 +352,8 @@ module RobustExcelOle
353
352
  manage_saving_workbook(filename, options)
354
353
  when :close_if_saved
355
354
  if !@ole_workbook.Saved
356
- raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}"
355
+ raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}" +
356
+ "\nHint: Use the option :if_blocked => :save to save the workbook"
357
357
  else
358
358
  manage_forgetting_workbook(filename, options)
359
359
  end
@@ -365,15 +365,14 @@ module RobustExcelOle
365
365
  end
366
366
  end
367
367
 
368
- # @private
369
- def manage_unsaved_workbook(filename,options)
368
+ def manage_unsaved_workbook(filename, options)
370
369
  case options[:if_unsaved]
371
370
  when :raise
372
371
  raise WorkbookNotSaved, "workbook is already open but not saved: #{File.basename(filename).inspect}" +
373
372
  "\nHint: Save the workbook or open the workbook using option :if_unsaved with values :forget and :accept to
374
373
  close the unsaved workbook and reopen it, or to let the unsaved workbook open, respectively"
375
374
  when :forget
376
- manage_forgetting_workbook(filename,options)
375
+ manage_forgetting_workbook(filename, options)
377
376
  when :accept
378
377
  # do nothing
379
378
  when :save
@@ -388,34 +387,29 @@ module RobustExcelOle
388
387
  end
389
388
  end
390
389
 
391
- # @private
392
390
  def manage_forgetting_workbook(filename, options)
393
391
  @excel.with_displayalerts(false) { @ole_workbook.Close }
394
392
  @ole_workbook = nil
395
393
  open_or_create_workbook(filename, options)
396
394
  end
397
395
 
398
- # @private
399
396
  def manage_saving_workbook(filename, options)
400
397
  save unless @ole_workbook.Saved
401
398
  manage_forgetting_workbook(filename, options)
402
399
  end
403
400
 
404
- # @private
405
401
  def manage_new_excel(filename, options)
406
402
  @excel = excel_class.new(:reuse => false)
407
403
  @ole_workbook = nil
408
404
  open_or_create_workbook(filename, options)
409
405
  end
410
406
 
411
- # @private
412
407
  def open_or_create_workbook(filename, options)
413
408
  return if @ole_workbook && options[:if_unsaved] != :alert && options[:if_unsaved] != :excel &&
414
409
  (options[:read_only].nil? || options[:read_only]==@ole_workbook.ReadOnly )
415
410
  begin
416
411
  abs_filename = General.absolute_path(filename)
417
412
  begin
418
- @was_open = false if @was_open.nil?
419
413
  workbooks = @excel.Workbooks
420
414
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
421
415
  raise UnexpectedREOError, "cannot access workbooks: #{msg.message} #{msg.backtrace}"
@@ -427,7 +421,7 @@ module RobustExcelOle
427
421
  updatelinks_vba(options[:update_links]),
428
422
  options[:read_only] )
429
423
  end
430
- rescue WIN32OLERuntimeError => msg
424
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
431
425
  # for Excel2007: for option :if_unsaved => :alert and user cancels: this error appears?
432
426
  # if yes: distinguish these events
433
427
  raise UnexpectedREOError, "cannot open workbook: #{msg.message} #{msg.backtrace}"
@@ -436,29 +430,27 @@ module RobustExcelOle
436
430
  # workaround for bug in Excel 2010: workbook.Open does not always return the workbook when given file name
437
431
  begin
438
432
  @ole_workbook = workbooks.Item(File.basename(filename))
439
- rescue WIN32OLERuntimeError => msg
433
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
440
434
  raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message}"
441
435
  end
442
- rescue WIN32OLERuntimeError => msg
436
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
443
437
  raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message} #{msg.backtrace}"
444
438
  end
445
439
  end
446
440
  end
447
441
 
448
- # @private
449
442
  # translating the option UpdateLinks from REO to VBA
450
443
  # setting UpdateLinks works only if calculation mode is automatic,
451
444
  # parameter 'UpdateLinks' has no effect
452
445
  def updatelinks_vba(updatelinks_reo)
453
446
  case updatelinks_reo
454
- when :alert then RobustExcelOle::XlUpdateLinksUserSetting
455
- when :never then RobustExcelOle::XlUpdateLinksNever
447
+ when :alert then RobustExcelOle::XlUpdateLinksUserSetting
448
+ when :never then RobustExcelOle::XlUpdateLinksNever
456
449
  when :always then RobustExcelOle::XlUpdateLinksAlways
457
- else RobustExcelOle::XlUpdateLinksNever
450
+ else RobustExcelOle::XlUpdateLinksNever
458
451
  end
459
452
  end
460
453
 
461
- # @private
462
454
  # workaround for linked workbooks for Excel 2007:
463
455
  # opening and closing a dummy workbook if Excel has no workbooks.
464
456
  # delay: with visible: 0.2 sec, without visible almost none
@@ -522,13 +514,10 @@ module RobustExcelOle
522
514
  else
523
515
  close_workbook
524
516
  end
525
- # trace "close: canceled by user" if alive? &&
526
- # (opts[:if_unsaved] == :alert || opts[:if_unsaved] == :excel) && (not @ole_workbook.Saved)
527
517
  end
528
518
 
529
519
  private
530
520
 
531
- # @private
532
521
  def close_workbook
533
522
  @ole_workbook.Close if alive?
534
523
  @ole_workbook = nil unless alive?
@@ -581,9 +570,10 @@ module RobustExcelOle
581
570
  self.class.unobtrusively_opening(file, opts, alive?, &block)
582
571
  end
583
572
 
584
- @private
573
+ private
574
+
585
575
  def self.unobtrusively_opening(file, opts, book_is_alive, &block)
586
- opts = process_options(opts)
576
+ process_options(opts)
587
577
  opts = {:if_closed => :current, :keep_open => false}.merge(opts)
588
578
  raise OptionInvalid, 'contradicting options' if opts[:writable] && opts[:read_only]
589
579
  if book_is_alive.nil?
@@ -598,33 +588,37 @@ module RobustExcelOle
598
588
  end
599
589
  open_opts = excel_opts.merge({:if_unsaved => :accept})
600
590
  begin
591
+ open_opts[:was_open] = nil
601
592
  book = open(file, open_opts)
602
593
  was_visible = book.visible
603
594
  was_writable = book.writable
604
595
  was_saved = book.saved
605
596
  was_check_compatibility = book.check_compatibility
606
597
  was_calculation = book.excel.properties[:calculation]
607
- book.set_options(file,opts)
598
+ book.send :apply_options, file, opts
608
599
  yield book
609
600
  ensure
610
601
  if book && book.alive?
611
602
  do_not_write = opts[:read_only] || opts[:writable]==false
612
603
  book.save unless book.saved || do_not_write || !book.writable
613
604
  if (opts[:read_only] && was_writable) || (!opts[:read_only] && !was_writable)
614
- book.set_options(file, opts.merge({:read_only => !was_writable,
615
- :if_unsaved => (opts[:writable]==false ? :forget : :save)}))
605
+ book.send :apply_options, file, opts.merge({:read_only => !was_writable,
606
+ :if_unsaved => (opts[:writable]==false ? :forget : :save)})
616
607
  end
617
- if book.was_open
608
+ was_open = open_opts[:was_open]
609
+ if was_open
618
610
  book.visible = was_visible
619
611
  book.CheckCompatibility = was_check_compatibility
620
612
  book.excel.calculation = was_calculation
621
613
  end
622
- book.Saved = (was_saved || !book.was_open)
623
- book.close unless book.was_open || opts[:keep_open]
614
+ book.Saved = (was_saved || !was_open)
615
+ book.close unless was_open || opts[:keep_open]
624
616
  end
625
617
  end
626
618
  end
627
619
 
620
+ public
621
+
628
622
  # reopens a closed workbook
629
623
  # @options options
630
624
  def reopen(options = { })
@@ -638,10 +632,6 @@ module RobustExcelOle
638
632
  def save(opts = { }) # option opts is deprecated #
639
633
  raise ObjectNotAlive, 'workbook is not alive' unless alive?
640
634
  raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
641
- # if you have open the workbook with :read_only => true,
642
- # then you could close the workbook and open it again with option :read_only => false
643
- # otherwise the workbook may already be open writable in an another Excel instance
644
- # then you could use this workbook or close the workbook there
645
635
  begin
646
636
  @ole_workbook.Save
647
637
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
@@ -671,12 +661,12 @@ module RobustExcelOle
671
661
  # :close_if_saved -> closes the blocking workbook, if it is saved,
672
662
  # otherwise raises an exception
673
663
  # @return [Workbook], the book itself, if successfully saved, raises an exception otherwise
674
- def save_as(file, opts = { })
664
+ def save_as(file, options = { })
675
665
  raise FileNameNotGiven, 'filename is nil' if file.nil?
676
666
  raise ObjectNotAlive, 'workbook is not alive' unless alive?
677
667
  raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
678
668
  raise(FileNotFound, "file #{General.absolute_path(file).inspect} is a directory") if File.directory?(file)
679
- options = self.class.process_options(opts)
669
+ self.class.process_options(options)
680
670
  if File.exist?(file)
681
671
  case options[:if_exists]
682
672
  when :overwrite
@@ -731,7 +721,6 @@ module RobustExcelOle
731
721
 
732
722
  private
733
723
 
734
- # @private
735
724
  def save_as_workbook(file, options)
736
725
  dirname, basename = File.split(file)
737
726
  file_format =
@@ -741,7 +730,7 @@ module RobustExcelOle
741
730
  when '.xlsm' then RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
742
731
  end
743
732
  @ole_workbook.SaveAs(General.absolute_path(file), file_format)
744
- bookstore.store(self)
733
+ store_myself
745
734
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
746
735
  if msg.message =~ /SaveAs/ && msg.message =~ /Workbook/
747
736
  # trace "save: canceled by user" if options[:if_exists] == :alert || options[:if_exists] == :excel
@@ -751,6 +740,11 @@ module RobustExcelOle
751
740
  end
752
741
  end
753
742
 
743
+ def store_myself
744
+ bookstore.store(self)
745
+ @stored_filename = filename
746
+ end
747
+
754
748
  public
755
749
 
756
750
  # closes a given file if it is open
@@ -789,12 +783,22 @@ module RobustExcelOle
789
783
  raise NameNotFound, "could not return a sheet with name #{name.inspect}"
790
784
  end
791
785
 
786
+ def worksheets_count
787
+ @ole_workbook.Worksheets.Count
788
+ end
789
+
792
790
  def each
793
791
  @ole_workbook.Worksheets.each do |sheet|
794
792
  yield worksheet_class.new(sheet)
795
793
  end
796
794
  end
797
795
 
796
+ def worksheets
797
+ result = []
798
+ each { |worksheet| result << worksheet }
799
+ result
800
+ end
801
+
798
802
  def each_with_index(offset = 0)
799
803
  i = offset
800
804
  @ole_workbook.Worksheets.each do |sheet|
@@ -819,36 +823,18 @@ module RobustExcelOle
819
823
  new_sheet_name = opts.delete(:as)
820
824
  last_sheet_local = last_sheet
821
825
  after_or_before, base_sheet = opts.to_a.first || [:after, last_sheet_local]
826
+ base_sheet_ole = base_sheet.ole_worksheet
822
827
  begin
823
- if !::JRUBY_BUG_COPYSHEETS
824
- if sheet
825
- sheet.Copy({ after_or_before.to_s => base_sheet.ole_worksheet })
826
- else
827
- @ole_workbook.Worksheets.Add({ after_or_before.to_s => base_sheet.ole_worksheet })
828
- #@ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
829
- end
828
+ if !::COPYSHEETS_JRUBY_BUG
829
+ add_or_copy_sheet_simple(sheet, { after_or_before.to_s => base_sheet_ole })
830
830
  else
831
831
  if after_or_before == :before
832
- if sheet
833
- sheet.Copy(base_sheet.ole_worksheet)
834
- else
835
- ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
836
- end
832
+ add_or_copy_sheet_simple(sheet, base_sheet_ole)
837
833
  else
838
- #not_given = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_NULL)
839
- #ole_workbook.Worksheets.Add(not_given,base_sheet.ole_worksheet)
840
834
  if base_sheet.name != last_sheet_local.name
841
- if sheet
842
- sheet.Copy(base_sheet.Next)
843
- else
844
- ole_workbook.Worksheets.Add(base_sheet.Next)
845
- end
835
+ add_or_copy_sheet_simple(sheet, base_sheet.Next)
846
836
  else
847
- if sheet
848
- sheet.Copy(base_sheet.ole_worksheet)
849
- else
850
- ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
851
- end
837
+ add_or_copy_sheet_simple(sheet, base_sheet_ole)
852
838
  base_sheet.Move(ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count-1))
853
839
  ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
854
840
  end
@@ -857,14 +843,23 @@ module RobustExcelOle
857
843
  rescue WIN32OLERuntimeError, NameNotFound, Java::OrgRacobCom::ComFailException
858
844
  raise WorksheetREOError, "could not add given worksheet #{sheet.inspect}"
859
845
  end
860
- #ole_sheet = @excel.Activesheet
861
- ole_sheet = ole_workbook.Activesheet
862
- #ole_sheet = ole_sheet.nil? ? ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count) : ole_sheet
863
- new_sheet = worksheet_class.new(ole_sheet)
846
+ new_sheet = worksheet_class.new(ole_workbook.Activesheet)
864
847
  new_sheet.name = new_sheet_name if new_sheet_name
865
848
  new_sheet
866
849
  end
867
850
 
851
+ private
852
+
853
+ def add_or_copy_sheet_simple(sheet, base_sheet_ole_or_hash)
854
+ if sheet
855
+ sheet.Copy(base_sheet_ole_or_hash)
856
+ else
857
+ ole_workbook.Worksheets.Add(base_sheet_ole_or_hash)
858
+ end
859
+ end
860
+
861
+ public
862
+
868
863
  # for compatibility to older versions
869
864
  def add_sheet(sheet = nil, opts = { })
870
865
  add_or_copy_sheet(sheet, opts)
@@ -894,30 +889,15 @@ module RobustExcelOle
894
889
  # @param [String] name the name of the range
895
890
  # @param [Variant] value the contents of the range
896
891
  def []= (name, value)
897
- old_color_if_modified = @color_if_modified
898
- workbook.color_if_modified = 42 # 42 - aqua-marin, 4-green
899
- set_namevalue_glob(name,value)
900
- workbook.color_if_modified = old_color_if_modified
892
+ set_namevalue_glob(name, value, :color => 42)
901
893
  end
902
894
 
903
895
  # sets options
904
896
  # @param [Hash] opts
905
897
  def for_this_workbook(opts)
906
898
  return unless alive?
907
- opts = self.class.process_options(opts, :use_defaults => false)
908
- visible_before = visible
909
- check_compatibility_before = check_compatibility
910
- unless opts[:read_only].nil?
911
- # if the ReadOnly status shall be changed, then close and reopen it
912
- if (!writable && !(opts[:read_only])) || (writable && opts[:read_only])
913
- opts[:check_compatibility] = check_compatibility if opts[:check_compatibility].nil?
914
- close(:if_unsaved => true)
915
- open_or_create_workbook(@stored_filename, opts)
916
- end
917
- end
918
- self.visible = opts[:force][:visible].nil? ? visible_before : opts[:force][:visible]
919
- self.CheckCompatibility = opts[:check_compatibility].nil? ? check_compatibility_before : opts[:check_compatibility]
920
- @excel.calculation = opts[:calculation] unless opts[:calculation].nil?
899
+ self.class.process_options(opts, :use_defaults => false)
900
+ self.send :apply_options, @stored_filename, opts
921
901
  end
922
902
 
923
903
  # brings workbook to foreground, makes it available for heyboard inputs, makes the Excel instance visible
@@ -933,7 +913,6 @@ module RobustExcelOle
933
913
  true
934
914
  rescue
935
915
  @ole_workbook = nil # dead object won't be alive again
936
- # t $!.message
937
916
  false
938
917
  end
939
918
 
@@ -995,6 +974,7 @@ module RobustExcelOle
995
974
  self.filename == other_book.filename
996
975
  end
997
976
 
977
+ # @private
998
978
  def self.books
999
979
  bookstore.books
1000
980
  end
@@ -1045,16 +1025,6 @@ module RobustExcelOle
1045
1025
  end
1046
1026
  end
1047
1027
 
1048
- # @private
1049
- def self.address_class
1050
- @address_class ||= begin
1051
- module_name = self.parent_name
1052
- "#{module_name}::Address".constantize
1053
- rescue NameError => e
1054
- Address
1055
- end
1056
- end
1057
-
1058
1028
  # @private
1059
1029
  def excel_class
1060
1030
  self.class.excel_class
@@ -1065,11 +1035,6 @@ module RobustExcelOle
1065
1035
  self.class.worksheet_class
1066
1036
  end
1067
1037
 
1068
- # @private
1069
- def address_class
1070
- self.class.address_class
1071
- end
1072
-
1073
1038
  include MethodHelpers
1074
1039
 
1075
1040
  private
@@ -1077,7 +1042,7 @@ module RobustExcelOle
1077
1042
  def method_missing(name, *args)
1078
1043
  if name.to_s[0,1] =~ /[A-Z]/
1079
1044
  raise ObjectNotAlive, 'method missing: workbook not alive' unless alive?
1080
- if ::JRUBY_BUG_ERRORMESSAGE
1045
+ if ::ERRORMESSAGE_JRUBY_BUG
1081
1046
  begin
1082
1047
  @ole_workbook.send(name, *args)
1083
1048
  rescue Java::OrgRacobCom::ComFailException
@@ -1099,6 +1064,47 @@ module RobustExcelOle
1099
1064
 
1100
1065
  public
1101
1066
 
1067
+ # @private
1068
+ class WorkbookBlocked < WorkbookREOError
1069
+ end
1070
+
1071
+ # @private
1072
+ class WorkbookNotSaved < WorkbookREOError
1073
+ end
1074
+
1075
+ # @private
1076
+ class WorkbookReadOnly < WorkbookREOError
1077
+ end
1078
+
1079
+ # @private
1080
+ class WorkbookBeingUsed < WorkbookREOError
1081
+ end
1082
+
1083
+ # @private
1084
+ class WorkbookConnectingUnsavedError < WorkbookREOError
1085
+ end
1086
+
1087
+ # @private
1088
+ class WorkbookConnectingBlockingError < WorkbookREOError
1089
+ end
1090
+
1091
+ # @private
1092
+ class WorkbookConnectingUnknownError < WorkbookREOError
1093
+ end
1094
+
1095
+ # @private
1096
+ class FileAlreadyExists < FileREOError
1097
+ end
1098
+
1099
+ # @private
1100
+ class FileNameNotGiven < FileREOError
1101
+ end
1102
+
1103
+ # @private
1104
+ class FileNotFound < FileREOError
1105
+ end
1106
+
1107
+
1102
1108
  Book = Workbook
1103
1109
 
1104
1110
  end