robust_excel_ole 1.4 → 1.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.
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "1.4"
2
+ VERSION = "1.5"
3
3
  end
@@ -11,27 +11,27 @@ module RobustExcelOle
11
11
  attr_accessor :excel
12
12
  attr_accessor :ole_workbook
13
13
  attr_accessor :stored_filename
14
- attr_accessor :options
14
+ attr_accessor :options
15
15
  attr_accessor :modified_cells
16
16
  attr_reader :workbook
17
17
 
18
18
  alias ole_object ole_workbook
19
19
 
20
- DEFAULT_OPEN_OPTS = {
20
+ DEFAULT_OPEN_OPTS = {
21
21
  :default => {:excel => :current},
22
- :force => {},
22
+ :force => {},
23
23
  :if_unsaved => :raise,
24
24
  :if_obstructed => :raise,
25
25
  :if_absent => :raise,
26
26
  :read_only => false,
27
- :check_compatibility => false,
27
+ :check_compatibility => false,
28
28
  :update_links => :never
29
- }
30
-
31
- ABBREVIATIONS = [[:default,:d], [:force, :f], [:excel, :e], [:visible, :v]]
29
+ }.freeze
30
+
31
+ ABBREVIATIONS = [[:default,:d], [:force, :f], [:excel, :e], [:visible, :v]].freeze
32
32
 
33
33
  class << self
34
-
34
+
35
35
  # opens a workbook.
36
36
  # @param [String] file the file name
37
37
  # @param [Hash] opts the options
@@ -42,66 +42,66 @@ module RobustExcelOle
42
42
  # @option opts [Symbol] :if_absent :raise (default) or :create
43
43
  # @option opts [Boolean] :read_only true (default) or false
44
44
  # @option opts [Boolean] :update_links :never (default), :always, :alert
45
- # @option opts [Boolean] :calculation :manual, :automatic, or nil (default)
46
- # options:
45
+ # @option opts [Boolean] :calculation :manual, :automatic, or nil (default)
46
+ # options:
47
47
  # :default : if the workbook was already open before, then use (unchange) its properties,
48
48
  # otherwise, i.e. if the workbook cannot be reopened, use the properties stated in :default
49
- # :force : no matter whether the workbook was already open before, use the properties stated in :force
49
+ # :force : no matter whether the workbook was already open before, use the properties stated in :force
50
50
  # :default and :force contain: :excel, :visible
51
- # :excel :current (or :active or :reuse)
51
+ # :excel :current (or :active or :reuse)
52
52
  # -> connects to a running (the first opened) Excel instance,
53
53
  # excluding the hidden Excel instance, if it exists,
54
54
  # otherwise opens in a new Excel instance.
55
- # :new -> opens in a new Excel instance
55
+ # :new -> opens in a new Excel instance
56
56
  # <excel-instance> -> opens in the given Excel instance
57
57
  # :visible true, false, or nil (default)
58
58
  # alternatives: :default_excel, :force_excel, :visible, :d, :f, :e, :v
59
59
  # :if_unsaved if an unsaved workbook with the same name is open, then
60
60
  # :raise -> raises an exception
61
- # :forget -> close the unsaved workbook, open the new workbook
62
- # :accept -> lets the unsaved workbook open
61
+ # :forget -> close the unsaved workbook, open the new workbook
62
+ # :accept -> lets the unsaved workbook open
63
63
  # :alert or :excel -> gives control to Excel
64
64
  # :new_excel -> opens the new workbook in a new Excel instance
65
65
  # :if_obstructed if a workbook with the same name in a different path is open, then
66
- # :raise -> raises an exception
66
+ # :raise -> raises an exception
67
67
  # :forget -> closes the old workbook, open the new workbook
68
68
  # :save -> saves the old workbook, close it, open the new workbook
69
69
  # :close_if_saved -> closes the old workbook and open the new workbook, if the old workbook is saved,
70
70
  # otherwise raises an exception.
71
- # :new_excel -> opens the new workbook in a new Excel instance
71
+ # :new_excel -> opens the new workbook in a new Excel instance
72
72
  # :if_absent :raise -> raises an exception , if the file does not exists
73
- # :create -> creates a new Excel file, if it does not exists
74
- # :read_only true -> opens in read-only mode
73
+ # :create -> creates a new Excel file, if it does not exists
74
+ # :read_only true -> opens in read-only mode
75
75
  # :visible true -> makes the workbook visible
76
76
  # :check_compatibility true -> check compatibility when saving
77
77
  # :update_links true -> user is being asked how to update links, false -> links are never updated
78
78
  # @return [Workbook] a representation of a workbook
79
- def open(file, opts={ }, &block)
79
+ def open(file, opts = { }, &block)
80
80
  options = @options = process_options(opts)
81
81
  book = nil
82
- if (not (options[:force][:excel] == :new) and not (options[:force][:excel] == :reserved_new))
82
+ if (options[:force][:excel] != :new) && (options[:force][:excel] != :reserved_new)
83
83
  # if readonly is true, then prefer a book that is given in force_excel if this option is set
84
84
  forced_excel = if options[:force][:excel]
85
- options[:force][:excel] == :current ? excel_class.new(:reuse => true) : excel_of(options[:force][:excel])
85
+ options[:force][:excel] == :current ? excel_class.new(:reuse => true) : excel_of(options[:force][:excel])
86
86
  end
87
- book = bookstore.fetch(file,
88
- :prefer_writable => (not options[:read_only]),
87
+ book = bookstore.fetch(file,
88
+ :prefer_writable => !(options[:read_only]),
89
89
  :prefer_excel => (options[:read_only] ? forced_excel : nil)) rescue nil
90
90
  if book
91
- #if forced_excel != book.excel &&
91
+ # if forced_excel != book.excel &&
92
92
  # (not (book.alive? && (not book.saved) && (not options[:if_unsaved] == :accept)))
93
- if (((not options[:force][:excel]) || (forced_excel == book.excel)) &&
94
- (not (book.alive? && (not book.saved) && (not options[:if_unsaved] == :accept))))
93
+ if (!(options[:force][:excel]) || (forced_excel == book.excel)) &&
94
+ !(book.alive? && !book.saved && (options[:if_unsaved] != :accept))
95
95
  book.options = options
96
96
  book.ensure_excel(options) # unless book.excel.alive?
97
97
  # if the ReadOnly status shall be changed, save, close and reopen it
98
- if book.alive? and (((not book.writable) and (not options[:read_only])) or
99
- (book.writable and options[:read_only]))
100
- book.save if book.writable && (not book.saved)
98
+ if book.alive? && ((!book.writable && !(options[:read_only])) ||
99
+ (book.writable && options[:read_only]))
100
+ book.save if book.writable && !book.saved
101
101
  book.close(:if_unsaved => :forget)
102
- end
103
- # reopens the book if it was closed
104
- book.ensure_workbook(file,options) unless book.alive?
102
+ end
103
+ # reopens the book if it was closed
104
+ book.ensure_workbook(file,options) unless book.alive?
105
105
  book.visible = options[:force][:visible] unless options[:force][:visible].nil?
106
106
  book.CheckCompatibility = options[:check_compatibility] unless options[:check_compatibility].nil?
107
107
  book.excel.calculation = options[:calculation] unless options[:calculation].nil?
@@ -111,7 +111,7 @@ module RobustExcelOle
111
111
  end
112
112
  new(file, options, &block)
113
113
  end
114
- end
114
+ end
115
115
 
116
116
  # creates a Workbook object by opening an Excel file given its filename workbook
117
117
  # or by promoting a Win32OLE object representing an Excel file
@@ -119,16 +119,16 @@ module RobustExcelOle
119
119
  # @param [Hash] opts the options
120
120
  # @option opts [Symbol] see above
121
121
  # @return [Workbook] a workbook
122
- def self.new(workbook, opts={ }, &block)
122
+ def self.new(workbook, opts = { }, &block)
123
123
  opts = process_options(opts)
124
124
  if workbook && (workbook.is_a? WIN32OLE)
125
125
  filename = workbook.Fullname.tr('\\','/') rescue nil
126
126
  if filename
127
127
  book = bookstore.fetch(filename)
128
128
  if book && book.alive?
129
- book.visible = opts[:force][:visible] unless opts[:force].nil? or opts[:force][:visible].nil?
129
+ book.visible = opts[:force][:visible] unless opts[:force].nil? || opts[:force][:visible].nil?
130
130
  book.excel.calculation = opts[:calculation] unless opts[:calculation].nil?
131
- return book
131
+ return book
132
132
  else
133
133
  super
134
134
  end
@@ -139,20 +139,20 @@ module RobustExcelOle
139
139
  end
140
140
 
141
141
  # creates a new Workbook object, if a file name is given
142
- # Promotes the win32ole workbook to a Workbook object, if a win32ole-workbook is given
142
+ # Promotes the win32ole workbook to a Workbook object, if a win32ole-workbook is given
143
143
  # @param [Variant] file_or_workbook file name or workbook
144
144
  # @param [Hash] opts the options
145
145
  # @option opts [Symbol] see above
146
146
  # @return [Workbook] a workbook
147
- def initialize(file_or_workbook, options={ }, &block)
148
- #options = @options = self.class.process_options(options) if options.empty?
149
- if file_or_workbook.is_a? WIN32OLE
147
+ def initialize(file_or_workbook, options = { }, &block)
148
+ # options = @options = self.class.process_options(options) if options.empty?
149
+ if file_or_workbook.is_a? WIN32OLE
150
150
  workbook = file_or_workbook
151
- @ole_workbook = workbook
151
+ @ole_workbook = workbook
152
152
  # use the Excel instance where the workbook is opened
153
- win32ole_excel = WIN32OLE.connect(workbook.Fullname).Application rescue nil
154
- @excel = excel_class.new(win32ole_excel)
155
- @excel.visible = options[force][:visible] unless options[:force][:visible].nil?
153
+ win32ole_excel = WIN32OLE.connect(workbook.Fullname).Application rescue nil
154
+ @excel = excel_class.new(win32ole_excel)
155
+ @excel.visible = options[force][:visible] unless options[:force][:visible].nil?
156
156
  @excel.calculation = options[:calculation] unless options[:calculation].nil?
157
157
  ensure_excel(options)
158
158
  else
@@ -180,12 +180,12 @@ module RobustExcelOle
180
180
  erg = {}
181
181
  opts.each do |key,value|
182
182
  new_key = key
183
- ABBREVIATIONS.each{|long,short| new_key = long if key == short}
183
+ ABBREVIATIONS.each { |long,short| new_key = long if key == short }
184
184
  if value.is_a?(Hash)
185
185
  erg[new_key] = {}
186
186
  value.each do |k,v|
187
187
  new_k = k
188
- ABBREVIATIONS.each{|l,s| new_k = l if k == s}
188
+ ABBREVIATIONS.each { |l,s| new_k = l if k == s }
189
189
  erg[new_key][new_k] = v
190
190
  end
191
191
  else
@@ -195,20 +195,20 @@ module RobustExcelOle
195
195
  erg[:default] = {} if erg[:default].nil?
196
196
  erg[:force] = {} if erg[:force].nil?
197
197
  force_list = [:visible, :excel]
198
- erg.each {|key,value| erg[:force][key] = value if force_list.include?(key)}
198
+ erg.each { |key,value| erg[:force][key] = value if force_list.include?(key) }
199
199
  erg[:default][:excel] = erg[:default_excel] unless erg[:default_excel].nil?
200
200
  erg[:force][:excel] = erg[:force_excel] unless erg[:force_excel].nil?
201
- erg[:default][:excel] = :current if (erg[:default][:excel] == :reuse || erg[:default][:excel] == :active)
202
- erg[:force][:excel] = :current if (erg[:force][:excel] == :reuse || erg[:force][:excel] == :active)
201
+ erg[:default][:excel] = :current if erg[:default][:excel] == :reuse || erg[:default][:excel] == :active
202
+ erg[:force][:excel] = :current if erg[:force][:excel] == :reuse || erg[:force][:excel] == :active
203
203
  erg
204
204
  end
205
205
  opts = translator.call(options)
206
- default_open_opts = proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS :
206
+ default_open_opts = proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS :
207
207
  {:default => {:excel => :current}, :force => {}, :update_links => :never }
208
208
  default_opts = translator.call(default_open_opts)
209
209
  opts = default_opts.merge(opts)
210
210
  opts[:default] = default_opts[:default].merge(opts[:default]) unless opts[:default].nil?
211
- opts[:force] = default_opts[:force].merge(opts[:force]) unless opts[:force].nil?
211
+ opts[:force] = default_opts[:force].merge(opts[:force]) unless opts[:force].nil?
212
212
  opts
213
213
  end
214
214
 
@@ -216,8 +216,8 @@ module RobustExcelOle
216
216
  def self.excel_of(object) # :nodoc: #
217
217
  if object.is_a? WIN32OLE
218
218
  case object.ole_obj_help.name
219
- when /Workbook/i
220
- new(object).excel
219
+ when /Workbook/i
220
+ new(object).excel
221
221
  when /Application/i
222
222
  excel_class.new(object)
223
223
  else
@@ -227,7 +227,7 @@ module RobustExcelOle
227
227
  begin
228
228
  object.excel
229
229
  rescue
230
- raise TypeREOError, "given object is neither an Excel, a Workbook, nor a Win32ole"
230
+ raise TypeREOError, 'given object is neither an Excel, a Workbook, nor a Win32ole'
231
231
  end
232
232
  end
233
233
  end
@@ -235,34 +235,34 @@ module RobustExcelOle
235
235
  public
236
236
 
237
237
  def ensure_excel(options) # :nodoc: #
238
- if excel && @excel.alive?
238
+ if excel && @excel.alive?
239
239
  @excel.created = false
240
240
  return
241
241
  end
242
- excel_option = (options[:force].nil? or options[:force][:excel].nil?) ? options[:default][:excel] : options[:force][:excel]
243
- @excel = self.class.excel_of(excel_option) unless (excel_option == :current || excel_option == :new || excel_option == :reserved_new)
244
- excel_class.new(:reuse => false) if excel_option == :reserved_new and Excel.known_excel_instances.empty?
245
- @excel = excel_class.new(:reuse => (excel_option == :current)) unless (@excel && @excel.alive?)
242
+ excel_option = options[:force].nil? || options[:force][:excel].nil? ? options[:default][:excel] : options[:force][:excel]
243
+ @excel = self.class.excel_of(excel_option) unless excel_option == :current || excel_option == :new || excel_option == :reserved_new
244
+ excel_class.new(:reuse => false) if (excel_option == :reserved_new) && Excel.known_excel_instances.empty?
245
+ @excel = excel_class.new(:reuse => (excel_option == :current)) unless @excel && @excel.alive?
246
246
  @excel
247
- end
247
+ end
248
248
 
249
249
  def ensure_workbook(file, options) # :nodoc: #
250
250
  file = @stored_filename ? @stored_filename : file
251
- raise(FileNameNotGiven, "filename is nil") if file.nil?
252
- raise(FileNotFound, "file #{General::absolute_path(file).inspect} is a directory") if File.directory?(file)
251
+ raise(FileNameNotGiven, 'filename is nil') if file.nil?
252
+ raise(FileNotFound, "file #{General.absolute_path(file).inspect} is a directory") if File.directory?(file)
253
253
  unless File.exist?(file)
254
254
  if options[:if_absent] == :create
255
255
  @ole_workbook = excel_class.current.generate_workbook(file)
256
- else
257
- raise FileNotFound, "file #{General::absolute_path(file).inspect} not found"
256
+ else
257
+ raise FileNotFound, "file #{General.absolute_path(file).inspect} not found"
258
258
  end
259
259
  end
260
260
  @ole_workbook = @excel.Workbooks.Item(File.basename(file)) rescue nil
261
- if @ole_workbook then
262
- obstructed_by_other_book = (File.basename(file) == File.basename(@ole_workbook.Fullname)) &&
263
- (not (General::absolute_path(file) == @ole_workbook.Fullname))
261
+ if @ole_workbook
262
+ obstructed_by_other_book = (File.basename(file) == File.basename(@ole_workbook.Fullname)) &&
263
+ (General.absolute_path(file) != @ole_workbook.Fullname)
264
264
  # if workbook is obstructed by a workbook with same name and different path
265
- if obstructed_by_other_book then
265
+ if obstructed_by_other_book
266
266
  case options[:if_obstructed]
267
267
  when :raise
268
268
  raise WorkbookBlocked, "blocked by a workbook with the same name in a different path: #{@ole_workbook.Fullname.tr('\\','/')}"
@@ -276,14 +276,14 @@ module RobustExcelOle
276
276
  @ole_workbook = nil
277
277
  open_or_create_workbook(file, options)
278
278
  when :close_if_saved
279
- if (not @ole_workbook.Saved) then
279
+ if !@ole_workbook.Saved
280
280
  raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}"
281
- else
281
+ else
282
282
  @ole_workbook.Close
283
283
  @ole_workbook = nil
284
284
  open_or_create_workbook(file, options)
285
285
  end
286
- when :new_excel
286
+ when :new_excel
287
287
  @excel = excel_class.new(:reuse => false)
288
288
  open_or_create_workbook(file, options)
289
289
  else
@@ -291,7 +291,7 @@ module RobustExcelOle
291
291
  end
292
292
  else
293
293
  # book open, not obstructed by an other book, but not saved and writable
294
- if (not @ole_workbook.Saved) then
294
+ unless @ole_workbook.Saved
295
295
  case options[:if_unsaved]
296
296
  when :raise
297
297
  raise WorkbookNotSaved, "workbook is already open but not saved: #{File.basename(file).inspect}"
@@ -320,9 +320,9 @@ module RobustExcelOle
320
320
  private
321
321
 
322
322
  def open_or_create_workbook(file, options) # :nodoc: #
323
- if ((not @ole_workbook) || (options[:if_unsaved] == :alert) || options[:if_obstructed]) then
323
+ if !@ole_workbook || (options[:if_unsaved] == :alert) || options[:if_obstructed]
324
324
  begin
325
- filename = General::absolute_path(file)
325
+ filename = General.absolute_path(file)
326
326
  begin
327
327
  workbooks = @excel.Workbooks
328
328
  rescue WIN32OLERuntimeError => msg
@@ -330,7 +330,7 @@ module RobustExcelOle
330
330
  end
331
331
  begin
332
332
  with_workaround_linked_workbooks_excel2007(options) do
333
- workbooks.Open(filename, { 'ReadOnly' => options[:read_only] ,
333
+ workbooks.Open(filename, { 'ReadOnly' => options[:read_only],
334
334
  'UpdateLinks' => updatelinks_vba(options[:update_links]) })
335
335
  end
336
336
  rescue WIN32OLERuntimeError => msg
@@ -345,9 +345,9 @@ module RobustExcelOle
345
345
  rescue WIN32OLERuntimeError => msg
346
346
  raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message}"
347
347
  end
348
- if options[:force][:visible].nil? && (not options[:default][:visible].nil?)
349
- if @excel.created
350
- self.visible = options[:default][:visible]
348
+ if options[:force][:visible].nil? && !options[:default][:visible].nil?
349
+ if @excel.created
350
+ self.visible = options[:default][:visible]
351
351
  else
352
352
  self.window_visible = options[:default][:visible]
353
353
  end
@@ -359,43 +359,43 @@ module RobustExcelOle
359
359
  self.Saved = true # unless self.Saved # ToDo: this is too hard
360
360
  rescue WIN32OLERuntimeError => msg
361
361
  raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message} #{msg.backtrace}"
362
- end
362
+ end
363
363
  end
364
364
  end
365
365
  end
366
366
 
367
- # translating the option UpdateLinks from REO to VBA
367
+ # translating the option UpdateLinks from REO to VBA
368
368
  # setting UpdateLinks works only if calculation mode is automatic,
369
369
  # parameter 'UpdateLinks' has no effect
370
370
  def updatelinks_vba(updatelinks_reo)
371
371
  case updatelinks_reo
372
- when :alert; RobustExcelOle::XlUpdateLinksUserSetting
373
- when :never; RobustExcelOle::XlUpdateLinksNever
374
- when :always; RobustExcelOle::XlUpdateLinksAlways
372
+ when :alert then RobustExcelOle::XlUpdateLinksUserSetting
373
+ when :never then RobustExcelOle::XlUpdateLinksNever
374
+ when :always then RobustExcelOle::XlUpdateLinksAlways
375
375
  else RobustExcelOle::XlUpdateLinksNever
376
376
  end
377
377
  end
378
378
 
379
- # workaround for linked workbooks for Excel 2007:
379
+ # workaround for linked workbooks for Excel 2007:
380
380
  # opening and closing a dummy workbook if Excel has no workbooks.
381
381
  # delay: with visible: 0.2 sec, without visible almost none
382
382
  def with_workaround_linked_workbooks_excel2007(options)
383
383
  old_visible_value = @excel.Visible
384
384
  workbooks = @excel.Workbooks
385
- workaround_condition = @excel.Version.split(".").first.to_i == 12 && workbooks.Count == 0
385
+ workaround_condition = @excel.Version.split('.').first.to_i == 12 && workbooks.Count == 0
386
386
  if workaround_condition
387
- workbooks.Add
388
- @excel.calculation = options[:calculation].nil? ? @excel.calculation : options[:calculation]
387
+ workbooks.Add
388
+ @excel.calculation = options[:calculation].nil? ? @excel.calculation : options[:calculation]
389
389
  end
390
390
  begin
391
- #@excel.with_displayalerts(update_links_opt == :alert ? true : @excel.displayalerts) do
391
+ # @excel.with_displayalerts(update_links_opt == :alert ? true : @excel.displayalerts) do
392
392
  yield self
393
393
  ensure
394
- @excel.with_displayalerts(false){workbooks.Item(1).Close} if workaround_condition
395
- @excel.visible = old_visible_value
394
+ @excel.with_displayalerts(false) { workbooks.Item(1).Close } if workaround_condition
395
+ @excel.visible = old_visible_value
396
396
  end
397
397
  end
398
-
398
+
399
399
  public
400
400
 
401
401
  # closes the workbook, if it is alive
@@ -403,15 +403,15 @@ module RobustExcelOle
403
403
  # @option opts [Symbol] :if_unsaved :raise (default), :save, :forget, :keep_open, or :alert
404
404
  # options:
405
405
  # :if_unsaved if the workbook is unsaved
406
- # :raise -> raises an exception
407
- # :save -> saves the workbook before it is closed
408
- # :forget -> closes the workbook
406
+ # :raise -> raises an exception
407
+ # :save -> saves the workbook before it is closed
408
+ # :forget -> closes the workbook
409
409
  # :keep_open -> keep the workbook open
410
410
  # :alert or :excel -> gives control to excel
411
411
  # @raise WorkbookNotSaved if the option :if_unsaved is :raise and the workbook is unsaved
412
412
  # @raise OptionInvalid if the options is invalid
413
413
  def close(opts = {:if_unsaved => :raise})
414
- if (alive? && (not @ole_workbook.Saved) && writable) then
414
+ if alive? && !@ole_workbook.Saved && writable
415
415
  case opts[:if_unsaved]
416
416
  when :raise
417
417
  raise WorkbookNotSaved, "workbook is unsaved: #{File.basename(self.stored_filename).inspect}"
@@ -430,13 +430,13 @@ module RobustExcelOle
430
430
  else
431
431
  close_workbook
432
432
  end
433
- #trace "close: canceled by user" if alive? &&
433
+ # trace "close: canceled by user" if alive? &&
434
434
  # (opts[:if_unsaved] == :alert || opts[:if_unsaved] == :excel) && (not @ole_workbook.Saved)
435
435
  end
436
436
 
437
437
  private
438
438
 
439
- def close_workbook
439
+ def close_workbook
440
440
  @ole_workbook.Close if alive?
441
441
  @ole_workbook = nil unless alive?
442
442
  end
@@ -447,7 +447,7 @@ module RobustExcelOle
447
447
  def retain_saved
448
448
  saved = self.Saved
449
449
  begin
450
- yield self
450
+ yield self
451
451
  ensure
452
452
  self.Saved = saved
453
453
  end
@@ -470,25 +470,25 @@ module RobustExcelOle
470
470
  end
471
471
 
472
472
  # allows to read or modify a workbook such that its state remains unchanged
473
- # state comprises: open, saved, writable, visible, calculation mode, check compatibility
473
+ # state comprises: open, saved, writable, visible, calculation mode, check compatibility
474
474
  # remarks: works only for workbooks opened with RobustExcelOle
475
475
  # @param [String] file the file name
476
476
  # @param [Hash] opts the options
477
477
  # @option opts [Variant] :if_closed :current (default), :new or an Excel instance
478
478
  # @option opts [Boolean] :read_only true/false, open the workbook in read-only/read-write modus (save changes)
479
- # @option opts [Boolean] :writable true/false changes of the workbook shall be saved/not saved
479
+ # @option opts [Boolean] :writable true/false changes of the workbook shall be saved/not saved
480
480
  # @option opts [Boolean] :rw_change_excel Excel instance in which the workbook with the new
481
- # write permissions shall be opened :current (default), :new or an Excel instance
482
- # @option opts [Boolean] :keep_open whether the workbook shall be kept open after unobtrusively opening
481
+ # write permissions shall be opened :current (default), :new or an Excel instance
482
+ # @option opts [Boolean] :keep_open whether the workbook shall be kept open after unobtrusively opening
483
483
  # @return [Workbook] a workbook
484
- def self.unobtrusively(file, opts = { }, &block)
484
+ def self.unobtrusively(file, opts = { })
485
485
  opts = {:if_closed => :current,
486
486
  :rw_change_excel => :current,
487
487
  :keep_open => false}.merge(opts)
488
- raise OptionInvalid, "contradicting options" if (opts[:writable] && opts[:read_only])
489
- prefer_writable = (((not opts[:read_only]) || opts[:writable]==true) &&
490
- (not (opts[:read_only].nil?) && opts[:writable]==false))
491
- do_not_write = (opts[:read_only] or (opts[:read_only].nil? && opts[:writable]==false))
488
+ raise OptionInvalid, 'contradicting options' if opts[:writable] && opts[:read_only]
489
+ prefer_writable = ((!(opts[:read_only]) || opts[:writable] == true) &&
490
+ !(opts[:read_only].nil? && opts[:writable] == false))
491
+ do_not_write = (opts[:read_only] || (opts[:read_only].nil? && opts[:writable] == false))
492
492
  book = bookstore.fetch(file, :prefer_writable => prefer_writable)
493
493
  was_open = book && book.alive?
494
494
  if was_open
@@ -497,17 +497,17 @@ module RobustExcelOle
497
497
  was_visible = book.visible
498
498
  was_calculation = book.calculation
499
499
  was_check_compatibility = book.check_compatibility
500
- if ((opts[:writable] && (not was_writable) && (not was_saved)) ||
501
- (opts[:read_only] && was_writable && (not was_saved)))
502
- raise NotImplementedREOError, "unsaved read-only workbook shall be written"
500
+ if (opts[:writable] && !was_writable && !was_saved) ||
501
+ (opts[:read_only] && was_writable && !was_saved)
502
+ raise NotImplementedREOError, 'unsaved read-only workbook shall be written'
503
503
  end
504
- opts[:rw_change_excel] = book.excel if opts[:rw_change_excel]==:current
505
- end
506
- change_rw_mode = ((opts[:read_only] && was_writable) or (opts[:writable] && (not was_writable)))
504
+ opts[:rw_change_excel] = book.excel if opts[:rw_change_excel] == :current
505
+ end
506
+ change_rw_mode = ((opts[:read_only] && was_writable) || (opts[:writable] && !was_writable))
507
507
  begin
508
- book =
509
- if was_open
510
- if change_rw_mode
508
+ book =
509
+ if was_open
510
+ if change_rw_mode
511
511
  open(file, :force => {:excel => opts[:rw_change_excel]}, :read_only => do_not_write)
512
512
  else
513
513
  book
@@ -520,45 +520,45 @@ module RobustExcelOle
520
520
  if book && book.alive?
521
521
  book.save unless book.saved || do_not_write || book.ReadOnly
522
522
  if was_open
523
- if opts[:rw_change_excel]==book.excel && change_rw_mode
523
+ if opts[:rw_change_excel] == book.excel && change_rw_mode
524
524
  book.close
525
- book = open(file, :force => {:excel => opts[:rw_change_excel]}, :read_only => (not was_writable))
526
- end
525
+ book = open(file, :force => {:excel => opts[:rw_change_excel]}, :read_only => !was_writable)
526
+ end
527
527
  book.excel.calculation = was_calculation
528
528
  book.CheckCompatibility = was_check_compatibility
529
- #book.visible = was_visible # not necessary
529
+ # book.visible = was_visible # not necessary
530
530
  end
531
- book.Saved = (was_saved || (not was_open))
531
+ book.Saved = (was_saved || !was_open)
532
532
  book.close unless was_open || opts[:keep_open]
533
533
  end
534
534
  end
535
535
  end
536
536
 
537
537
  # reopens a closed workbook
538
- # @options options
538
+ # @options options
539
539
  def reopen(options = { })
540
540
  book = self.class.open(@stored_filename, options)
541
- raise WorkbookREOError("cannot reopen book") unless book && book.alive?
541
+ raise WorkbookREOError('cannot reopen book') unless book && book.alive?
542
542
  book
543
543
  end
544
544
 
545
545
  # simple save of a workbook.
546
546
  # @option opts [Boolean] :discoloring states, whether colored ranges shall be discolored
547
547
  # @return [Boolean] true, if successfully saved, nil otherwise
548
- def save(opts = {:discoloring => false})
549
- raise ObjectNotAlive, "workbook is not alive" if (not alive?)
550
- raise WorkbookReadOnly, "Not opened for writing (opened with :read_only option)" if @ole_workbook.ReadOnly
548
+ def save(opts = {:discoloring => false})
549
+ raise ObjectNotAlive, 'workbook is not alive' unless alive?
550
+ raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
551
551
  begin
552
- discoloring if opts[:discoloring]
552
+ discoloring if opts[:discoloring]
553
553
  @modified_cells = []
554
- @ole_workbook.Save
554
+ @ole_workbook.Save
555
555
  rescue WIN32OLERuntimeError => msg
556
- if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
557
- raise WorkbookNotSaved, "workbook not saved"
556
+ if msg.message =~ /SaveAs/ && msg.message =~ /Workbook/
557
+ raise WorkbookNotSaved, 'workbook not saved'
558
558
  else
559
559
  raise UnexpectedREOError, "unknown WIN32OLERuntimeError:\n#{msg.message}"
560
- end
561
- end
560
+ end
561
+ end
562
562
  true
563
563
  end
564
564
 
@@ -567,28 +567,28 @@ module RobustExcelOle
567
567
  # @param [Hash] opts the options
568
568
  # @option opts [Symbol] :if_exists :raise (default), :overwrite, or :alert, :excel
569
569
  # @option opts [Symbol] :if_obstructed :raise (default), :forget, :save, or :close_if_saved
570
- # options:
571
- # :if_exists if a file with the same name exists, then
570
+ # options:
571
+ # :if_exists if a file with the same name exists, then
572
572
  # :raise -> raises an exception, dont't write the file (default)
573
573
  # :overwrite -> writes the file, delete the old file
574
574
  # :alert or :excel -> gives control to Excel
575
575
  # :if_obstructed if a workbook with the same name and different path is already open and blocks the saving, then
576
- # :raise -> raises an exception
576
+ # :raise -> raises an exception
577
577
  # :forget -> closes the blocking workbook
578
578
  # :save -> saves the blocking workbook and closes it
579
- # :close_if_saved -> closes the blocking workbook, if it is saved,
579
+ # :close_if_saved -> closes the blocking workbook, if it is saved,
580
580
  # otherwise raises an exception
581
581
  # :discoloring states, whether colored ranges shall be discolored
582
582
  # @return [Workbook], the book itself, if successfully saved, raises an exception otherwise
583
- def save_as(file, opts = { } )
584
- raise FileNameNotGiven, "filename is nil" if file.nil?
585
- raise ObjectNotAlive, "workbook is not alive" unless alive?
586
- raise WorkbookReadOnly, "Not opened for writing (opened with :read_only option)" if @ole_workbook.ReadOnly
583
+ def save_as(file, opts = { })
584
+ raise FileNameNotGiven, 'filename is nil' if file.nil?
585
+ raise ObjectNotAlive, 'workbook is not alive' unless alive?
586
+ raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
587
587
  options = {
588
588
  :if_exists => :raise,
589
- :if_obstructed => :raise,
589
+ :if_obstructed => :raise
590
590
  }.merge(opts)
591
- if File.exist?(file) then
591
+ if File.exist?(file)
592
592
  case options[:if_exists]
593
593
  when :overwrite
594
594
  if file == self.filename
@@ -598,10 +598,10 @@ module RobustExcelOle
598
598
  begin
599
599
  File.delete(file)
600
600
  rescue Errno::EACCES
601
- raise WorkbookBeingUsed, "workbook is open and used in Excel"
601
+ raise WorkbookBeingUsed, 'workbook is open and used in Excel'
602
602
  end
603
603
  end
604
- when :alert, :excel
604
+ when :alert, :excel
605
605
  @excel.with_displayalerts true do
606
606
  save_as_workbook(file, options)
607
607
  end
@@ -613,7 +613,7 @@ module RobustExcelOle
613
613
  end
614
614
  end
615
615
  other_workbook = @excel.Workbooks.Item(File.basename(file)) rescue nil
616
- if other_workbook && (not(self.filename == other_workbook.Fullname.tr('\\','/'))) then
616
+ if other_workbook && self.filename != other_workbook.Fullname.tr('\\','/')
617
617
  case options[:if_obstructed]
618
618
  when :raise
619
619
  raise WorkbookBlocked, "blocked by another workbook: #{other_workbook.Fullname.tr('\\','/')}"
@@ -635,29 +635,27 @@ module RobustExcelOle
635
635
  private
636
636
 
637
637
  def discoloring
638
- @modified_cells.each{|cell| cell.Interior.ColorIndex = XlNone}
638
+ @modified_cells.each { |cell| cell.Interior.ColorIndex = XlNone }
639
639
  end
640
640
 
641
641
  def save_as_workbook(file, options) # :nodoc: #
642
- begin
643
- dirname, basename = File.split(file)
644
- file_format =
645
- case File.extname(basename)
646
- when '.xls' ; RobustExcelOle::XlExcel8
647
- when '.xlsx'; RobustExcelOle::XlOpenXMLWorkbook
648
- when '.xlsm'; RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
649
- end
650
- discoloring if options[:discoloring]
651
- @modified_cells = []
652
- @ole_workbook.SaveAs(General::absolute_path(file), file_format)
653
- bookstore.store(self)
654
- rescue WIN32OLERuntimeError => msg
655
- if msg.message =~ /SaveAs/ and msg.message =~ /Workbook/ then
656
- # trace "save: canceled by user" if options[:if_exists] == :alert || options[:if_exists] == :excel
657
- # another possible semantics. raise WorkbookREOError, "could not save Workbook"
658
- else
659
- raise UnexpectedREOError, "unknown WIN32OELERuntimeError:\n#{msg.message}"
660
- end
642
+ dirname, basename = File.split(file)
643
+ file_format =
644
+ case File.extname(basename)
645
+ when '.xls' then RobustExcelOle::XlExcel8
646
+ when '.xlsx' then RobustExcelOle::XlOpenXMLWorkbook
647
+ when '.xlsm' then RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
648
+ end
649
+ discoloring if options[:discoloring]
650
+ @modified_cells = []
651
+ @ole_workbook.SaveAs(General.absolute_path(file), file_format)
652
+ bookstore.store(self)
653
+ rescue WIN32OLERuntimeError => msg
654
+ if msg.message =~ /SaveAs/ && msg.message =~ /Workbook/
655
+ # trace "save: canceled by user" if options[:if_exists] == :alert || options[:if_exists] == :excel
656
+ # another possible semantics. raise WorkbookREOError, "could not save Workbook"
657
+ else
658
+ raise UnexpectedREOError, "unknown WIN32OELERuntimeError:\n#{msg.message}"
661
659
  end
662
660
  end
663
661
 
@@ -686,12 +684,10 @@ module RobustExcelOle
686
684
  # @param [String] or [Number]
687
685
  # @returns [Worksheet]
688
686
  def sheet(name)
689
- begin
690
- worksheet_class.new(@ole_workbook.Worksheets.Item(name))
691
- rescue WIN32OLERuntimeError => msg
692
- raise NameNotFound, "could not return a sheet with name #{name.inspect}"
693
- end
694
- end
687
+ worksheet_class.new(@ole_workbook.Worksheets.Item(name))
688
+ rescue WIN32OLERuntimeError => msg
689
+ raise NameNotFound, "could not return a sheet with name #{name.inspect}"
690
+ end
695
691
 
696
692
  def each
697
693
  @ole_workbook.Worksheets.each do |sheet|
@@ -706,7 +702,7 @@ module RobustExcelOle
706
702
  i += 1
707
703
  end
708
704
  end
709
-
705
+
710
706
  # copies a sheet to another position
711
707
  # default: copied sheet is appended
712
708
  # @param [Worksheet] sheet a sheet that shall be copied
@@ -723,7 +719,7 @@ module RobustExcelOle
723
719
  new_sheet = worksheet_class.new(@excel.Activesheet)
724
720
  new_sheet.name = new_sheet_name if new_sheet_name
725
721
  new_sheet
726
- end
722
+ end
727
723
 
728
724
  # adds an empty sheet
729
725
  # default: empty sheet is appended
@@ -740,7 +736,7 @@ module RobustExcelOle
740
736
  new_sheet = worksheet_class.new(@excel.Activesheet)
741
737
  new_sheet.name = new_sheet_name if new_sheet_name
742
738
  new_sheet
743
- end
739
+ end
744
740
 
745
741
  # copies a sheet to another position if a sheet is given, or adds an empty sheet
746
742
  # default: copied or empty sheet is appended, i.e. added behind the last sheet
@@ -756,12 +752,12 @@ module RobustExcelOle
756
752
  sheet = nil
757
753
  end
758
754
  sheet ? copy_sheet(sheet, opts) : add_empty_sheet(opts)
759
- end
755
+ end
760
756
 
761
757
  # for compatibility to older versions
762
758
  def add_sheet(sheet = nil, opts = { })
763
759
  add_or_copy_sheet(sheet, opts)
764
- end
760
+ end
765
761
 
766
762
  def last_sheet
767
763
  worksheet_class.new(@ole_workbook.Worksheets.Item(@ole_workbook.Worksheets.Count))
@@ -794,12 +790,12 @@ module RobustExcelOle
794
790
  check_compatibility_before = check_compatibility
795
791
  unless opts[:read_only].nil?
796
792
  # if the ReadOnly status shall be changed, then close and reopen it
797
- if ((not writable) and (not opts[:read_only])) or (writable and opts[:read_only])
798
- opts[:check_compatibility] = check_compatibility if opts[:check_compatibility].nil?
799
- close(:if_unsaved => true)
793
+ if (!writable && !(opts[:read_only])) || (writable && opts[:read_only])
794
+ opts[:check_compatibility] = check_compatibility if opts[:check_compatibility].nil?
795
+ close(:if_unsaved => true)
800
796
  open_or_create_workbook(@stored_filename, opts)
801
797
  end
802
- end
798
+ end
803
799
  self.visible = opts[:force][:visible].nil? ? visible_before : opts[:force][:visible]
804
800
  self.CheckCompatibility = opts[:check_compatibility].nil? ? check_compatibility_before : opts[:check_compatibility]
805
801
  @excel.calculation = opts[:calculation] unless opts[:calculation].nil?
@@ -814,14 +810,12 @@ module RobustExcelOle
814
810
 
815
811
  # returns true, if the workbook reacts to methods, false otherwise
816
812
  def alive?
817
- begin
818
- @ole_workbook.Name
819
- true
820
- rescue
821
- @ole_workbook = nil # dead object won't be alive again
822
- #t $!.message
823
- false
824
- end
813
+ @ole_workbook.Name
814
+ true
815
+ rescue
816
+ @ole_workbook = nil # dead object won't be alive again
817
+ # t $!.message
818
+ false
825
819
  end
826
820
 
827
821
  # returns the full file name of the workbook
@@ -830,7 +824,7 @@ module RobustExcelOle
830
824
  end
831
825
 
832
826
  def writable # :nodoc: #
833
- (not @ole_workbook.ReadOnly) if @ole_workbook
827
+ !@ole_workbook.ReadOnly if @ole_workbook
834
828
  end
835
829
 
836
830
  def saved # :nodoc: #
@@ -845,7 +839,7 @@ module RobustExcelOle
845
839
  @ole_workbook.CheckCompatibility if @ole_workbook
846
840
  end
847
841
 
848
- # returns true, if the workbook is visible, false otherwise
842
+ # returns true, if the workbook is visible, false otherwise
849
843
  def visible
850
844
  @excel.visible && @ole_workbook.Windows(@ole_workbook.Name).Visible
851
845
  end
@@ -859,7 +853,7 @@ module RobustExcelOle
859
853
 
860
854
  # returns true, if the window of the workbook is set to visible, false otherwise
861
855
  def window_visible
862
- return @ole_workbook.Windows(@ole_workbook.Name).Visible
856
+ @ole_workbook.Windows(@ole_workbook.Name).Visible
863
857
  end
864
858
 
865
859
  # makes the window of the workbook visible or invisible
@@ -870,11 +864,11 @@ module RobustExcelOle
870
864
  end
871
865
  end
872
866
 
873
- # @return [Boolean] true, if the full book names and excel Instances are identical, false otherwise
867
+ # @return [Boolean] true, if the full book names and excel Instances are identical, false otherwise
874
868
  def == other_book
875
869
  other_book.is_a?(Workbook) &&
876
- @excel == other_book.excel &&
877
- self.filename == other_book.filename
870
+ @excel == other_book.excel &&
871
+ self.filename == other_book.filename
878
872
  end
879
873
 
880
874
  def self.books
@@ -887,14 +881,14 @@ module RobustExcelOle
887
881
 
888
882
  def bookstore # :nodoc: #
889
883
  self.class.bookstore
890
- end
884
+ end
891
885
 
892
886
  def to_s # :nodoc: #
893
- "#{self.filename}"
887
+ self.filename.to_s
894
888
  end
895
889
 
896
890
  def inspect # :nodoc: #
897
- "#<Workbook: " + "#{"not alive " unless alive?}" + "#{File.basename(self.filename) if alive?}" + " #{@ole_workbook} #{@excel}" + ">"
891
+ '#<Workbook: ' + ('not alive ' unless alive?).to_s + (File.basename(self.filename) if alive?).to_s + " #{@ole_workbook} #{@excel}" + '>'
898
892
  end
899
893
 
900
894
  def self.excel_class # :nodoc: #
@@ -902,7 +896,7 @@ module RobustExcelOle
902
896
  module_name = self.parent_name
903
897
  "#{module_name}::Excel".constantize
904
898
  rescue NameError => e
905
- #trace "excel_class: NameError: #{e}"
899
+ # trace "excel_class: NameError: #{e}"
906
900
  Excel
907
901
  end
908
902
  end
@@ -929,23 +923,23 @@ module RobustExcelOle
929
923
  private
930
924
 
931
925
  def method_missing(name, *args) # :nodoc: #
932
- if name.to_s[0,1] =~ /[A-Z]/
926
+ if name.to_s[0,1] =~ /[A-Z]/
933
927
  begin
934
- raise ObjectNotAlive, "method missing: workbook not alive" unless alive?
928
+ raise ObjectNotAlive, 'method missing: workbook not alive' unless alive?
935
929
  @ole_workbook.send(name, *args)
936
930
  rescue WIN32OLERuntimeError => msg
937
931
  if msg.message =~ /unknown property or method/
938
932
  raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
939
- else
933
+ else
940
934
  raise msg
941
935
  end
942
936
  end
943
- else
944
- super
937
+ else
938
+ super
945
939
  end
946
940
  end
947
941
  end
948
-
942
+
949
943
  public
950
944
 
951
945
  Book = Workbook