robust_excel_ole 0.3.4 → 0.3.5

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 (49) hide show
  1. data/README.rdoc +73 -26
  2. data/README_detail.rdoc +92 -27
  3. data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
  4. data/examples/edit_sheets/example_concating.rb +12 -12
  5. data/examples/edit_sheets/example_copying.rb +47 -0
  6. data/examples/edit_sheets/example_expanding.rb +17 -26
  7. data/examples/edit_sheets/example_naming.rb +13 -10
  8. data/examples/edit_sheets/example_ranges.rb +2 -2
  9. data/examples/edit_sheets/example_saving.rb +8 -14
  10. data/examples/open_save_close/example_control_to_excel.rb +1 -1
  11. data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
  12. data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
  13. data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
  14. data/examples/open_save_close/example_if_unsaved_forget.rb +4 -4
  15. data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
  16. data/examples/open_save_close/example_read_only.rb +1 -1
  17. data/examples/open_save_close/example_rename_cells.rb +1 -13
  18. data/examples/open_save_close/example_simple.rb +1 -1
  19. data/examples/open_save_close/example_unobtrusively.rb +3 -3
  20. data/lib/robust_excel_ole.rb +81 -2
  21. data/lib/robust_excel_ole/book.rb +171 -118
  22. data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
  23. data/lib/robust_excel_ole/excel.rb +153 -24
  24. data/lib/robust_excel_ole/range.rb +2 -2
  25. data/lib/robust_excel_ole/sheet.rb +84 -35
  26. data/lib/robust_excel_ole/version.rb +1 -1
  27. data/reo.bat +3 -0
  28. data/spec/book_close_spec.rb +179 -0
  29. data/spec/book_misc_spec.rb +365 -0
  30. data/spec/book_open_spec.rb +793 -0
  31. data/spec/book_save_spec.rb +257 -0
  32. data/spec/book_sheet_spec.rb +160 -0
  33. data/spec/book_spec.rb +145 -1533
  34. data/spec/book_subclass_spec.rb +50 -0
  35. data/spec/book_unobtr_spec.rb +950 -0
  36. data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
  37. data/spec/cell_spec.rb +6 -6
  38. data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
  39. data/spec/data/different_workbook.xls +0 -0
  40. data/spec/data/workbook.xls +0 -0
  41. data/spec/data/workbook.xlsm +0 -0
  42. data/spec/data/workbook.xlsx +0 -0
  43. data/spec/data/workbook_linked.xlsm +0 -0
  44. data/spec/data/workbook_linked_sub.xlsm +0 -0
  45. data/spec/excel_spec.rb +204 -5
  46. data/spec/range_spec.rb +6 -6
  47. data/spec/sheet_spec.rb +122 -34
  48. metadata +18 -8
  49. data/spec/data/workbook_connected_sub.xlsm +0 -0
@@ -1,4 +1,3 @@
1
-
2
1
  # -*- coding: utf-8 -*-
3
2
 
4
3
  require 'weakref'
@@ -11,12 +10,14 @@ module RobustExcelOle
11
10
  attr_accessor :stored_filename
12
11
  attr_accessor :options
13
12
 
13
+
14
14
  DEFAULT_OPEN_OPTS = {
15
15
  :excel => :reuse,
16
16
  :default_excel => :reuse,
17
- :if_locked => :readonly,
17
+ :if_lockraiseed => :readonly,
18
18
  :if_unsaved => :raise,
19
19
  :if_obstructed => :raise,
20
+ :if_absent => :raise,
20
21
  :read_only => false
21
22
  }
22
23
 
@@ -51,8 +52,9 @@ module RobustExcelOle
51
52
  # :close_if_saved -> close the old book and open the new book, if the old book is saved,
52
53
  # otherwise raise an exception.
53
54
  # :new_excel -> open the new book in a new Excel
54
- # :if_absent :create (default) -> creates a new Excel file, if it does not exists
55
- # :raise -> raises an exception , if the file does not exists
55
+ # :if_absent :raise (default) -> raises an exception , if the file does not exists
56
+ # :create -> creates a new Excel file, if it does not exists
57
+ #
56
58
  # :read_only open in read-only mode (default: false)
57
59
  # :displayalerts enable DisplayAlerts in Excel (default: false)
58
60
  # :visible make visible in Excel (default: false)
@@ -63,19 +65,18 @@ module RobustExcelOle
63
65
  book = nil
64
66
  if (not (current_options[:force_excel] == :new && (not current_options[:if_locked] == :take_writable)))
65
67
  # if readonly is true, then prefer a book that is given in force_excel if this option is set
66
- book = book_store.fetch(file,
68
+ book = bookstore.fetch(file,
67
69
  :prefer_writable => (not current_options[:read_only]),
68
- :prefer_excel => (current_options[:read_only] ? Book.excel(current_options[:force_excel]) : nil)) rescue nil
70
+ :prefer_excel => (current_options[:read_only] ? current_options[:force_excel].excel : nil)) rescue nil
69
71
  if book
70
- #if (((not current_options[:force_excel]) || (current_options[:force_excel].excel == book.excel)) &&
71
- if (((not current_options[:force_excel]) || (Book.excel(current_options[:force_excel]) == book.excel)) &&
72
+ if (((not current_options[:force_excel]) || (current_options[:force_excel].excel == book.excel)) &&
72
73
  (not (book.alive? && (not book.saved) && (not current_options[:if_unsaved] == :accept))))
73
74
  book.options = DEFAULT_OPEN_OPTS.merge(opts)
74
75
  book.get_excel unless book.excel.alive?
75
76
  # if the book is opened as readonly and should be opened as writable, then close it and open the book with the new readonly mode
76
77
  book.close if (book.alive? && (not book.writable) && (not current_options[:read_only]))
77
78
  # reopen the book
78
- book.get_workbook unless book.alive?
79
+ book.get_workbook(file) unless book.alive?
79
80
  return book
80
81
  end
81
82
  end
@@ -86,11 +87,10 @@ module RobustExcelOle
86
87
  end
87
88
 
88
89
  def initialize(file, opts={ }, &block)
89
- @options = DEFAULT_OPEN_OPTS.merge(opts)
90
- @file = file
90
+ @options = DEFAULT_OPEN_OPTS.merge(opts)
91
91
  get_excel
92
- get_workbook
93
- book_store.store(self)
92
+ get_workbook file
93
+ bookstore.store(self)
94
94
  if block
95
95
  begin
96
96
  yield self
@@ -99,20 +99,33 @@ module RobustExcelOle
99
99
  end
100
100
  end
101
101
  end
102
+
103
+ def self.excel_class
104
+ @excel_class ||= begin
105
+ module_name = self.parent_name
106
+ "#{module_name}::Excel".constantize
107
+ rescue NameError => e
108
+ Excel
109
+ end
110
+ end
111
+
112
+ def excel_class
113
+ self.class.excel_class
114
+ end
115
+
102
116
 
103
117
  def get_excel
104
118
  if @options[:excel] == :reuse
105
- @excel = Excel.new(:reuse => true)
119
+ @excel = excel_class.new(:reuse => true)
106
120
  end
107
121
  @excel_options = nil
108
122
  if (not @excel)
109
123
  if @options[:excel] == :new
110
124
  @excel_options = {:displayalerts => false, :visible => false}.merge(@options)
111
125
  @excel_options[:reuse] = false
112
- @excel = Excel.new(@excel_options)
126
+ @excel = excel_class.new(@excel_options)
113
127
  else
114
- @excel = @options[:excel]
115
- @excel = Book.excel(@options[:excel])
128
+ @excel = @options[:excel].excel
116
129
  end
117
130
  end
118
131
  # if :excel => :new or (:excel => :reuse but could not reuse)
@@ -123,39 +136,46 @@ module RobustExcelOle
123
136
  end
124
137
  end
125
138
 
126
- def get_workbook
127
- raise ExcelErrorOpen, "file #{@file} not found" if ((not File.exist?(@file)) && @options[:if_absent] == :raise)
128
- @workbook = @excel.Workbooks.Item(File.basename(@file)) rescue nil
139
+ def get_workbook file
140
+ file = @stored_filename ? @stored_filename : file
141
+ unless File.exist?(file)
142
+ if @options[:if_absent] == :create
143
+ @workbook = excel_class.current.generate_workbook(file)
144
+ else
145
+ raise ExcelErrorOpen, "file #{file} not found"
146
+ end
147
+ end
148
+ @workbook = @excel.Workbooks.Item(File.basename(file)) rescue nil
129
149
  if @workbook then
130
- obstructed_by_other_book = (File.basename(@file) == File.basename(@workbook.Fullname)) &&
131
- (not (RobustExcelOle::absolute_path(@file) == @workbook.Fullname))
150
+ obstructed_by_other_book = (File.basename(file) == File.basename(@workbook.Fullname)) &&
151
+ (not (RobustExcelOle::absolute_path(file) == @workbook.Fullname))
132
152
  # if book is obstructed by a book with same name and different path
133
153
  if obstructed_by_other_book then
134
154
  case @options[:if_obstructed]
135
155
  when :raise
136
- raise ExcelErrorOpen, "blocked by a book with the same name in a different path: #{File.basename(@file)}"
156
+ raise ExcelErrorOpen, "blocked by a book with the same name in a different path: #{File.basename(file)}"
137
157
  when :forget
138
158
  @workbook.Close
139
159
  @workbook = nil
140
- open_or_create_workbook
160
+ open_or_create_workbook file
141
161
  when :save
142
162
  save unless @workbook.Saved
143
163
  @workbook.Close
144
164
  @workbook = nil
145
- open_or_create_workbook
165
+ open_or_create_workbook file
146
166
  when :close_if_saved
147
167
  if (not @workbook.Saved) then
148
- raise ExcelErrorOpen, "book with the same name in a different path is unsaved: #{File.basename(@file)}"
168
+ raise ExcelErrorOpen, "book with the same name in a different path is unsaved: #{File.basename(file)}"
149
169
  else
150
170
  @workbook.Close
151
171
  @workbook = nil
152
- open_or_create_workbook
172
+ open_or_create_workbook file
153
173
  end
154
174
  when :new_excel
155
175
  @excel_options = {:displayalerts => false, :visible => false}.merge(@options)
156
176
  @excel_options[:reuse] = false
157
- @excel = Excel.new(@excel_options)
158
- open_or_create_workbook
177
+ @excel = excel_class.new(@excel_options)
178
+ open_or_create_workbook file
159
179
  else
160
180
  raise ExcelErrorOpen, ":if_obstructed: invalid option: #{@options[:if_obstructed]}"
161
181
  end
@@ -164,22 +184,22 @@ module RobustExcelOle
164
184
  if (not @workbook.Saved) then
165
185
  case @options[:if_unsaved]
166
186
  when :raise
167
- raise ExcelErrorOpen, "book is already open but not saved (#{File.basename(@file)})"
187
+ raise ExcelErrorOpen, "book is already open but not saved (#{File.basename(file)})"
168
188
  when :forget
169
189
  @workbook.Close
170
190
  @workbook = nil
171
- open_or_create_workbook
191
+ open_or_create_workbook file
172
192
  when :accept
173
193
  # do nothing
174
194
  when :alert
175
195
  @excel.with_displayalerts true do
176
- open_or_create_workbook
196
+ open_or_create_workbook file
177
197
  end
178
198
  when :new_excel
179
199
  @excel_options = {:displayalerts => false, :visible => false}.merge(@options)
180
200
  @excel_options[:reuse] = false
181
- @excel = Excel.new(@excel_options)
182
- open_or_create_workbook
201
+ @excel = excel_class.new(@excel_options)
202
+ open_or_create_workbook file
183
203
  else
184
204
  raise ExcelErrorOpen, ":if_unsaved: invalid option: #{@options[:if_unsaved]}"
185
205
  end
@@ -187,23 +207,24 @@ module RobustExcelOle
187
207
  end
188
208
  else
189
209
  # book is not open
190
- open_or_create_workbook
210
+ open_or_create_workbook file
191
211
  end
192
212
  end
193
213
 
194
- def open_or_create_workbook
195
- if (not File.exist?(@file))
196
- @workbook = Excel.current.generate_workbook(@file)
197
- return
198
- end
214
+ def open_or_create_workbook file
199
215
  if ((not @workbook) || (@options[:if_unsaved] == :alert) || @options[:if_obstructed]) then
200
216
  begin
201
- filename = RobustExcelOle::absolute_path(@file)
202
- workbooks = @excel.Workbooks
217
+ filename = RobustExcelOle::absolute_path(file)
218
+ begin
219
+ workbooks = @excel.Workbooks
220
+ rescue RuntimeError => msg
221
+ puts "RuntimeError: #{msg.message}"
222
+ raise ExcelErrorOpen, "Excel instance not alive or damaged" if msg.message =~ /failed to get Dispatch Interface/
223
+ end
203
224
  workbooks.Open(filename,{ 'ReadOnly' => @options[:read_only] })
204
225
  rescue WIN32OLERuntimeError => msg
205
- puts "msg: #{msg}"
206
- raise ExcelErrorOpen, "open: user canceled or open error" if msg.message =~ /OLE error code:800A03EC/
226
+ puts "WIN32OLERuntimeError: #{msg.message}"
227
+ raise ExcelErrorOpen, "open: user canceled or open error" if msg.message =~ /800A03EC/
207
228
  end
208
229
  begin
209
230
  # workaround for bug in Excel 2010: workbook.Open does not always return
@@ -215,20 +236,6 @@ module RobustExcelOle
215
236
  end
216
237
  end
217
238
 
218
- private
219
-
220
- # return an Excel.
221
- # return the given instance if it is an Excel and alive. If the given instance is a Book then take the Excel of the Book
222
- def self.excel(instance)
223
- raise ExcelErrorOpen, "provided instance is neither an Excel nor a Book: #{instance}" \
224
- unless instance.is_a?(Excel) || instance.is_a?(Book)
225
- excel = instance.is_a?(Book) ? instance.excel : instance
226
- raise ExcelErrorOpen, "provided Excel instance is not alive" unless excel.alive?
227
- excel
228
- end
229
-
230
- public
231
-
232
239
  # closes the book, if it is alive
233
240
  #
234
241
  # options:
@@ -269,91 +276,113 @@ module RobustExcelOle
269
276
 
270
277
  public
271
278
 
279
+ def self.for_reading(*args, &block)
280
+ args = args.dup
281
+ opts = args.last.is_a?(Hash) ? args.pop : {}
282
+ opts = {:read_only => true}.merge(opts)
283
+ args.push opts
284
+ unobtrusively(*args, &block)
285
+ end
286
+
287
+ def self.for_modifying(*args, &block)
288
+ args = args.dup
289
+ opts = args.last.is_a?(Hash) ? args.pop : {}
290
+ opts = {:read_only => false}.merge(opts)
291
+ args.push opts
292
+ unobtrusively(*args, &block)
293
+ end
294
+
272
295
  # modify a book such that its state (open/close, saved/unsaved, readonly/writable) remains unchanged.
273
- # options:
274
- # :if_closed : :hidden (default) : open closed books in one separate Excel instance that is not visible and has no displayaslerts
275
- # :reuse : open closed books in the Excel instance of the book, if it exists, reuse another Excel, otherwise
276
- # <excel-instance> : open closed books in the given Excel instance
296
+ # options:
297
+ # :reuse (default) : open closed books in the Excel instance of the book, if it exists, reuse another Excel, otherwise
298
+ # :hidden : open closed books in one separate Excel instance that is not visible and has no displayaslerts
299
+ # <excel-instance> : open closed books in the given Excel instance
277
300
  # :read_only: Open the book unobtrusively for reading only (default: false)
278
- # :use_readonly_excel: if the book is opened only as ReadOnly and shall be modified, then
279
- # true: close it and open it as writable in the excel instance where it was open so far
280
- # false (default) open it as writable in another running excel instance, if it exists,
281
- # otherwise open in a new excel instance.
301
+ # :readonly_excel: if the book is opened only as ReadOnly and shall be modified, then
302
+ # true: close it and open it as writable in the excel instance where it was open so far
303
+ # false (default) open it as writable in another running excel instance, if it exists,
304
+ # otherwise open in a new excel instance.
282
305
  # :keep_open: let the book open after unobtrusively opening (default: false)
283
- def self.unobtrusively(file, opts = { })
306
+ def self.unobtrusively(file, if_closed = nil, opts = { }, &block)
307
+ if if_closed.is_a? Hash
308
+ opts = if_closed
309
+ if_closed = nil
310
+ end
311
+ if_closed = :reuse unless if_closed
284
312
  options = {
285
- :if_closed => :hidden,
286
313
  :read_only => false,
287
- :use_readonly_excel => false,
314
+ :readonly_excel => false,
288
315
  :keep_open => false,
289
316
  }.merge(opts)
290
- book = book_store.fetch(file, :prefer_writable => (not options[:read_only]))
317
+ book = bookstore.fetch(file, :prefer_writable => (not options[:read_only]))
291
318
  was_not_alive_or_nil = book.nil? || (not book.alive?)
292
319
  was_saved = was_not_alive_or_nil ? true : book.saved
293
320
  was_writable = book.writable unless was_not_alive_or_nil
294
321
  begin
295
322
  book =
296
323
  if was_not_alive_or_nil
297
- case options[:if_closed]
298
- when :hidden
299
- open(file, :force_excel => book_store.hidden_excel)
324
+ case if_closed
300
325
  when :reuse
301
- open(file)
326
+ open(file, :read_only => options[:read_only])
327
+ when :hidden
328
+ open(file, :force_excel => bookstore.hidden_excel, :read_only => options[:read_only])
302
329
  else
303
- open(file, :force_excel => options[:if_closed])
330
+ open(file, :force_excel => if_closed, :read_only => options[:read_only])
304
331
  end
305
332
  else
306
333
  if was_writable || options[:read_only]
307
334
  book
308
335
  else
309
- options[:use_readonly_excel] ? open(file, :force_excel => book.excel) : open(file, :force_excel => :new)
336
+ options[:readonly_excel] ? open(file, :force_excel => book.excel, :read_only => options[:read_only]) :
337
+ open(file, :force_excel => :new, :read_only => options[:read_only])
310
338
  end
311
339
  end
312
340
  yield book
313
341
  ensure
314
- book.save if (was_not_alive_or_nil || was_saved || ((not was_writable) && (not options[:read_only]))) && (book && (not book.saved))
342
+ book.save if (was_not_alive_or_nil || was_saved || ((not options[:read_only]) && (not was_writable))) && (not options[:read_only]) && book && (not book.saved)
315
343
  # book was open, readonly and shoud be modified
316
- if (not was_not_alive_or_nil) && (not options[:read_only]) && (not was_writable) && options[:use_readonly_excel]
344
+ if (not was_not_alive_or_nil) && (not options[:read_only]) && (not was_writable) && options[:readonly_excel]
317
345
  open(file, :force_excel => book.excel, :if_obstructed => :new_excel, :read_only => true)
318
346
  end
319
347
  book.close if (was_not_alive_or_nil && (not opts[:keep_open]) && book)
320
348
  end
321
349
  end
322
350
 
351
+ def reopen
352
+ self.class.open(self.stored_filename)
353
+ end
354
+
323
355
  # rename a range
324
356
  def rename_range(name,new_name)
325
357
  begin
326
- p "name: #{name}"
327
- p "new_name: #{new_name}"
328
358
  item = self.Names.Item(name)
329
- p "nil" if item.nil?
330
359
  rescue WIN32OLERuntimeError
331
- raise ExcelErrorRename, "name #{name} not in #{File.basename(self.stored_filename)}"
360
+ raise ExcelError, "name #{name} not in #{File.basename(self.stored_filename)}"
332
361
  end
333
362
  begin
334
363
  item.Name = new_name
335
364
  rescue WIN32OLERuntimeError
336
- raise ExcelErrorRename, "name error in #{File.basename(self.stored_filename)}"
365
+ raise ExcelError, "name error in #{File.basename(self.stored_filename)}"
337
366
  end
338
367
  end
339
368
 
340
369
  # returns the contents of a range with given name
341
- def nvalue(name)
370
+ # if no contents could returned, then return default value, if a default value was provided
371
+ # raise an error, otherwise
372
+ def nvalue(name, opts = {:default => nil})
342
373
  begin
343
374
  item = self.Names.Item(name)
344
375
  rescue WIN32OLERuntimeError
345
- raise ExcelErrorNValue, "name #{name} not in #{File.basename(self.stored_filename)}"
376
+ return opts[:default] if opts[:default]
377
+ raise ExcelErrorNValue, "name #{name} not in #{File.basename(self.stored_filename)}"
346
378
  end
347
379
  begin
348
- referstorange = item.RefersToRange
349
- rescue WIN32OLERuntimeError
350
- raise ExcelErrorNValue, "range error in #{File.basename(self.stored_filename)}"
351
- end
352
- begin
353
- referstorange.Value
354
- rescue WIN32OLERuntimeError
355
- raise ExcelErrorNValue, "value error in #{File.basename(self.stored_filename)}"
380
+ value = item.RefersToRange.Value
381
+ rescue WIN32OLERuntimeError
382
+ return opts[:default] if opts[:default]
383
+ raise ExcelErrorNValue, "RefersToRange error of name #{name} in #{File.basename(self.stored_filename)}"
356
384
  end
385
+ value
357
386
  end
358
387
 
359
388
  # set the contents of a range with given name
@@ -364,14 +393,19 @@ module RobustExcelOle
364
393
  raise ExcelErrorNValue, "name #{name} not in #{File.basename(self.stored_filename)}"
365
394
  end
366
395
  begin
367
- referstorange = item.RefersToRange
396
+ item.RefersToRange.Value = value
368
397
  rescue WIN32OLERuntimeError
369
- raise ExcelErrorNValue, "range error in #{File.basename(self.stored_filename)}"
398
+ raise ExcelErrorNValue, "RefersToRange error of name #{name} in #{File.basename(self.stored_filename)}"
370
399
  end
400
+ end
401
+
402
+ def activate
403
+ @excel.visible = true
371
404
  begin
372
- referstorange.Value = value
405
+ self.Activate
406
+ self.ActiveSheet.Activate
373
407
  rescue WIN32OLERuntimeError
374
- raise ExcelErrorNValue, "value error in #{File.basename(self.stored_filename)}"
408
+ raise ExcelError, "cannot activate"
375
409
  end
376
410
  end
377
411
 
@@ -474,7 +508,7 @@ module RobustExcelOle
474
508
  when '.xlsm': RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
475
509
  end
476
510
  @workbook.SaveAs(RobustExcelOle::absolute_path(file), file_format)
477
- book_store.store(self)
511
+ bookstore.store(self)
478
512
  rescue WIN32OLERuntimeError => msg
479
513
  if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
480
514
  if @opts[:if_exists] == :alert then
@@ -491,9 +525,24 @@ module RobustExcelOle
491
525
 
492
526
  public
493
527
 
494
- def [] sheet
495
- sheet += 1 if sheet.is_a? Numeric
496
- RobustExcelOle::Sheet.new(@workbook.Worksheets.Item(sheet))
528
+ # returns a sheet, if a name of a sheet or a number is given
529
+ # returns the value of the range, if a global name of a range in the book is given
530
+ def [] name
531
+ name += 1 if name.is_a? Numeric
532
+ begin
533
+ RobustExcelOle::Sheet.new(@workbook.Worksheets.Item(name))
534
+ rescue WIN32OLERuntimeError => msg
535
+ if msg.message =~ /8002000B/
536
+ nvalue(name)
537
+ else
538
+ raise ExcelError, "could neither return a sheet nor a value of a range when giving the name #{name}"
539
+ end
540
+ end
541
+ end
542
+
543
+ # set the value of a range given its name
544
+ def []= (name, value)
545
+ set_nvalue(name,value)
497
546
  end
498
547
 
499
548
  def each
@@ -507,35 +556,40 @@ module RobustExcelOle
507
556
  opts = sheet
508
557
  sheet = nil
509
558
  end
510
-
511
559
  new_sheet_name = opts.delete(:as)
512
-
513
560
  ws = @workbook.Worksheets
514
- after_or_before, base_sheet = opts.to_a.first ||
515
- [:after, Sheet.new(ws.Item(ws.Count))]
516
- base_sheet = base_sheet.sheet
561
+ after_or_before, base_sheet = opts.to_a.first || [:after, Sheet.new(ws.Item(ws.Count))]
562
+ base_sheet = base_sheet.worksheet
517
563
  sheet ? sheet.Copy({ after_or_before.to_s => base_sheet }) : @workbook.WorkSheets.Add({ after_or_before.to_s => base_sheet })
518
564
  new_sheet = RobustExcelOle::Sheet.new(@excel.Activesheet)
519
565
  begin
520
566
  new_sheet.name = new_sheet_name if new_sheet_name
521
567
  rescue WIN32OLERuntimeError => msg
522
- if msg.message =~ /OLE error code:800A03EC/
568
+ if msg.message =~ /800A03EC/
523
569
  raise ExcelErrorSheet, "sheet name already exists"
570
+ else
571
+ puts "#{msg.message}"
572
+ raise ExcelErrorSheetUnknown
524
573
  end
525
574
  end
526
575
  new_sheet
527
- end
576
+ end
528
577
 
529
- def add_name name
578
+ def self.bookstore
579
+ @@bookstore ||= Bookstore.new
530
580
  end
531
581
 
532
- def self.book_store
533
- @@bookstore ||= BookStore.new
582
+ def bookstore
583
+ self.class.bookstore
584
+ end
585
+
586
+ def to_s
587
+ "<#BOOK:" + "#{"not alive " unless alive?}" + "#{File.basename(@stored_filename)}" + " #{@workbook} #{@excel}" + ">"
534
588
  end
535
589
 
536
- def book_store
537
- self.class.book_store
538
- end
590
+ def inspect
591
+ self.to_s
592
+ end
539
593
 
540
594
  private
541
595
 
@@ -577,10 +631,7 @@ public
577
631
  class ExcelErrorSaveUnknown < ExcelErrorSave # :nodoc: #
578
632
  end
579
633
 
580
- class ExcelErrorRename < WIN32OLERuntimeError # :nodoc: #
581
- end
582
-
583
- class ExcelErrorNValue < WIN32OLERuntimeError # :nodoc: #
634
+ class ExcelErrorNValue < ExcelError # :nodoc: #
584
635
  end
585
636
 
586
637
  class ExcelUserCanceled < RuntimeError # :nodoc: #
@@ -589,4 +640,6 @@ public
589
640
  class ExcelErrorSheet < ExcelError # :nodoc: #
590
641
  end
591
642
 
643
+ class ExcelErrorSheetUnknown < ExcelErrorSheet # :nodoc: #
644
+ end
592
645
  end