robust_excel_ole 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,8 +1,19 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.0.2] - 2017-07-26
4
5
 
5
- ## [1.0.1] - 2017-01-04
6
+ ### Added
7
+
8
+ - Excel#set_options
9
+ - Excel#retain_saved_workbooks
10
+ - Book#retain_saved
11
+
12
+ ### Changed
13
+
14
+ - Book#unobtrusively: option: :if_closed =>
15
+
16
+ ## [1.0.1] - 2017-16-04
6
17
 
7
18
  ### Added
8
19
 
data/README.rdoc CHANGED
@@ -5,37 +5,11 @@ It supports simultaneously running Excel instances and user interactions.
5
5
  RobustExcelOle deals with various cases of Excel and user behaviour,
6
6
  and implements workarounds for some Excel bugs.
7
7
  The gem provides convenient methods for common tasks, and facilitates referenced libraries.
8
- It supports Excel 2010 and Excel 2007.
8
+ It supports Excel 2010.
9
9
 
10
10
  RobustExcelOle works by sending VBA methods via Win32OLE.
11
11
  Moreover, it implements a management system and keeps track of Excel files and Excel instances.
12
12
 
13
- In the following, some features of RobustExcelOle are depicted.
14
-
15
- RobustExcelOle allows a "script mode" and an "interactive mode": Commands enable to open Excel files (or workbooks) in various Excel instances, enable to close, reopen, modify and save the Excel files, without the need of the user's interaction, and even without the user noticing. While running this script, the user can open and mofify any Excel files at any time. RobustExcelOle manages the complex cases of conflicts that might occur such that the user does not need to interfere and the script can continue.
16
-
17
- For example, suppose you want to process a list of workbooks (Excel files). RobustExcelOle allows to rapidly open, manipulate, close and save these workbooks (script mode). Now assume, the workbook "workbook.xls" is being processed, while the user has opened this workbook, has manipulated but not saved it yet. Excel would prompt a message and ask the user what to do. RobustExcelOle solves this conflict by using several options that state whether the changes of the user should be saved (accepted) or discarded before opening the workbook.
18
-
19
- book1 = Book.open('workbook.xls') # user
20
- ...
21
- book2 = Book.open('workbook.xls', :if_unsaved => accept) # script
22
-
23
- Similarly, if the user has opened a workbook that has the same name but a different path, the conflict is solved via options.
24
-
25
- book1 = Book.open('path1/workbook.xls')
26
- ...
27
- book2 = Book.open('workbook.xls', :if_obstructed => :forget)
28
-
29
- Another feature that RobustExcelOle povides is reopening workbooks after closing them. A workbook is opened by default in the Excel instance where it was open before most recently. If this Excel instance is damaged or closed, then RobustExcelIle controls via options whether the workbook is opened in the current (active) Excel instance, a new or a given Excel instance.
30
-
31
- book1 = Book.open('workbook.xls', :default => {:excel => :new})
32
-
33
- Moreover, RobustExcelOle allows unobtrusively reading and modifying workbooks, i.e. accessing workbooks without changing their "status". The status comprises whether the workbook is open in some Excel instance , saved and writable.
34
-
35
- Book.for_modifying('workbook.xls') do |book|
36
- ...
37
- end
38
-
39
13
  == Requirements
40
14
 
41
15
  * Ruby 1.8.6 or higher
@@ -49,58 +23,37 @@ Moreover, RobustExcelOle allows unobtrusively reading and modifying workbooks, i
49
23
  require 'robust_excel_ole'
50
24
  include RobustExcelOle
51
25
 
52
- === Opening a workbook.
53
-
54
- book = Book.open('workbook.xls')
55
-
56
- You can also open a workbook with a block.
57
- The semantics is similar to, e.g., +File.open+.
58
-
59
- Book.open('workbook.xls') do |book|
60
- # do something
61
- end
62
-
63
- There are some options that determine the Excel instance in which the workbook is opened, the visibility, calculation mode, and solving conflicts when the workbook is unsaved or blocked. Here are a few examples:
64
-
65
- If you want to open a workbook that was not opened before, or reopen a workbook that was open in an Excel instance that is now closed, in the current (active) Excel instance, then use
66
-
67
- Book.open('workbook.xls', :default => {:excel => :current})
68
-
69
- or simply
70
-
71
- Book.open('workbook.xls')
72
-
73
- If you want to open a workbook in a new Excel instance, no matter if it was opened before, you can write
74
-
75
- Bool.open('workbook.xls', :force => {:excel => :new})
26
+ == Description
76
27
 
77
- If you want to open the workbook and make its window visible, then you can use
78
-
79
- book = Book.open('workbook.xls', :visible => true)
80
-
81
- If a workbook contains unsaved changes, a workbook with the same filename shall be opened and the former one shall remain open, you apply
28
+ In the following, some features of RobustExcelOle are depicted.
82
29
 
83
- book = Book.open('workbook.xls', :if_unsaved => :accept)
30
+ RobustExcelOle allows a "script mode" and an "interactive mode": Commands enable to open Excel files (or workbooks) in various Excel instances, enable to close, reopen, modify and save the Excel files, without the need of the user's interaction, and even without the user noticing. While running this script mode, the user can open and modify any Excel files in any Excel instances at any time. RobustExcelOle manages the complex cases of conflicts that might occur such that the user does not need to interfere and the script can continue.
84
31
 
85
- If a workbook is open and a workbook with the same name but in different path shall be opened, i.e. the first workbook blocks opening the other workbook, then the option +:if_obstructed+ handles this situation, e.g.
32
+ For example, suppose you want to process a list of workbooks (Excel files). RobustExcelOle allows to rapidly open, manipulate, close and save these workbooks (script mode). Now assume, the workbook "workbook.xls" is being processed, while the user has opened this workbook, has manipulated but not saved it yet. Excel would prompt a message and ask the user what to do. RobustExcelOle solves this conflict by using several options that state whether the changes of the user should be saved (accepted) or discarded before opening the workbook.
86
33
 
87
- book = Book.open('path/workbook.xls', :if_obstructed => :forget)
34
+ book1 = Book.open('workbook.xls') # user
35
+ ...
36
+ book2 = Book.open('workbook.xls', :if_unsaved => accept) # script
88
37
 
89
- === Closing a workbook.
38
+ Similarly, if the user has opened a workbook that has the same name but a different path, the conflict is solved via options.
90
39
 
91
- book.close
40
+ book1 = Book.open('path1/workbook.xls')
41
+ ...
42
+ book2 = Book.open('workbook.xls', :if_obstructed => :forget)
92
43
 
93
- This method has the option +:if_unsaved+. For example, if you want to close the workbook and save its changes before, you can use
44
+ Another feature that RobustExcelOle povides is reopening workbooks after closing them. A workbook is opened by default in the Excel instance where it was open before most recently. If this Excel instance is damaged or closed, then RobustExcelIle controls via options whether the workbook is opened in the current (active) Excel instance, a new or a given Excel instance, e.g.
94
45
 
95
- book.close(:if_unsaved => :save)
46
+ book1 = Book.open('workbook.xls', :default => {:excel => :new})
96
47
 
97
- === Reopening a workbook.
48
+ Moreover, RobustExcelOle allows unobtrusively reading and modifying workbooks, i.e. accessing workbooks without changing their "status". The status comprises whether the workbook is open or closed, saved or unsaved, read-only or writable, visible or invisible, calculation mode is manual or automatic, and checking compatibility is done or not done.
98
49
 
99
- A special feature of RobustExcelOle is that it allows to reopen workbooks after closing them.
50
+ Book.for_modifying('workbook.xls') do |book|
51
+ ...
52
+ end
100
53
 
101
- book = Book.open('workbook.xls')
102
- book.close
103
- book.reopen
54
+ Book.for_reading('workbook.xls') do |book|
55
+ ...
56
+ end
104
57
 
105
58
  === The Book objects and transperence identity
106
59
 
@@ -108,311 +61,196 @@ An Excel file (or workbook) is represented by a Book object. A Book object is de
108
61
  Identity transparence means that the same Book objects refer to the same Excel files, and vice versa.
109
62
  In other words, a Book objects is a proxy of an Excel file.
110
63
 
111
- === Promoting a workbook to a Book object
112
-
113
- A Book object can be created when giving an Excel workbook.
114
-
115
- book = Book.new(win32ole_workbook)
116
-
117
- === Saving a workbook.
118
-
119
- book.save
120
-
121
- Saving a workbook with a file name, is done by
122
-
123
- book.save_as('another_workbook.xls')
124
-
125
- When you want to overwrite a workbook, then use
126
-
127
- book.save_as('another_workbook.xls', :if_exists => :overwrite)
128
-
129
- If a workbook blocks the workbook that should be saved, then the former one can be saved and closed before.
130
-
131
- book.save_as('workbook.xls', :if_exists => :overwrite, :if_obstructed => :save)
132
-
133
- === Unobtrusively opening a workbook
64
+ === Opening and closing workbooks
134
65
 
135
- The method +unobtrusively+ enables reading and modifying a workbook, without changing its "status". This status comprises whether the workbook is open in some Excel instance or closed, whether it is saved or unsaved, and whether it is writable or not. Some options determine the Excel instance in which a closed workbook is opened.
136
-
137
- Book.unobtrusively('workbook.xls') do |book|
138
- # some modification
139
- end
140
-
141
- Likewise, the methods +for_reading+ and +for_modifying+ are methods for unobtrusively reading or modifying.
142
-
143
- === Retaining the saved-status
144
-
145
- This method ensures keeping the save status of the workbook
66
+ Let's have a look at an example. Suppose, we want to open a workbook.
146
67
 
147
68
  book = Book.open('workbook.xls')
148
- book.retain_saved do
149
- # some reading or modifying
150
- end
151
-
152
- === Checking whether the workbook is alive.
153
-
154
- This method finds out whether the workbook that is referenced by the Book object responds to methods.
155
-
156
- if book.alive? then sheet = book[0] end
157
69
 
158
- === Getting and setting the contents of a range in a workbook.
70
+ We could do this in a block as well. The semantics is similar to, e.g., +File.open+.
159
71
 
160
- You can get the contents of a range with
161
-
162
- book["name"]
163
- => "value"
164
-
165
- or
166
-
167
- book.nameval("name")
168
- => "value"
169
-
170
- You can set the contents of a range with
171
-
172
- book["name"] = "value"
173
-
174
- or
175
-
176
- book.set_nameval("name") = "value"
177
-
178
- === Bringing a workbook to the focus.
179
-
180
- If you want to make the workbook visible and available for keyboard inputs, use
181
-
182
- book.focus
183
-
184
- === Making the window of the workbook visible
72
+ Book.open('workbook.xls') do |book|
73
+ # do something with book
74
+ end
185
75
 
186
- You can make the window of the workbook invisible or visible:
76
+ Now let's make the workbook visible.
187
77
 
188
- book.visible = false
189
78
  book.visible = true
190
79
 
191
- === Making an Excel visible or invisible, and enable and disable DisplayAlerts.
192
-
193
- You can make an Excel instance visible with
80
+ We can do this in one step as well.
194
81
 
195
- book.excel.visible = true
196
-
197
- and enable DisplayAlerts using
198
-
199
- book.excel.displayalerts = true
82
+ book = Book.open('workbook.xls', :visible => true)
200
83
 
84
+ Now we want to open another workbook in a new Excel instance.
201
85
 
202
- === Accessing a worksheet.
86
+ book2 = Book.open('another_workbook.xls', :force => {:excel => :new}, :visible => true)
203
87
 
204
- You can access a worksheet by providing its number
88
+ Then we open a third workbook in the second Excel instance.
205
89
 
206
- sheet = book.sheet(1)
90
+ book3 = Book.open('different_workbook.xls', :force => {:excel => book2.excel})
207
91
 
208
- or its name
92
+ We close the second workbook.
209
93
 
210
- sheet = book.sheet('Sheet1')
94
+ book2.close
211
95
 
212
- You can get the first and last worksheet using
96
+ Reopening this workbook is done by
213
97
 
214
- sheet = book.first_sheet
98
+ book2.reopen
215
99
 
216
- and
100
+ === Modifying workbooks
217
101
 
218
- sheet = book.last_sheet
102
+ We can get the value of a named range.
219
103
 
220
- You can access all worksheet objects by using the methods Book#each.
104
+ book2["new"] # => foo
221
105
 
222
- book.each do |sheet|
223
- # do something with sheet
224
- end
106
+ or
225
107
 
226
- === Accessing cells, rows and columns.
108
+ book2.nameval("new") # => "foo"
227
109
 
228
- You can use Sheet#each, each_column, and each_row to access cells, rows and columns.
110
+ Now we assign a new value to this range.
229
111
 
230
- sheet.each do |cell|
231
- # do something with cell
232
- end
112
+ book2["new"] = "bar"
233
113
 
234
- sheet.each_row do |row|
235
- # do something with row
236
- end
114
+ or
237
115
 
238
- sheet.each_column do |column|
239
- # do something with column
240
- end
116
+ book2.set_nameval("new", "bar")
241
117
 
242
- === Accessing a cell.
118
+ Now we access the first worksheet by
243
119
 
244
- You can read a cell from a sheet object
120
+ sheet1 = book2.sheet(1)
245
121
 
246
- sheet[1, 1] => first cell (first row, first column).
122
+ or
247
123
 
248
- or a range object
124
+ sheet1 = book2.sheet('Sheet1')
249
125
 
250
- row_range[1] => first cell in row_range
251
- column_range[2] => second cell in column_range
126
+ or
127
+
128
+ sheet1 = book2.first_sheet
252
129
 
253
- You can read and write the value of a cell
130
+ We can read the first three cells of the first row
254
131
 
255
- cell = sheet[1,1]
256
- cell.Value => value of the cell.
257
- sheet[1,1] = "new_value"
132
+ sheet1.row_range(1, 1..3).values # => ["foo","workbook","sheet1"]
258
133
 
259
- === Accessing a range of a row or column.
134
+ and the third column
260
135
 
261
- You access a range of a row by giving the number of the row, and optionally, the range of the cell numbers.
136
+ sheet1.col_range(3).values # => ["sheet1", 2.0, 4.0]
262
137
 
263
- sheet.row_range(1) => first row
264
- sheet.row_range(1, 1..3 ) => first three cells of the first row
138
+ Then we read first cell
265
139
 
266
- Simarly you can access a range of a column.
140
+ sheet1[1,1].value # => "foo"
267
141
 
268
- sheet.col_range(3) => third column
269
- sheet.col_range(3, 1..2) => first two cells of the third column
142
+ or
270
143
 
271
- === Naming a cell
144
+ sheet1.row_range(1)[0].value # => "foo"
272
145
 
273
- You can (re-) name a cell range.
146
+ Then we modify it
274
147
 
275
- book.set_name(1,1,"name")
148
+ sheet1[1,1] = "hello"
276
149
 
277
- === Getting and setting the contents of a named range in a worksheet
150
+ We get the value of a range
278
151
 
279
- You get the value of a range by
152
+ sheet1.nameval("firstcell") # => "hello"
280
153
 
281
- sheet[name]
282
-
283
- or
154
+ and set the value
284
155
 
285
- sheet.nameval(name)
156
+ sheet1.set_nameval("firstcell", "foo")
286
157
 
287
- You set the value if a range using
158
+ We get the value of a range of a locally defined name.
288
159
 
289
- book[name] = value
160
+ sheet1.rangeval("firstcell") # => "foo"
290
161
 
291
162
  or
292
163
 
293
- book.set_nameval(name,value)
164
+ sheet1.rangeval("A1") # => "foo"
294
165
 
295
- === Getting and setting the contents of a named range in a Worksheet directly
166
+ Then we set the value of this range.
296
167
 
297
- You get the value of a range with
168
+ sheet1.set_rangeval("firstcell", "bar")
298
169
 
299
- sheet.rangeval(name)
170
+ We can copy the first worksheet, name it and add it before the third worksheet.
300
171
 
301
- and set the value of a range.
172
+ book2.add_or_copy_sheet(sheet1, :as => "copied_name, :before => book2.last_sheet)
302
173
 
303
- book.set_rangeval(name,value)
174
+ === Saving workbooks
304
175
 
305
- === Adding and copying a worksheet.
176
+ Simple save is done by
306
177
 
307
- You can add (append) an empty worksheet using, name it and specify its position.
178
+ book2.save
308
179
 
309
- book.add_empty_sheet(:as => 'new_name', :before => another_sheet)
180
+ We could save the workbook under a different name, and overwrite, if a file with the same name exists.
310
181
 
311
- You can copy a worksheet, add it, and specify its name and position.
182
+ book2.save_as('example_workbook.xls', :if_exists => :overwrite)
312
183
 
313
- book.copy_sheet(sheet, :as => 'new_name', :after => another_sheet)
184
+ Then we close this workbook.
314
185
 
315
- If you want to copy a worksheet, if a sheet is given, and add an empty worksheet, if no worksheet is given, then use
186
+ book2.close
316
187
 
317
- book.add_or_copy_sheet
188
+ Simple saving and closing can be also done in one step by
318
189
 
319
- === Creating and reusing an Excel instance.
190
+ book2.close(:if_unsaved => :save)
320
191
 
321
- If you want to start a new Excel, use
192
+ === Operating on Excel instances.
322
193
 
323
- excel1 = Excel.create
324
-
325
- or
194
+ Suppose we want to create an Excel object by connecting to the already running Excel instance.
326
195
 
327
- excel1 = Excel.new(:reuse => false)
328
-
329
- In case you want to reuse an already running Excel instance, write
330
-
331
- excel2 = Excel.current
196
+ excel1 = Excel.current
332
197
 
333
198
  or
334
199
 
335
- excel2 = Excel.new(:reuse => true)
336
-
337
- Further options specify the visibility, displayalerts, screen updating and calculation mode, e.g.
338
-
339
- excel1 = Excel.new(:reuse => false, :visible => true, :displayalerts => true, :calculation => :manual)
340
-
341
- You can also promote an Excel instance represented as WIN32OLE object to an Excel object.
342
-
343
- excel = Excel.new(win32ole_object)
344
-
345
- === Making all workbooks visible or invisible
346
-
347
- excel1.workbooks_visible true
200
+ excel1 = Excel.new(:reuse => true)
348
201
 
349
- === Bringing an Excel instance to the foreground
350
202
 
351
- excel1.focus
203
+ Now we want to start a new, visible Excel instance.
352
204
 
353
- === Closing an Excel
205
+ excel2 = Excel.create(:visible => true)
354
206
 
355
- excel.close
356
-
357
- === Closing all Excel instances
358
-
359
- Excel.close_all
207
+ or
360
208
 
361
- The option +:if_unsaved+ manages unsaved workbooks.
209
+ excel2 = Excel.new(:reuse => false, :visible => true)
362
210
 
363
- === Terminating all Excel processes
211
+ We open a workbook in this Excel instance.
364
212
 
365
- Excel.kill_all
213
+ book4 = Book.open('more_data/workbook', {:force => {:excel => excel2}})
366
214
 
367
- This method kills all Excel instances no matter whether they contain unsaved workbooks.
215
+ We can close Closing an Excel instance is dony by
368
216
 
369
- === Recreating an Excel instance
217
+ excel1.close
370
218
 
371
219
  Closed Excel instances can be reopened.
372
220
 
373
- excel.recreate(:reopen_workbooks => true, :visible => true, :displayalerts => true)
374
-
375
- === Providing Excel instances
376
-
377
- Providing all Excel instances (opened via RobustExcelOle) as objects of the class Excel
378
-
379
- Excel.excel_processes
380
-
381
- === Setting Calculation mode.
221
+ excel1.recreate(:reopen_workbooks => true, :visible => true)
382
222
 
383
- The calculation mode of an Excel instance can be set to manual or automatic.
223
+ We can get the value of a range in an Excel instance by
384
224
 
385
- excel.calculation = :manual
386
-
387
- You can do it in a block:
225
+ excel2["firstcell"] => "foo"
226
+
227
+ or
388
228
 
389
- excel.with_calculation(:manual) do
390
- # do something
391
- end
229
+ excel2.nameval("firstcell") = "foo"
392
230
 
393
- === Getting and setting the contents of a named range in an Excel application
231
+ and set the value of this range by using
394
232
 
395
- You can get the value of a range by using
233
+ excel2["firstcell"] = "bar"
396
234
 
397
- excel[name]
398
-
399
235
  or
400
236
 
401
- excel.nameval(name)
237
+ excel2.set_nameval("firstcell", "bar")
402
238
 
403
- and set the value of a range by using
239
+ We get and set the value of a range with a locally defined named by
404
240
 
405
- excel[name] = value
241
+ excel2.rangeval("firstcell")
406
242
 
407
- or
243
+ and set its value by
408
244
 
409
- excel.set_nameval(name,value)
245
+ excel2.set_rangeval("firstcell, "bar")
410
246
 
411
- === Getting and setting the contents of a named range in an Excel instance
247
+ Closing all Excel instances ist done by
412
248
 
413
- excel.rangeval(name)
249
+ Excel.close_all(:if_unsaved => :forget)
414
250
 
415
- excel.set_rangeval(name,value)
251
+ Hard terminating all Excel processes is done by
252
+
253
+ Excel.kill_all
416
254
 
417
255
  === More details
418
256