robust_excel_ole 1.31 → 1.32
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.
- checksums.yaml +4 -4
- data/Changelog +20 -1
- data/README.rdoc +118 -18
- data/___dummy_workbook.xls +0 -0
- data/benchmarking/creek_example.rb +1 -1
- data/benchmarking/roo_example.rb +1 -1
- data/benchmarking/simple_xlsx_reader_example.rb +1 -1
- data/benchmarking/spreadsheet_example.rb +1 -1
- data/docs/README_excel.rdoc +16 -24
- data/docs/README_listobjects.rdoc +176 -0
- data/docs/README_open.rdoc +12 -12
- data/docs/README_ranges.rdoc +72 -55
- data/docs/README_save_close.rdoc +3 -3
- data/docs/README_sheet.rdoc +18 -13
- data/examples/example_ruby_library.rb +2 -2
- data/examples/introductory_examples/example_range.rb +2 -2
- data/examples/modifying_sheets/example_access_sheets_and_cells.rb +6 -6
- data/examples/modifying_sheets/example_add_names.rb +1 -1
- data/examples/modifying_sheets/example_concating.rb +1 -1
- data/examples/modifying_sheets/example_copying.rb +2 -2
- data/examples/modifying_sheets/example_listobjects.rb +86 -0
- data/examples/modifying_sheets/example_naming.rb +1 -1
- data/examples/modifying_sheets/example_ranges.rb +1 -1
- data/examples/open_save_close/example_control_to_excel.rb +1 -1
- data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +1 -1
- data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
- data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
- data/examples/open_save_close/example_if_unsaved_forget.rb +3 -3
- data/examples/open_save_close/example_if_unsaved_forget_more.rb +4 -4
- data/examples/open_save_close/example_read_only.rb +1 -1
- data/examples/open_save_close/example_simple.rb +1 -1
- data/examples/open_save_close/example_unobtrusively.rb +3 -3
- data/lib/robust_excel_ole/address_tool.rb +54 -44
- data/lib/robust_excel_ole/base.rb +4 -6
- data/lib/robust_excel_ole/bookstore.rb +2 -16
- data/lib/robust_excel_ole/cell.rb +16 -21
- data/lib/robust_excel_ole/excel.rb +131 -186
- data/lib/robust_excel_ole/general.rb +82 -55
- data/lib/robust_excel_ole/list_object.rb +182 -109
- data/lib/robust_excel_ole/list_row.rb +65 -38
- data/lib/robust_excel_ole/range.rb +125 -93
- data/lib/robust_excel_ole/range_owners.rb +52 -66
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +168 -176
- data/lib/robust_excel_ole/worksheet.rb +177 -141
- data/robust_excel_ole.gemspec +4 -3
- data/spec/bookstore_spec.rb +2 -3
- data/spec/cell_spec.rb +9 -9
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +132 -85
- data/spec/general_spec.rb +47 -15
- data/spec/list_object_spec.rb +258 -145
- data/spec/list_row_spec.rb +218 -0
- data/spec/range_spec.rb +76 -29
- data/spec/spec_helper.rb +15 -1
- data/spec/workbook_spec.rb +75 -34
- data/spec/workbook_specs/workbook_all_spec.rb +2 -1
- data/spec/workbook_specs/workbook_misc_spec.rb +20 -13
- data/spec/workbook_specs/workbook_open_spec.rb +47 -45
- data/spec/workbook_specs/workbook_save_spec.rb +21 -22
- data/spec/workbook_specs/workbook_sheet_spec.rb +3 -3
- data/spec/workbook_specs/workbook_unobtr_spec.rb +303 -303
- data/spec/worksheet_spec.rb +522 -318
- metadata +37 -2
@@ -11,6 +11,8 @@ module RobustExcelOle
|
|
11
11
|
# worksheet: see https://github.com/Thomas008/robust_excel_ole/blob/master/lib/robust_excel_ole/worksheet.rb
|
12
12
|
class Worksheet < RangeOwners
|
13
13
|
|
14
|
+
include Enumerable
|
15
|
+
|
14
16
|
using ToReoRefinement
|
15
17
|
|
16
18
|
attr_reader :ole_worksheet
|
@@ -49,9 +51,9 @@ module RobustExcelOle
|
|
49
51
|
# sheet name
|
50
52
|
# @returns name of the sheet
|
51
53
|
def name
|
52
|
-
@ole_worksheet.Name
|
54
|
+
@ole_worksheet.Name.encode('utf-8')
|
53
55
|
rescue
|
54
|
-
raise WorksheetREOError, "name could not be determined"
|
56
|
+
raise WorksheetREOError, "name could not be determined\n#{$!.message}"
|
55
57
|
end
|
56
58
|
|
57
59
|
# sets sheet name
|
@@ -66,49 +68,69 @@ module RobustExcelOle
|
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
69
|
-
#
|
70
|
-
# @params
|
71
|
-
# @returns
|
72
|
-
def []
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
# value of a range given its defined name or address
|
72
|
+
# @params [Variant] defined name or address
|
73
|
+
# @returns [Variant] value (contents) of the range
|
74
|
+
def [](name_or_address, address2 = :__not_provided)
|
75
|
+
range(name_or_address, address2).value
|
76
|
+
end
|
77
|
+
|
78
|
+
# sets the value of a range given its defined name or address, and the value
|
79
|
+
# @params [Variant] defined name or address of the range
|
80
|
+
# @params [Variant] value (contents) of the range
|
81
|
+
# @returns [Variant] value (contents) of the range
|
82
|
+
def []=(name_or_address, value_or_address2, remaining_arg = :__not_provided)
|
83
|
+
if remaining_arg != :__not_provided
|
84
|
+
name_or_address, value = [name_or_address, value_or_address2], remaining_arg
|
82
85
|
else
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
value = value_or_address2
|
87
|
+
end
|
88
|
+
begin
|
89
|
+
range(name_or_address).value = value
|
90
|
+
rescue #WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
91
|
+
raise RangeNotEvaluatable, "cannot assign value to range with name or address #{name_or_address.inspect}\n#{$!.message}"
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
92
|
-
#
|
93
|
-
# @params
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
95
|
+
# a range given a defined name or address
|
96
|
+
# @params [Variant] defined name or address
|
97
|
+
# @return [Range] a range
|
98
|
+
def range(name_or_address, address2 = :__not_provided)
|
99
|
+
if name_or_address.respond_to?(:gsub) && address2 == :__not_provided
|
100
|
+
name = name_or_address
|
101
|
+
range = get_name_object(name).RefersToRange rescue nil
|
102
|
+
end
|
103
|
+
unless range
|
104
|
+
address = normalize_address(name_or_address, address2)
|
105
|
+
workbook.retain_saved do
|
103
106
|
begin
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
+
self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' + address_tool.as_r1c1(address))
|
108
|
+
range = get_name_object('__dummy001').RefersToRange
|
109
|
+
self.Names.Item('__dummy001').Delete
|
110
|
+
rescue
|
111
|
+
address2_string = (address2.nil? || address2 == :__not_provided) ? "" : ", #{address2.inspect}"
|
112
|
+
raise RangeNotCreated, "cannot find name or address #{name_or_address.inspect}#{address2_string})"
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
116
|
+
range.to_reo
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def normalize_address(address, address2)
|
122
|
+
address = [address,address2] unless address2 == :__not_provided
|
123
|
+
address = if address.is_a?(Integer) || address.is_a?(::Range)
|
124
|
+
[address, nil]
|
125
|
+
elsif address.is_a?(Array) && address.size == 1 && (address.first.is_a?(Integer) || address.first.is_a?(::Range))
|
126
|
+
[address.first, nil]
|
127
|
+
else
|
128
|
+
address
|
129
|
+
end
|
110
130
|
end
|
111
131
|
|
132
|
+
public
|
133
|
+
|
112
134
|
# returns the contents of a range with a locally defined name
|
113
135
|
# evaluates the formula if the contents is a formula
|
114
136
|
# if the name could not be found or the range or value could not be determined,
|
@@ -117,7 +139,7 @@ module RobustExcelOle
|
|
117
139
|
# @param [Hash] opts the options
|
118
140
|
# @option opts [Symbol] :default the default value that is provided if no contents could be returned
|
119
141
|
# @return [Variant] the contents of a range with given name
|
120
|
-
def namevalue(name, opts = { :
|
142
|
+
def namevalue(name, opts = { default: :__not_provided })
|
121
143
|
begin
|
122
144
|
ole_range = self.Range(name)
|
123
145
|
rescue # WIN32OLERuntimeError, VBAMethodMissingError, Java::OrgRacobCom::ComFailException
|
@@ -135,11 +157,11 @@ module RobustExcelOle
|
|
135
157
|
end
|
136
158
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
137
159
|
return opts[:default] unless opts[:default] == :__not_provided
|
138
|
-
raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}"
|
160
|
+
raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}\n#{$!.message}"
|
139
161
|
end
|
140
162
|
if value == -2146828288 + RobustExcelOle::XlErrName
|
141
163
|
return opts[:default] unless opts[:default] == __not_provided
|
142
|
-
raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
|
164
|
+
raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}\n#{$!.message}"
|
143
165
|
end
|
144
166
|
return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
|
145
167
|
value
|
@@ -164,25 +186,23 @@ module RobustExcelOle
|
|
164
186
|
row, col = address_tool.as_integer_ranges(address_r1c1)
|
165
187
|
row.each_with_index do |r,i|
|
166
188
|
col.each_with_index do |c,j|
|
167
|
-
ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:
|
189
|
+
ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:pop) ? value[i][j] : value)
|
168
190
|
end
|
169
191
|
end
|
170
192
|
end
|
171
193
|
value
|
172
194
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
173
|
-
raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
|
195
|
+
raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}\n#{$!.message}"
|
174
196
|
end
|
175
197
|
end
|
176
198
|
|
177
199
|
# value of a cell, if row and column are given
|
178
200
|
# @params row and column
|
179
201
|
# @returns value of the cell
|
180
|
-
def cellval(x,y)
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
raise RangeNotEvaluatable, "cannot read cell (#{x.inspect},#{y.inspect})"
|
185
|
-
end
|
202
|
+
def cellval(x,y) # :deprecated :#
|
203
|
+
@ole_worksheet.Cells.Item(x, y).Value
|
204
|
+
rescue
|
205
|
+
raise RangeNotEvaluatable, "cannot read cell (#{x.inspect},#{y.inspect})\n#{$!.message}"
|
186
206
|
end
|
187
207
|
|
188
208
|
# sets the value of a cell, if row, column and color of the cell are given
|
@@ -193,73 +213,93 @@ module RobustExcelOle
|
|
193
213
|
cell.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
|
194
214
|
cell.Value = value
|
195
215
|
rescue # WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
196
|
-
raise RangeNotEvaluatable, "cannot assign value #{value.inspect} to cell (#{y.inspect},#{x.inspect})"
|
216
|
+
raise RangeNotEvaluatable, "cannot assign value #{value.inspect} to cell (#{y.inspect},#{x.inspect})\n#{$!.message}"
|
197
217
|
end
|
198
218
|
|
199
|
-
#
|
219
|
+
# @return [Array] a 2-dimensional array that contains the values in each row of the used range
|
200
220
|
def values
|
201
221
|
@ole_worksheet.UsedRange.Value
|
202
222
|
end
|
203
223
|
|
204
|
-
#
|
224
|
+
# @return [Enumerator] traversing the rows values
|
205
225
|
def each
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def each_with_index(offset = 0)
|
214
|
-
i = offset
|
215
|
-
each_row do |row_range|
|
216
|
-
row_range.each do |cell|
|
217
|
-
yield cell, i
|
218
|
-
i += 1
|
226
|
+
if block_given?
|
227
|
+
@ole_worksheet.UsedRange.Rows.lazy.each do |ole_row|
|
228
|
+
row_value = ole_row.Value
|
229
|
+
yield (row_value.nil? ? [] : row_value.first)
|
219
230
|
end
|
231
|
+
else
|
232
|
+
to_enum(:each).lazy
|
220
233
|
end
|
221
234
|
end
|
222
235
|
|
223
|
-
#
|
236
|
+
# @return [Enumerator] traversing the rows
|
224
237
|
def each_row(offset = 0)
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
238
|
+
if block_given?
|
239
|
+
offset += 1
|
240
|
+
1.upto(@end_row) do |row|
|
241
|
+
next if row < offset
|
242
|
+
yield RobustExcelOle::Range.new(@ole_worksheet.Range(@ole_worksheet.Cells(row, 1), @ole_worksheet.Cells(row, @end_column)), self)
|
243
|
+
end
|
244
|
+
else
|
245
|
+
to_enum(:each_row).lazy
|
229
246
|
end
|
230
247
|
end
|
231
248
|
|
232
|
-
def each_row_with_index(offset = 0)
|
249
|
+
def each_row_with_index(offset = 0) # :nodoc: # # :deprecated :#
|
233
250
|
each_row(offset) do |row_range|
|
234
251
|
yield RobustExcelOle::Range.new(row_range, self), (row_range.Row - 1 - offset)
|
235
252
|
end
|
236
253
|
end
|
237
254
|
|
238
|
-
#
|
255
|
+
# @return [Enumerator] traversing the columns
|
239
256
|
def each_column(offset = 0)
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
257
|
+
if block_given?
|
258
|
+
offset += 1
|
259
|
+
1.upto(@end_column) do |column|
|
260
|
+
next if column < offset
|
261
|
+
yield RobustExcelOle::Range.new(@ole_worksheet.Range(@ole_worksheet.Cells(1, column), @ole_worksheet.Cells(@end_row, column)), self)
|
262
|
+
end
|
263
|
+
else
|
264
|
+
to_enum(:each_column).lazy
|
244
265
|
end
|
245
266
|
end
|
246
267
|
|
247
|
-
def each_column_with_index(offset = 0)
|
268
|
+
def each_column_with_index(offset = 0) # :nodoc: # # :deprecated :#
|
248
269
|
each_column(offset) do |column_range|
|
249
270
|
yield RobustExcelOle::Range.new(column_range, self), (column_range.Column - 1 - offset)
|
250
271
|
end
|
251
272
|
end
|
252
273
|
|
274
|
+
# @return [Enumerator] traversing the cells
|
275
|
+
def each_cell
|
276
|
+
if block_given?
|
277
|
+
each_row do |row_range|
|
278
|
+
row_range.lazy.each do |cell|
|
279
|
+
yield cell
|
280
|
+
end
|
281
|
+
end
|
282
|
+
else
|
283
|
+
to_enum(:each_cell).lazy
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def each_cell_with_index(offset = 0) # :nodoc: # # :deprecated :#
|
288
|
+
i = offset
|
289
|
+
each_row do |row_range|
|
290
|
+
row_range.each do |cell|
|
291
|
+
yield cell, i
|
292
|
+
i += 1
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
253
297
|
def each_rowvalue # :deprecated: #
|
254
298
|
values.each do |row_values|
|
255
299
|
yield row_values
|
256
300
|
end
|
257
301
|
end
|
258
302
|
|
259
|
-
def each_value # :deprecated: #
|
260
|
-
each_rowvalue
|
261
|
-
end
|
262
|
-
|
263
303
|
def each_rowvalue_with_index(offset = 0) # :deprecated: #
|
264
304
|
i = offset
|
265
305
|
values.each do |row_values|
|
@@ -268,6 +308,8 @@ module RobustExcelOle
|
|
268
308
|
end
|
269
309
|
end
|
270
310
|
|
311
|
+
alias each_value each_rowvalue # :deprecated: #
|
312
|
+
|
271
313
|
def row_range(row, integer_range = nil)
|
272
314
|
integer_range ||= 1..@end_column
|
273
315
|
RobustExcelOle::Range.new(@ole_worksheet.Range(@ole_worksheet.Cells(row, integer_range.min), @ole_worksheet.Cells(row, integer_range.max)), self)
|
@@ -280,44 +322,17 @@ module RobustExcelOle
|
|
280
322
|
|
281
323
|
def == other_worksheet
|
282
324
|
other_worksheet.is_a?(Worksheet) &&
|
283
|
-
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
# creates a range from a given defined name or address
|
288
|
-
# @params [Variant] defined name or address
|
289
|
-
# @return [Range] a range
|
290
|
-
def range(name_or_address, address2 = :__not_provided)
|
291
|
-
if name_or_address.respond_to?(:gsub) && address2 == :__not_provided
|
292
|
-
name = name_or_address
|
293
|
-
range = RobustExcelOle::Range.new(name_object(name).RefersToRange, self) rescue nil
|
294
|
-
end
|
295
|
-
unless range
|
296
|
-
address = name_or_address
|
297
|
-
address = [name_or_address,address2] unless address2 == :__not_provided
|
298
|
-
workbook.retain_saved do
|
299
|
-
begin
|
300
|
-
self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' + address_tool.as_r1c1(address))
|
301
|
-
range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange, self)
|
302
|
-
self.Names.Item('__dummy001').Delete
|
303
|
-
rescue
|
304
|
-
address2_string = address2.nil? ? "" : ", #{address2.inspect}"
|
305
|
-
raise RangeNotCreated, "cannot create range (#{name_or_address.inspect}#{address2_string})"
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
range
|
325
|
+
self.workbook == other_worksheet.workbook &&
|
326
|
+
self.Name == other_worksheet.Name
|
310
327
|
end
|
311
328
|
|
329
|
+
|
312
330
|
# @params [Variant] table (listobject) name or number
|
313
331
|
# @return [ListObject] a table (listobject)
|
314
332
|
def table(number_or_name)
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
raise WorksheetREOError, "table #{number_or_name} not found"
|
319
|
-
end
|
320
|
-
ListObject.new(ole_listobject)
|
333
|
+
listobject_class.new(@ole_worksheet.ListObjects.Item(number_or_name))
|
334
|
+
rescue
|
335
|
+
raise WorksheetREOError, "table #{number_or_name} not found"
|
321
336
|
end
|
322
337
|
|
323
338
|
# @private
|
@@ -330,6 +345,29 @@ module RobustExcelOle
|
|
330
345
|
false
|
331
346
|
end
|
332
347
|
|
348
|
+
# last_row, last_column:
|
349
|
+
# the last row and last column in a worksheet can be determined with help of
|
350
|
+
# UsedRange.SpecialCells and UsedRange.Rows/Columns
|
351
|
+
# both values can differ in certain cases:
|
352
|
+
# - if the worksheet contains a table, then UsedRange starts at the table, not in the first cell
|
353
|
+
# therefore we use SpecialCells.
|
354
|
+
# - if the worksheet contains merged cells, then SpecialCells considers the merged cells only,
|
355
|
+
# therefor we use UsedRange here.
|
356
|
+
|
357
|
+
# @private
|
358
|
+
def last_row
|
359
|
+
special_last_row = @ole_worksheet.UsedRange.SpecialCells(RobustExcelOle::XlLastCell).Row
|
360
|
+
used_last_row = @ole_worksheet.UsedRange.Rows.Count
|
361
|
+
[special_last_row, used_last_row].max
|
362
|
+
end
|
363
|
+
|
364
|
+
# @private
|
365
|
+
def last_column
|
366
|
+
special_last_column = @ole_worksheet.UsedRange.SpecialCells(RobustExcelOle::XlLastCell).Column
|
367
|
+
used_last_column = @ole_worksheet.UsedRange.Columns.Count
|
368
|
+
[special_last_column, used_last_column].max
|
369
|
+
end
|
370
|
+
|
333
371
|
using ParentRefinement
|
334
372
|
using StringRefinement
|
335
373
|
|
@@ -348,9 +386,24 @@ module RobustExcelOle
|
|
348
386
|
self.class.workbook_class
|
349
387
|
end
|
350
388
|
|
389
|
+
# @private
|
390
|
+
def self.listobject_class
|
391
|
+
@listobject_class ||= begin
|
392
|
+
module_name = self.parent_name
|
393
|
+
"#{module_name}::ListObject".constantize
|
394
|
+
rescue NameError => e
|
395
|
+
ListObject
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
# @private
|
400
|
+
def listobject_class
|
401
|
+
self.class.listobject_class
|
402
|
+
end
|
403
|
+
|
351
404
|
# @private
|
352
405
|
def to_s
|
353
|
-
|
406
|
+
"#<Worksheet: #{(workbook.nil? ? "not alive " : (name + ' ' + File.basename(workbook.stored_filename)))}>"
|
354
407
|
end
|
355
408
|
|
356
409
|
# @private
|
@@ -363,39 +416,22 @@ module RobustExcelOle
|
|
363
416
|
private
|
364
417
|
|
365
418
|
def method_missing(name, *args)
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
end
|
373
|
-
else
|
374
|
-
begin
|
375
|
-
@ole_worksheet.send(name, *args)
|
376
|
-
rescue NoMethodError
|
377
|
-
raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
|
378
|
-
end
|
419
|
+
super unless name.to_s[0,1] =~ /[A-Z]/
|
420
|
+
if ::ERRORMESSAGE_JRUBY_BUG
|
421
|
+
begin
|
422
|
+
@ole_worksheet.send(name, *args)
|
423
|
+
rescue Java::OrgRacobCom::ComFailException
|
424
|
+
raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
|
379
425
|
end
|
380
426
|
else
|
381
|
-
|
427
|
+
begin
|
428
|
+
@ole_worksheet.send(name, *args)
|
429
|
+
rescue NoMethodError
|
430
|
+
raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
|
431
|
+
end
|
382
432
|
end
|
383
433
|
end
|
384
|
-
|
385
|
-
def last_row
|
386
|
-
special_last_row = @ole_worksheet.UsedRange.SpecialCells(RobustExcelOle::XlLastCell).Row
|
387
|
-
used_last_row = @ole_worksheet.UsedRange.Rows.Count
|
388
|
-
|
389
|
-
special_last_row >= used_last_row ? special_last_row : used_last_row
|
390
|
-
end
|
391
|
-
|
392
|
-
def last_column
|
393
|
-
special_last_column = @ole_worksheet.UsedRange.SpecialCells(RobustExcelOle::XlLastCell).Column
|
394
|
-
used_last_column = @ole_worksheet.UsedRange.Columns.Count
|
395
|
-
|
396
|
-
special_last_column >= used_last_column ? special_last_column : used_last_column
|
397
|
-
end
|
398
|
-
|
434
|
+
|
399
435
|
end
|
400
436
|
|
401
437
|
public
|