robust_excel_ole 1.13 → 1.18
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 +47 -4
- data/README.rdoc +52 -47
- data/___dummy_workbook.xls +0 -0
- data/docs/README_excel.rdoc +9 -3
- data/docs/README_open.rdoc +86 -44
- data/docs/README_ranges.rdoc +90 -81
- data/docs/README_save_close.rdoc +9 -9
- data/docs/README_sheet.rdoc +17 -17
- data/examples/example_ruby_library.rb +27 -0
- data/extconf.rb +7 -0
- data/lib/robust_excel_ole.rb +7 -4
- data/lib/robust_excel_ole/{address.rb → address_tool.rb} +23 -22
- data/lib/robust_excel_ole/{reo_common.rb → base.rb} +3 -92
- data/lib/robust_excel_ole/bookstore.rb +14 -77
- data/lib/robust_excel_ole/cell.rb +30 -18
- data/lib/robust_excel_ole/excel.rb +138 -92
- data/lib/robust_excel_ole/general.rb +40 -15
- data/lib/robust_excel_ole/range.rb +42 -19
- data/lib/robust_excel_ole/range_owners.rb +40 -25
- data/lib/robust_excel_ole/vba_objects.rb +30 -0
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +320 -319
- data/lib/robust_excel_ole/worksheet.rb +51 -25
- data/robust_excel_ole.gemspec +1 -0
- data/spec/address_tool_spec.rb +175 -0
- data/spec/{reo_common_spec.rb → base_spec.rb} +19 -34
- data/spec/bookstore_spec.rb +3 -3
- data/spec/cell_spec.rb +67 -25
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +137 -369
- data/spec/general_spec.rb +21 -27
- data/spec/range_spec.rb +57 -3
- data/spec/workbook_spec.rb +11 -79
- data/spec/workbook_specs/workbook_misc_spec.rb +29 -40
- data/spec/workbook_specs/workbook_open_spec.rb +599 -31
- data/spec/workbook_specs/workbook_unobtr_spec.rb +760 -93
- data/spec/worksheet_spec.rb +36 -4
- metadata +12 -7
- data/spec/address_spec.rb +0 -174
data/docs/README_ranges.rdoc
CHANGED
@@ -8,39 +8,39 @@ RobustExcelOle enables to read and write the contents of ranges and cells in wor
|
|
8
8
|
|
9
9
|
Suppose you have opened a workbook.
|
10
10
|
|
11
|
-
|
11
|
+
workbook = Workbook.open('spec/data/workbook.xls', :visible => true)
|
12
12
|
|
13
13
|
We access the first worksheet:
|
14
14
|
|
15
|
-
|
15
|
+
worksheet = workbook.sheet(1)
|
16
16
|
|
17
17
|
Now we can access a range consisting of one cell by providing the row and and the column of a cell. With help of VBA methods you can put
|
18
18
|
|
19
|
-
|
19
|
+
worksheet.Range(sheet.Cells(1,2))
|
20
20
|
|
21
21
|
or using RobustExcelOle
|
22
22
|
|
23
|
-
range =
|
23
|
+
range = worksheet.range([1,2])
|
24
24
|
|
25
25
|
or, using the A1-format,
|
26
26
|
|
27
|
-
range =
|
27
|
+
range = worksheet.range("B1")
|
28
28
|
|
29
29
|
Similarly you can access a rectangular range. Using VBA methods we provide the row and column of the top left cell and the row and column of the bottum right cell.
|
30
30
|
|
31
|
-
range =
|
31
|
+
range = worksheet.Range(sheet.Cells(1,1), sheet.Cells(3,4))
|
32
32
|
|
33
33
|
In RobustExcelOle we would supply the rows and columns as integer ranges.
|
34
34
|
|
35
|
-
range =
|
35
|
+
range = worksheet.range([1..3,1..4])
|
36
36
|
|
37
37
|
or, using the A1-format
|
38
38
|
|
39
|
-
range =
|
39
|
+
range = worksheet.range([1..3,"A".."D"])
|
40
40
|
|
41
41
|
or
|
42
42
|
|
43
|
-
range =
|
43
|
+
range = worksheet.range(["A1:D3"])
|
44
44
|
|
45
45
|
You can read the values by
|
46
46
|
|
@@ -75,72 +75,72 @@ or with help of RobustExcelOle
|
|
75
75
|
|
76
76
|
You can also copy a range into another worksheet in another workbook.
|
77
77
|
|
78
|
-
|
78
|
+
workbook2 = Workbook.open('spec/data/another_workbook.xls', :excel => :new, :visible => true)
|
79
79
|
range.copy([4,5],book2.sheet(3))
|
80
80
|
|
81
81
|
Now we define a name that refers to a range consisting of only the first cell, i.e. the 1st row and 1st column. Using VBA methods, you can use
|
82
82
|
|
83
|
-
|
83
|
+
workbook.Names.Add("Name" => "name", "RefersToR1C1" => "=Z1S1")
|
84
84
|
|
85
85
|
RobustExcelOle provides the method +add_name+.
|
86
86
|
|
87
|
-
|
87
|
+
workbook.add_name("name",[1,1])
|
88
88
|
|
89
89
|
We define a name of a rectangular range. With help of VBA methods this is done by supplying the row and column of the top left cell and the row and columns of the bottum right cell of the range.
|
90
90
|
|
91
|
-
|
91
|
+
workbook.Names.Add("Name" => "name", "RefersToR1C1" => "=Z1S3:Z2S4")
|
92
92
|
|
93
|
-
Using RobustExcelOle
|
93
|
+
Using RobustExcelOle defining a name referring to a rectangular range is done by providing the rows and columns as integer range.
|
94
94
|
|
95
|
-
|
95
|
+
workbook.add_name("name",[1..2,3..4])
|
96
96
|
|
97
97
|
Now we can assign a value to that named range. With help of VBA methods this can be done by
|
98
98
|
|
99
|
-
|
99
|
+
workbook.Names.Item("name").RefersToRange.Value = [["foo", "bar"],[1.0, nil]]
|
100
100
|
|
101
101
|
Now we can read value of that range.
|
102
102
|
|
103
|
-
|
103
|
+
workbook.Names.Item("rec_name").RefersToRange.Value
|
104
104
|
=> [["foo", "bar"],[1.0, nil]]
|
105
105
|
|
106
106
|
or
|
107
107
|
|
108
|
-
|
108
|
+
workbook["name"]
|
109
109
|
=> [["foo", "bar"],[1.0, nil]]
|
110
110
|
|
111
111
|
Finally we can rename a range, and delete the name of a range. With help of VBA methods this can be achieved by
|
112
112
|
|
113
|
-
|
114
|
-
|
113
|
+
workbook.Names.Item("name").Name = "new_name"
|
114
|
+
workbook.Names.Item("new_name").Delete
|
115
115
|
|
116
116
|
Using RobustExcelOle, we write
|
117
117
|
|
118
|
-
|
119
|
-
|
118
|
+
workbook.rename_range("name", "new_name")
|
119
|
+
workbook.delete_name("name")
|
120
120
|
|
121
121
|
Now we can read the value of cell simply by providing the row and the column
|
122
122
|
|
123
|
-
|
123
|
+
worksheet.Cells.Item(1,1).Value
|
124
124
|
|
125
125
|
or with RobustExcelOle
|
126
126
|
|
127
|
-
|
127
|
+
worksheet[1,1].Value
|
128
128
|
=> "foo
|
129
129
|
|
130
130
|
or
|
131
131
|
|
132
|
-
|
132
|
+
worksheet[1,1].v
|
133
133
|
=> "foo"
|
134
134
|
|
135
135
|
Similarly, you can write a cell.
|
136
136
|
|
137
|
-
|
137
|
+
worksheet.Cells.Item(1,1).Value = "new_value"
|
138
138
|
|
139
139
|
or using RobustExcelOle
|
140
140
|
|
141
|
-
|
141
|
+
worksheet[1,1] = "new_value"
|
142
142
|
|
143
|
-
|
143
|
+
In the following some details are being summarized.
|
144
144
|
|
145
145
|
=== Accessing a range
|
146
146
|
|
@@ -148,51 +148,51 @@ You can access a range via its address or defined name. RobustExcelOle allows th
|
|
148
148
|
|
149
149
|
For example, you can access a range consisting of one cell by providing the row and and the column of a cell.
|
150
150
|
|
151
|
-
range =
|
151
|
+
range = worksheet.range([1,1])
|
152
152
|
|
153
153
|
Using the A1-format and R1C1-format you write
|
154
154
|
|
155
|
-
range =
|
155
|
+
range = worksheet.range("A1")
|
156
156
|
|
157
157
|
and
|
158
158
|
|
159
|
-
range =
|
159
|
+
range = worksheet.range("Z1S1")
|
160
160
|
|
161
161
|
respectively.
|
162
162
|
|
163
163
|
You can access a rectangular range by providing the row and column of the top left cell and the row and column of the bottum right cell.
|
164
164
|
|
165
|
-
range =
|
165
|
+
range = worksheet.range([1..3,1..4])
|
166
166
|
|
167
167
|
or using the A1-format.
|
168
168
|
|
169
|
-
range =
|
169
|
+
range = worksheet.range([1..3,"A".."D"])
|
170
170
|
|
171
171
|
or
|
172
172
|
|
173
|
-
range =
|
173
|
+
range = worksheet.range("A1:D3")
|
174
174
|
|
175
175
|
or using the R1C1-format
|
176
176
|
|
177
|
-
range =
|
177
|
+
range = worksheet.range("Z1S1:Z3S4")
|
178
178
|
|
179
179
|
Infinite ranges are defined, e.g., by setting the rows or columns to +nil+
|
180
180
|
|
181
|
-
range =
|
182
|
-
range =
|
181
|
+
range = worksheet.range([1..3,nil])
|
182
|
+
range = worksheet.range([nil,"A".."B"])
|
183
183
|
|
184
184
|
Using the A1-format you write
|
185
185
|
|
186
|
-
range =
|
187
|
-
range =
|
186
|
+
range = worksheet.range("1:3")
|
187
|
+
range = worksheet.range("A:B")
|
188
188
|
|
189
189
|
You can also apply relative references by using brackets, e.g.
|
190
190
|
|
191
|
-
range =
|
191
|
+
range = worksheet.range("Z[1]S1:Z3S[4]")
|
192
192
|
|
193
193
|
or
|
194
194
|
|
195
|
-
range =
|
195
|
+
range = worksheet.range([[1]..3,2..[4]])
|
196
196
|
|
197
197
|
You get the values of the range as flat array with help of
|
198
198
|
|
@@ -200,17 +200,17 @@ You get the values of the range as flat array with help of
|
|
200
200
|
|
201
201
|
You can access a range via its defined name with
|
202
202
|
|
203
|
-
range =
|
203
|
+
range = worksheet.range("name")
|
204
204
|
|
205
205
|
=== Copying a range
|
206
206
|
|
207
207
|
Let's assume, you have a source range
|
208
208
|
|
209
|
-
range =
|
209
|
+
range = worksheet.range(1..2,3..5)
|
210
210
|
|
211
211
|
or, in A1-format,
|
212
212
|
|
213
|
-
range =
|
213
|
+
range = worksheet.range("C1:E2")
|
214
214
|
|
215
215
|
To copy it to the destination range (3..4,6..8), you can use
|
216
216
|
|
@@ -234,47 +234,47 @@ Note that when you don't copy the values only but all formating as well, and you
|
|
234
234
|
|
235
235
|
You can (re-) define a name referring to a range by stating its name, and the address. The address is given by integer-range-format, r1c1-format or a1-format. For example, you can define a name for a rectangular range by
|
236
236
|
|
237
|
-
|
237
|
+
workbook.add_name("name",[1..2,3..5])
|
238
238
|
|
239
239
|
or
|
240
240
|
|
241
|
-
|
241
|
+
workbook.add_name("name","Z1S3:Z2S5")
|
242
242
|
|
243
243
|
or
|
244
244
|
|
245
|
-
|
245
|
+
workbook.add_name("name", "C1:E2")
|
246
246
|
|
247
247
|
Similarly you can define a name referring to a cell
|
248
248
|
|
249
|
-
|
249
|
+
workbook.add_name("name",[1,1])
|
250
250
|
|
251
251
|
or
|
252
252
|
|
253
|
-
|
253
|
+
workbook.add_name("name","Z1S1")
|
254
254
|
|
255
255
|
or
|
256
256
|
|
257
|
-
|
257
|
+
workbook.add_name("name","A1")
|
258
258
|
|
259
259
|
and infinite ranges
|
260
260
|
|
261
|
-
|
261
|
+
workbook.add_name("name",[1..2,nil])
|
262
262
|
|
263
263
|
or
|
264
264
|
|
265
|
-
|
265
|
+
workbook.add_name("name", "Z1:Z2")
|
266
266
|
|
267
267
|
or
|
268
268
|
|
269
|
-
|
269
|
+
workbook.add_name("name","1:2")
|
270
270
|
|
271
271
|
Furthermore, you can define a name using relative references with the r1c1-format.
|
272
272
|
|
273
|
-
|
273
|
+
workbook.add_name("name", "Z1S[1]:Z[2]S4")
|
274
274
|
|
275
275
|
or
|
276
276
|
|
277
|
-
|
277
|
+
workbook.add_name("name", [1..[2],[1]..4])
|
278
278
|
|
279
279
|
You can do the same for an worksheet or Excel object.
|
280
280
|
|
@@ -282,43 +282,46 @@ You can do the same for an worksheet or Excel object.
|
|
282
282
|
|
283
283
|
Assume you have opened a workbook:
|
284
284
|
|
285
|
-
|
285
|
+
workbook = Workbook.open('spec/data/workbook.xls', :visible => true)
|
286
286
|
|
287
287
|
You can get the contents of a range with a defined name with help of the method [] or +namevalue_glob+.
|
288
288
|
|
289
|
-
|
289
|
+
workbook["name"]
|
290
290
|
=> "value"
|
291
291
|
|
292
292
|
or
|
293
293
|
|
294
|
-
|
294
|
+
workbook.namevalue_glob("name")
|
295
295
|
=> "value"
|
296
296
|
|
297
297
|
Using +namevalue_glob+, via the option +:default+ you can provide a value that is returned when the name cannot be found or some other error would occur.
|
298
298
|
|
299
|
-
|
299
|
+
workbook.namvalue_glob("name", :default => "default_value")
|
300
300
|
|
301
301
|
You can set the contents of a range with
|
302
302
|
|
303
|
-
|
303
|
+
workbook["name"] = "new_value"
|
304
304
|
|
305
305
|
or
|
306
306
|
|
307
|
-
|
307
|
+
workbook.set_namevalue_glob("name", "new_value")
|
308
308
|
|
309
|
-
|
309
|
+
You can color the range when setting the contents of a range.
|
310
310
|
|
311
|
-
|
312
|
-
|
311
|
+
workbook.set_namevalue_glob("name", "new_value", :color => 4)
|
312
|
+
|
313
|
+
The method []= sets the contents of a range and colors the range via some default color.
|
314
|
+
|
315
|
+
workbook["name"] = "new_value"
|
313
316
|
|
314
317
|
Similarly, the contents of a named range can be read and modified in a worksheet
|
315
318
|
|
316
|
-
|
319
|
+
worksheet = workbook.sheet(1)
|
317
320
|
|
318
|
-
|
321
|
+
worksheet["name"]
|
319
322
|
=> value
|
320
323
|
|
321
|
-
|
324
|
+
worksheet["name"] = "new_value"
|
322
325
|
|
323
326
|
or an Application object.
|
324
327
|
|
@@ -334,7 +337,7 @@ or an Application object.
|
|
334
337
|
|
335
338
|
The contents of locally defined ranges can be read by
|
336
339
|
|
337
|
-
|
340
|
+
worksheet.namevalue("name")
|
338
341
|
=> "value"
|
339
342
|
|
340
343
|
or
|
@@ -344,7 +347,7 @@ or
|
|
344
347
|
|
345
348
|
and be modified by
|
346
349
|
|
347
|
-
|
350
|
+
worksheet.set_namevalue("name", "value")
|
348
351
|
|
349
352
|
or
|
350
353
|
|
@@ -352,54 +355,60 @@ or
|
|
352
355
|
|
353
356
|
Similarly to namevalue, you can provide a default value that is returned when ocurring an error.
|
354
357
|
|
355
|
-
|
358
|
+
worksheet.namevalue("name", :default => "default_value")
|
356
359
|
|
357
360
|
=== Accessing a cell
|
358
361
|
|
359
362
|
You can read a cell from a sheet object by providing the row and the column. For example, the following lines provide the value of the first cell (first row, first column):
|
360
363
|
|
361
|
-
|
364
|
+
worksheet[1,1].Value
|
362
365
|
=> "foo
|
363
366
|
|
364
367
|
or
|
365
368
|
|
366
|
-
|
369
|
+
worksheet.cellval(1,1)
|
367
370
|
=> "foo"
|
368
371
|
|
369
372
|
Similarly, you can write a cell.
|
370
373
|
|
371
|
-
|
374
|
+
worksheet[1,1] = "new_value"
|
372
375
|
|
373
376
|
or
|
374
377
|
|
375
|
-
|
378
|
+
worksheet.set_cellval(1,1,"new_value")
|
376
379
|
|
377
380
|
=== Accessing rows and columns
|
378
381
|
|
379
382
|
The methods Worksheet#each, Worksheet#each_row and Worksheet#each_column enable to access each cell, row and column, respectively.
|
380
383
|
|
381
|
-
|
384
|
+
worksheet.each do |cell|
|
382
385
|
# do something with cell
|
383
386
|
# read every row, every column
|
384
387
|
end
|
385
388
|
|
386
|
-
|
389
|
+
worksheet.each_row do |row|
|
387
390
|
# do something with row
|
388
391
|
end
|
389
392
|
|
390
|
-
|
393
|
+
worksheet.each_column do |column|
|
391
394
|
# do something with column
|
392
395
|
end
|
393
396
|
|
397
|
+
The method Worksheet#each_value accesses the values of each row.
|
398
|
+
|
399
|
+
worksheet.each_value do |row_values|
|
400
|
+
# do something with the row_values
|
401
|
+
end
|
402
|
+
|
394
403
|
You access a range of a row by giving the number of the row, and optionally, the range of the cell numbers.
|
395
404
|
|
396
|
-
|
397
|
-
|
405
|
+
worksheet.row_range(1) # => first row
|
406
|
+
worksheet.row_range(1, 1..3 ) # => first three cells of the first row
|
398
407
|
|
399
408
|
Simarly you can access a range of a column.
|
400
409
|
|
401
|
-
|
402
|
-
|
410
|
+
worksheet.col_range(3) # => third column
|
411
|
+
worksheet.col_range(3, 1..2) # => first two cells of the third column
|
403
412
|
|
404
413
|
Within a row or column range you can access a certain cell.
|
405
414
|
|
data/docs/README_save_close.rdoc
CHANGED
@@ -6,17 +6,17 @@
|
|
6
6
|
|
7
7
|
Imagine, you have opened a workbook with
|
8
8
|
|
9
|
-
|
9
|
+
workbook = Workbook.open('spec/data/workbook.xls', :visible => true)
|
10
10
|
|
11
11
|
and have modified it.
|
12
12
|
|
13
13
|
You can save the workbook by
|
14
14
|
|
15
|
-
|
15
|
+
workbook.save
|
16
16
|
|
17
17
|
If you want to save a workbook with a file name, then use
|
18
18
|
|
19
|
-
|
19
|
+
workbook.save_as('new_workbook.xls')
|
20
20
|
|
21
21
|
The options and respective valid values are the following:
|
22
22
|
|
@@ -33,19 +33,19 @@ If a workbook with the file name already exists, then
|
|
33
33
|
|
34
34
|
For example, you want to save a workbook and overwrite the file if it exists before, then use
|
35
35
|
|
36
|
-
|
36
|
+
workbook.save_as('another_workbook.xls', :if_exists => :overwrite)
|
37
37
|
|
38
38
|
If a workbook blocks the workbook that should be saved, then the former one can be saved and closed before.
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
workbook = Workbook.open('spec/data/workbook.xls')
|
41
|
+
workbook2 = Workbook.open('spec/data/another_workbook.xls')
|
42
|
+
workbook2.save_as('dir/workbook.xls', :if_exists => :overwrite, :if_obstructed => :save)
|
43
43
|
|
44
44
|
=== Closing a workbook.
|
45
45
|
|
46
46
|
You can close the workbook with the command
|
47
47
|
|
48
|
-
|
48
|
+
workbook.close
|
49
49
|
|
50
50
|
There is one option: +:if_unsaved+ . It can have one of the following values:
|
51
51
|
|
@@ -62,7 +62,7 @@ The option specifies: If the workbook is unsaved, then
|
|
62
62
|
|
63
63
|
You can open a workbook with given file name.
|
64
64
|
|
65
|
-
|
65
|
+
workbook = Workbook.open('spec/data/workbook.xls')
|
66
66
|
|
67
67
|
You can save a workbook with given file name, if it is open.
|
68
68
|
|