robust_excel_ole 1.4 → 1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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