robust_excel_ole 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +73 -26
- data/README_detail.rdoc +92 -27
- data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
- data/examples/edit_sheets/example_concating.rb +12 -12
- data/examples/edit_sheets/example_copying.rb +47 -0
- data/examples/edit_sheets/example_expanding.rb +17 -26
- data/examples/edit_sheets/example_naming.rb +13 -10
- data/examples/edit_sheets/example_ranges.rb +2 -2
- data/examples/edit_sheets/example_saving.rb +8 -14
- data/examples/open_save_close/example_control_to_excel.rb +1 -1
- data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
- 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 +4 -4
- data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
- data/examples/open_save_close/example_read_only.rb +1 -1
- data/examples/open_save_close/example_rename_cells.rb +1 -13
- 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.rb +81 -2
- data/lib/robust_excel_ole/book.rb +171 -118
- data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
- data/lib/robust_excel_ole/excel.rb +153 -24
- data/lib/robust_excel_ole/range.rb +2 -2
- data/lib/robust_excel_ole/sheet.rb +84 -35
- data/lib/robust_excel_ole/version.rb +1 -1
- data/reo.bat +3 -0
- data/spec/book_close_spec.rb +179 -0
- data/spec/book_misc_spec.rb +365 -0
- data/spec/book_open_spec.rb +793 -0
- data/spec/book_save_spec.rb +257 -0
- data/spec/book_sheet_spec.rb +160 -0
- data/spec/book_spec.rb +145 -1533
- data/spec/book_subclass_spec.rb +50 -0
- data/spec/book_unobtr_spec.rb +950 -0
- data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
- data/spec/cell_spec.rb +6 -6
- data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
- data/spec/data/different_workbook.xls +0 -0
- data/spec/data/workbook.xls +0 -0
- data/spec/data/workbook.xlsm +0 -0
- data/spec/data/workbook.xlsx +0 -0
- data/spec/data/workbook_linked.xlsm +0 -0
- data/spec/data/workbook_linked_sub.xlsm +0 -0
- data/spec/excel_spec.rb +204 -5
- data/spec/range_spec.rb +6 -6
- data/spec/sheet_spec.rb +122 -34
- metadata +18 -8
- data/spec/data/workbook_connected_sub.xlsm +0 -0
data/README.rdoc
CHANGED
@@ -71,13 +71,13 @@ Closing the workbook and saving it before if it has unsaved changes.
|
|
71
71
|
|
72
72
|
book.close(:if_unsaved => :save)
|
73
73
|
|
74
|
-
=== Reopening
|
74
|
+
=== Reopening a workbook.
|
75
75
|
|
76
|
-
A special feature of robust_excel_ole is that it allows
|
76
|
+
A special feature of robust_excel_ole is that it allows to reopen books after closing them.
|
77
77
|
|
78
78
|
book = Book.open('workbook.xls')
|
79
79
|
book.close
|
80
|
-
|
80
|
+
book.reopen
|
81
81
|
|
82
82
|
The closed book is now alive again, i.e. is open and responds to Excel methods.
|
83
83
|
|
@@ -85,8 +85,6 @@ This feature is achieved by providing identity transperence and by storing the f
|
|
85
85
|
Identity transperence means that the same Book objects refer to the same Excel files, and vice versa.
|
86
86
|
In other words, a Book objects is a proxy of an Excel file.
|
87
87
|
|
88
|
-
reopened_book === book
|
89
|
-
=> true
|
90
88
|
|
91
89
|
=== Saving a workbook.
|
92
90
|
|
@@ -107,21 +105,23 @@ Saving a workbook and overwriting the file if it exists before.
|
|
107
105
|
|
108
106
|
The method +unobtrusively+ enables the user to read or modify a workbook, no matter if it is open in some Excel instance, if it is saved or unsaved, and if it is writable or not. When opening a workbook unobtrusively, its status remains unchanged. This status includes, whether the book is opened or closed, saved or unsaved, readonly or writable.
|
109
107
|
|
110
|
-
|
108
|
+
One option chooses the Excel instance in which a closed book is opened. The options +:reuse (default) indicates that the closed book is opened in the Excel instance of the book, if it exists, or that another Excel instance is reused. The option +:hidden+ provokes that the closed book is opened in a separate Excel instance that is not visible and has no DisplayAlerts. Any following closed book would be opened in this Excel instance as well when using this option. Moreover, an Excel instance can be given directly where to open the closed book.
|
111
109
|
|
112
|
-
|
110
|
+
Further options are +:read_only+, +:readonly_excel+, and +:keep_open. The option +:readonly_excel+ chooses whether a book that is opened as ReadOnly and that shall be modified shall be opned as writable in the Excel instance where it was open so far, or if it shall be opened as writable in another running Excel instance, if such an Excel exists, or opened in a new Excel instance.
|
113
111
|
|
114
|
-
Book.unobtrusively('workbook.xls', :
|
112
|
+
Book.unobtrusively('workbook.xls', :reuse, :read_only => false, :keep_open => false) do |book|
|
115
113
|
# some modification
|
116
114
|
sheet = book[0]
|
117
|
-
sheet[
|
115
|
+
sheet[1,1] = "c"
|
118
116
|
end
|
119
117
|
|
120
|
-
|
118
|
+
The methods +for_reading+ and +for_modifying+ indicate unobtrusively reading or modifying.
|
121
119
|
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
Book.for_modifying('workbook.xls') do |book|
|
121
|
+
# some modification
|
122
|
+
sheet = book[0]
|
123
|
+
sheet[1,1] = "c"
|
124
|
+
end
|
125
125
|
|
126
126
|
=== Checking whether the workbook is alive.
|
127
127
|
|
@@ -129,6 +129,26 @@ This method finds out whether the Excel workbook that is referenced by the Book
|
|
129
129
|
|
130
130
|
if book.alive? then sheet = book[0] end
|
131
131
|
|
132
|
+
=== Setting and getting the contents of a range.
|
133
|
+
|
134
|
+
Setting:
|
135
|
+
|
136
|
+
book["name"] = "value"
|
137
|
+
|
138
|
+
or
|
139
|
+
|
140
|
+
book.set_nvalue("name") = "value"
|
141
|
+
|
142
|
+
Getting:
|
143
|
+
|
144
|
+
book["name"]
|
145
|
+
=> "value"
|
146
|
+
|
147
|
+
or
|
148
|
+
|
149
|
+
book.nvalue("name")
|
150
|
+
=> "value"
|
151
|
+
|
132
152
|
=== Making an Excel visible or invisible, and enable and disable DisplayAlerts.
|
133
153
|
|
134
154
|
Make an Excel visible
|
@@ -177,7 +197,7 @@ A sheet object is enumerable. Use the methods Sheet#each_column, Sheet#each_row
|
|
177
197
|
|
178
198
|
Reading a cell from a sheet object.
|
179
199
|
|
180
|
-
sheet[
|
200
|
+
sheet[1, 1] => first cell (first row, first column).
|
181
201
|
|
182
202
|
Reading a cell from a range object.
|
183
203
|
|
@@ -188,26 +208,48 @@ Methods to a cell are just delegated. Example:
|
|
188
208
|
|
189
209
|
Reading the value of a cell.
|
190
210
|
|
191
|
-
cell = sheet[
|
211
|
+
cell = sheet[1,1]
|
192
212
|
cell.Value => value of the cell.
|
193
213
|
|
194
214
|
Writing a cell
|
195
215
|
|
196
|
-
sheet[
|
197
|
-
|
216
|
+
sheet[1,1] = "new_value"
|
198
217
|
|
199
218
|
=== Accessing a range of a row or column.
|
200
219
|
|
201
220
|
Accessing a range of a row.
|
202
221
|
|
203
|
-
sheet.row_range(
|
204
|
-
sheet.row_range(
|
222
|
+
sheet.row_range(1) => first row
|
223
|
+
sheet.row_range(1, 1..3 ) => first three cells of the first row
|
205
224
|
|
206
225
|
Accessing a range of a column.
|
207
226
|
|
208
|
-
sheet.col_range(
|
209
|
-
sheet.col_range(
|
227
|
+
sheet.col_range(3) => third column
|
228
|
+
sheet.col_range(3, 1..2) => first two cells of the third column
|
229
|
+
|
230
|
+
=== Naming a cell
|
231
|
+
|
232
|
+
Naming or renaming a cell range given its address.
|
233
|
+
|
234
|
+
book.add_name(1,1,"name")
|
235
|
+
|
236
|
+
=== Reading and modifying a Value of a named range
|
237
|
+
|
238
|
+
Returning the value of a range, e.g. a cell, that has a with a defined name.
|
239
|
+
|
240
|
+
book.nvalue(name)
|
210
241
|
|
242
|
+
or
|
243
|
+
|
244
|
+
book[name]
|
245
|
+
|
246
|
+
Setting the value of a range, e.g. a cell, that has a with a defined name.
|
247
|
+
|
248
|
+
book.set_nvalue(name,value)
|
249
|
+
|
250
|
+
or
|
251
|
+
|
252
|
+
book[name] = value
|
211
253
|
|
212
254
|
=== Adding a sheet.
|
213
255
|
|
@@ -282,6 +324,11 @@ Turning on and off in a block.
|
|
282
324
|
book = Book.open('workbook.xls')
|
283
325
|
end
|
284
326
|
|
327
|
+
=== Closing an Excel
|
328
|
+
|
329
|
+
excel = Excel.current
|
330
|
+
excel.close
|
331
|
+
|
285
332
|
=== Closing all Excel instances.
|
286
333
|
|
287
334
|
Excel.close_all
|
@@ -398,7 +445,7 @@ Opening a book with the same name in a different path. Close the old book.
|
|
398
445
|
Changing its cell.
|
399
446
|
|
400
447
|
sheet = book2[0]
|
401
|
-
sheet[
|
448
|
+
sheet[1,1] = "new"
|
402
449
|
|
403
450
|
Opening a book with the same name in a different path. The old book that was modified will be saved and closed before.
|
404
451
|
|
@@ -422,22 +469,22 @@ Opening a book.
|
|
422
469
|
Printing its first cell.
|
423
470
|
|
424
471
|
sheet = book[0]
|
425
|
-
p "1st cell: #{sheet[
|
472
|
+
p "1st cell: #{sheet[1,1].Value}"
|
426
473
|
|
427
474
|
Unobtrusively modify the book.
|
428
475
|
|
429
476
|
Book.unobtrusively('workbook.xls') do |book|
|
430
477
|
sheet = book[0]
|
431
|
-
sheet[
|
478
|
+
sheet[1,1] = 'simple'
|
432
479
|
end
|
433
480
|
|
434
481
|
The book is modified, but its status is unchanged.
|
435
482
|
|
436
483
|
new_sheet = book[0]
|
437
|
-
not (new_sheet[
|
484
|
+
not (new_sheet[1,1].Value == sheet[1,1].Value)
|
438
485
|
=> true
|
439
486
|
|
440
|
-
book.
|
487
|
+
book.saved
|
441
488
|
=> true
|
442
489
|
|
443
490
|
|
data/README_detail.rdoc
CHANGED
@@ -110,6 +110,20 @@ The option specifies: If the workbook is unsaved, then
|
|
110
110
|
+:forget+:: Close the workbook.
|
111
111
|
+:alert+:: Give control to Excel.
|
112
112
|
|
113
|
+
=== Reopening a workbook.
|
114
|
+
|
115
|
+
A special feature of robust_excel_ole is that it allows to reopen books after closing them.
|
116
|
+
|
117
|
+
book = Book.open('workbook.xls')
|
118
|
+
book.close
|
119
|
+
book.reopen
|
120
|
+
|
121
|
+
The closed book is now alive again, i.e. is open and responds to Excel methods.
|
122
|
+
|
123
|
+
This feature is achieved by providing identity transperence and by storing the file name.
|
124
|
+
Identity transperence means that the same Book objects refer to the same Excel files, and vice versa.
|
125
|
+
In other words, a Book objects is a proxy of an Excel file.
|
126
|
+
|
113
127
|
|
114
128
|
=== Saving a workbook.
|
115
129
|
|
@@ -138,37 +152,59 @@ If a book with the file name already exists, then
|
|
138
152
|
|
139
153
|
The method +unobtrusively+ enables the user to read or modify a workbook, no matter if it is open in some Excel instance, if it is saved or unsaved, and if it is writable or not. When opening a workbook unobtrusively, its status remains unchanged. This status includes, whether the book is opened or closed, saved or unsaved, readonly or writable.
|
140
154
|
|
141
|
-
|
142
|
-
|
143
|
-
The option +:if_closed+ => +:hidden+ provokes that a closed book is opened unobtrusively in a separate Excel instance that is not visible and has no DisplayAlerts. Any following closed book would be opened in this Excel instance as well when using this option.
|
155
|
+
One option chooses the Excel instance in which a closed book is opened. The options +:reuse (default) indicates that the closed book is opened in the Excel instance of the book, if it exists, or that another Excel instance is reused. The option +:hidden+ provokes that the closed book is opened in a separate Excel instance that is not visible and has no DisplayAlerts. Any following closed book would be opened in this Excel instance as well when using this option. Moreover, an Excel instance can be given directly where to open the closed book.
|
144
156
|
|
145
157
|
Options are the following:
|
146
158
|
|
147
|
-
|
148
|
-
|
149
|
-
|
159
|
+
:reuse (default) : open a closed book in the Excel instance of the book, if it exists, otherwise reuse another Excel
|
160
|
+
:hidden : open a closed book in one separate Excel instance that is not visible and has no displayaslerts
|
161
|
+
<excel-instance> : open a closed workbooks in the given Excel instance
|
162
|
+
|
150
163
|
+:read_only+:: Open the book unobtrusively for reading only (default: false)
|
151
|
-
+:
|
152
|
-
|
153
|
-
|
164
|
+
+:readonly_excel+:: if the book is opened only as ReadOnly and shall be modified, then
|
165
|
+
true: close it and open it as writable in the excel instance where it was open so far
|
166
|
+
false (default) open it as writable in another running excel instance, if it exists,
|
154
167
|
otherwise open in a new excel instance
|
155
168
|
+:keep_open+:: let the book open after unobtrusively opening (default: false)
|
156
169
|
|
157
170
|
Book.unobtrusively('workbook.xls') do |book|
|
158
171
|
# some modification
|
159
172
|
sheet = book[0]
|
160
|
-
sheet[
|
173
|
+
sheet[1,1] = "c"
|
161
174
|
end
|
162
175
|
|
163
|
-
|
176
|
+
The methods +for_reading+ and +for_modifying+ indicate unobtrusively reading or modifying.
|
164
177
|
|
165
|
-
|
178
|
+
Book.for_modifying('workbook.xls') do |book|
|
179
|
+
# some modification
|
180
|
+
sheet = book[0]
|
181
|
+
sheet[1,1] = "c"
|
182
|
+
end
|
166
183
|
|
167
|
-
book.nvalue(name)
|
168
184
|
|
169
185
|
=== Checking whether the referenced Excel workbook responds to methods.
|
170
186
|
|
171
|
-
|
187
|
+
book.alive?
|
188
|
+
|
189
|
+
=== Setting and getting the contents of a range.
|
190
|
+
|
191
|
+
Setting:
|
192
|
+
|
193
|
+
book["name"] = "value"
|
194
|
+
|
195
|
+
or
|
196
|
+
|
197
|
+
book.set_nvalue("name") = "value"
|
198
|
+
|
199
|
+
Getting:
|
200
|
+
|
201
|
+
book["name"]
|
202
|
+
=> "value"
|
203
|
+
|
204
|
+
or
|
205
|
+
|
206
|
+
book.nvalue("name")
|
207
|
+
=> "value"
|
172
208
|
|
173
209
|
=== Making an Excel visible or invisible, and enable and disable DisplayAlerts.
|
174
210
|
|
@@ -220,7 +256,7 @@ A sheet object is enumerable. Use the methods Sheet#each_column, Sheet#each_row
|
|
220
256
|
|
221
257
|
Reading a cell from a sheet object.
|
222
258
|
|
223
|
-
sheet[
|
259
|
+
sheet[1, 1] => first cell.
|
224
260
|
|
225
261
|
Reading a cell from a range object.
|
226
262
|
|
@@ -231,26 +267,49 @@ Methods to cell are just delegated as VBA methods. Example:
|
|
231
267
|
|
232
268
|
Reading the value of a cell.
|
233
269
|
|
234
|
-
cell = sheet[
|
270
|
+
cell = sheet[1,1]
|
235
271
|
cell.Value => value of the cell.
|
236
272
|
|
237
273
|
Writing a cell
|
238
274
|
|
239
|
-
sheet[
|
275
|
+
sheet[1,1] = "new_value"
|
240
276
|
|
241
277
|
|
242
278
|
=== Accessing a range of a row or column.
|
243
279
|
|
244
280
|
Accessing a range of a row.
|
245
281
|
|
246
|
-
sheet.row_range(
|
247
|
-
sheet.row_range(
|
282
|
+
sheet.row_range(1) => first row
|
283
|
+
sheet.row_range(1, 1..3 ) => first three cells of the first row
|
248
284
|
|
249
285
|
Accessing a range of a column.
|
250
286
|
|
251
|
-
sheet.col_range(
|
252
|
-
sheet.col_range(
|
287
|
+
sheet.col_range(3) => third column
|
288
|
+
sheet.col_range(3, 1..2) => first two cells of the third column
|
289
|
+
|
290
|
+
=== Naming a cell
|
253
291
|
|
292
|
+
Naming or renaming a cell range given its address.
|
293
|
+
|
294
|
+
book.add_name(1,1,"name")
|
295
|
+
|
296
|
+
=== Reading and modifying a Value of a named range
|
297
|
+
|
298
|
+
Returning the value of a range, e.g. a cell, that has a with a defined name.
|
299
|
+
|
300
|
+
book.nvalue(name)
|
301
|
+
|
302
|
+
or
|
303
|
+
|
304
|
+
book[name]
|
305
|
+
|
306
|
+
Setting the value of a range, e.g. a cell, that has a with a defined name.
|
307
|
+
|
308
|
+
book.set_nvalue(name,value)
|
309
|
+
|
310
|
+
or
|
311
|
+
|
312
|
+
book[name] = value
|
254
313
|
|
255
314
|
=== Adding a sheet.
|
256
315
|
|
@@ -331,6 +390,12 @@ Turning on and off in a block.
|
|
331
390
|
|
332
391
|
Excel.close_all
|
333
392
|
|
393
|
+
=== Closing an Excel
|
394
|
+
|
395
|
+
excel = Excel.current
|
396
|
+
excel.close
|
397
|
+
|
398
|
+
|
334
399
|
=== Examples
|
335
400
|
|
336
401
|
Including robust_excel_ole.
|
@@ -349,7 +414,7 @@ Accessing a sheet via its name.
|
|
349
414
|
|
350
415
|
Changing the first cell.
|
351
416
|
|
352
|
-
sheet[
|
417
|
+
sheet[1,1] = "new"
|
353
418
|
|
354
419
|
Saving the book.
|
355
420
|
|
@@ -449,7 +514,7 @@ Opening a book with the same name in a different path. Close the old book.
|
|
449
514
|
Changing its cell.
|
450
515
|
|
451
516
|
sheet = book2[0]
|
452
|
-
sheet[
|
517
|
+
sheet[1,1] = "new"
|
453
518
|
|
454
519
|
Opening a book with the same name in a different path. The old book that was modified will be saved and closed before.
|
455
520
|
|
@@ -473,22 +538,22 @@ Opening a book.
|
|
473
538
|
Printing its first cell.
|
474
539
|
|
475
540
|
sheet = book[0]
|
476
|
-
p "1st cell: #{sheet[
|
541
|
+
p "1st cell: #{sheet[1,1].Value}"
|
477
542
|
|
478
543
|
Unobtrusively modify the book.
|
479
544
|
|
480
545
|
Book.unobtrusively('workbook.xls') do |book|
|
481
546
|
sheet = book[0]
|
482
|
-
sheet[
|
547
|
+
sheet[1,1] = 'simple'
|
483
548
|
end
|
484
549
|
|
485
550
|
The book is modified, but its status is unchanged.
|
486
551
|
|
487
552
|
new_sheet = book[0]
|
488
|
-
not (new_sheet[
|
553
|
+
not (new_sheet[1,1].Value == sheet[1,1].Value)
|
489
554
|
=> true
|
490
555
|
|
491
|
-
book.
|
556
|
+
book.saved
|
492
557
|
=> true
|
493
558
|
|
494
559
|
|
@@ -15,10 +15,10 @@ begin
|
|
15
15
|
File.delete simple_save_file rescue nil
|
16
16
|
book = Book.open(simple_file) # open a book
|
17
17
|
sheet = book[0] # access a sheet via integer
|
18
|
-
cell = sheet[
|
18
|
+
cell = sheet[1,1] # access the first cell
|
19
19
|
puts "1st cell: #{cell.Value}" # put the value of the first cell
|
20
|
-
sheet[
|
21
|
-
puts "new cell: #{sheet[
|
20
|
+
sheet[1,1] = "complex" # write a value into a cell
|
21
|
+
puts "new cell: #{sheet[1,1].Value}"
|
22
22
|
puts "all cells:"
|
23
23
|
sheet.each do |cell| # access all cells
|
24
24
|
puts "#{cell.Value}" # for each row: for every column: put the value of the cells
|
@@ -1,31 +1,31 @@
|
|
1
|
-
#
|
1
|
+
# example_concating.rb:
|
2
2
|
# each named cell gets the value of cell right to it appended to its own value
|
3
3
|
# the new workbook's name is extended by the suffix "_concat"
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
|
-
require 'robust_excel_ole'
|
6
|
+
#require 'robust_excel_ole'
|
7
|
+
require File.join(File.dirname(__FILE__), '../../lib/robust_excel_ole')
|
7
8
|
require "fileutils"
|
8
9
|
|
9
10
|
include RobustExcelOle
|
10
11
|
|
11
12
|
begin
|
12
|
-
Excel.close_all
|
13
13
|
dir = "C:/data"
|
14
14
|
workbook_name = 'workbook_named.xls'
|
15
|
-
|
16
|
-
|
15
|
+
ws = workbook_name.split(".")
|
16
|
+
base_name = ws[0,ws.length-1].join(".")
|
17
|
+
suffix = ws.last
|
17
18
|
file_name = dir + "/" + workbook_name
|
18
19
|
extended_file_name = dir + "/" + base_name + "_concat" + "." + suffix
|
19
|
-
|
20
|
-
|
21
|
-
book_orig.close
|
20
|
+
FileUtils.copy file_name, extended_file_name
|
21
|
+
|
22
22
|
Book.unobtrusively(extended_file_name) do |book|
|
23
23
|
book.each do |sheet|
|
24
|
-
sheet.each do |
|
25
|
-
name =
|
24
|
+
sheet.each do |cell|
|
25
|
+
name = cell.Name.Name rescue nil
|
26
26
|
if name
|
27
|
-
|
28
|
-
sheet.
|
27
|
+
cell.Value = cell.Value.to_s + cell.Offset(0,1).Value.to_s
|
28
|
+
sheet.set_name(name, cell.Row, cell.Column)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|