robust_excel_ole 0.5.1 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/Changelog +13 -0
  2. data/README.rdoc +70 -21
  3. data/README_detail.rdoc +60 -27
  4. data/examples/edit_sheets/example_access_sheets_and_cells.rb +2 -2
  5. data/examples/edit_sheets/example_adding_sheets.rb +2 -2
  6. data/examples/edit_sheets/example_concating.rb +2 -3
  7. data/examples/edit_sheets/example_copying.rb +2 -3
  8. data/examples/edit_sheets/example_expanding.rb +2 -3
  9. data/examples/edit_sheets/example_naming.rb +2 -3
  10. data/examples/edit_sheets/example_ranges.rb +2 -2
  11. data/examples/edit_sheets/example_saving.rb +2 -3
  12. data/examples/open_save_close/example_control_to_excel.rb +3 -3
  13. data/examples/open_save_close/example_default_excel.rb +4 -4
  14. data/examples/open_save_close/example_force_excel.rb +2 -2
  15. data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +2 -2
  16. data/examples/open_save_close/example_if_obstructed_forget.rb +2 -2
  17. data/examples/open_save_close/example_if_obstructed_save.rb +2 -2
  18. data/examples/open_save_close/example_if_unsaved_accept.rb +2 -2
  19. data/examples/open_save_close/example_if_unsaved_forget.rb +2 -2
  20. data/examples/open_save_close/example_if_unsaved_forget_more.rb +4 -5
  21. data/examples/open_save_close/example_read_only.rb +2 -2
  22. data/examples/open_save_close/example_rename_cells.rb +3 -3
  23. data/examples/open_save_close/example_reuse.rb +2 -2
  24. data/examples/open_save_close/example_simple.rb +3 -4
  25. data/examples/open_save_close/example_unobtrusively.rb +2 -2
  26. data/lib/robust_excel_ole/book.rb +84 -78
  27. data/lib/robust_excel_ole/bookstore.rb +5 -1
  28. data/lib/robust_excel_ole/excel.rb +165 -188
  29. data/lib/robust_excel_ole/reo_common.rb +4 -0
  30. data/lib/robust_excel_ole/sheet.rb +15 -6
  31. data/lib/robust_excel_ole/version.rb +1 -1
  32. data/spec/book_spec.rb +104 -77
  33. data/spec/book_specs/book_close_spec.rb +9 -8
  34. data/spec/book_specs/book_misc_spec.rb +367 -26
  35. data/spec/book_specs/book_open_spec.rb +375 -94
  36. data/spec/book_specs/book_save_spec.rb +137 -112
  37. data/spec/book_specs/book_sheet_spec.rb +1 -1
  38. data/spec/book_specs/book_subclass_spec.rb +2 -1
  39. data/spec/book_specs/book_unobtr_spec.rb +87 -96
  40. data/spec/bookstore_spec.rb +8 -5
  41. data/spec/cell_spec.rb +1 -1
  42. data/spec/data/another_workbook.xls +0 -0
  43. data/spec/data/book_with_blank.xls +0 -0
  44. data/spec/data/workbook.xls +0 -0
  45. data/spec/excel_spec.rb +484 -72
  46. data/spec/range_spec.rb +1 -1
  47. data/spec/sheet_spec.rb +47 -1
  48. metadata +4 -5
@@ -1,9 +1,8 @@
1
1
  # example_saving.rb:
2
2
  # save the sheets of a book as separate workbooks
3
3
 
4
- require 'rubygems'
5
- #require 'general'
6
- require File.join(File.dirname(__FILE__), '../../lib/general')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
7
6
  require "fileutils"
8
7
 
9
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_give_control_to_excel.rb:
2
2
  # open, close, save with giving control to Excel
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -23,7 +23,7 @@ begin
23
23
  puts "#{msg.message}" # an exeptions is raised
24
24
  end
25
25
  puts "new book has opened" if new_book
26
- Excel.current.Visible = true
26
+ Excel.current.visible = true
27
27
  begin
28
28
  book.close(:if_unsaved => :alert) # close the unsaved book.
29
29
  rescue ExcelUserCanceled => msg # user is asked whether the unsaved book shall be saved
@@ -1,8 +1,8 @@
1
1
  # example_default_excel.rb:
2
2
  # reopening books using :default_excel
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -23,9 +23,9 @@ begin
23
23
  p "book1 == book2" if book2 == book1 # the books are identical
24
24
  sleep 2
25
25
  new_excel = Excel.new(:reuse => false) # create a new Excel
26
- book3 = Book.open(file_name2, :default_excel => :reuse, :visible => true) # open another book
26
+ book3 = Book.open(file_name2, :default_excel => :current, :visible => true) # open another book
27
27
  if book3.excel == book2.excel then # since this book cannot be reopened, the option :default_excel applies:
28
- p "book3 opened in the first Excel" # according to :default_excel => :reuse the book is opened
28
+ p "book3 opened in the first Excel" # according to :default_excel => :current the book is opened
29
29
  end # in the Excel instance the was created first
30
30
  sleep 2
31
31
  new_excel = Excel.new(:reuse => false)
@@ -1,8 +1,8 @@
1
1
  # example_force_excel.rb:
2
2
  # opening books in new or given Excel instances using :force_excel
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_if_obstructed_close_if_saved.rb:
2
2
  # open with :if_obstructed: :close_if_saved
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_if_obstructed_forget.rb:
2
2
  # open with :if_obstructed: :forget, :new_excel
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_if_obstructed_save.rb:
2
2
  # open with :if_obstructed: :save
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_ifunsaved_accept.rb:
2
2
  # open with :if_unsaved => :accept, close with :if_unsaved => :save
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_ifunsaved_forget.rb:
2
2
  # open with :if_unsaved => :forget, :new_excel, close with :if_unsaved => :save
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -1,19 +1,18 @@
1
1
  # example_ifunsaved_forget_more.rb:
2
2
  # open with :if_unsaved => :forget, :new_excel, close with :if_unsaved => :save
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
9
9
 
10
- Excel.close_all
10
+ Excel.kill_all
11
11
  begin
12
12
  dir = create_tmpdir
13
13
  file_name = dir + 'workbook.xls'
14
14
  book = Book.open(file_name) # open a book
15
15
  book.excel.visible = true # make current Excel visible
16
- sleep
17
16
  sheet = book.sheet(1) # access a sheet
18
17
  first_cell = sheet[1,1].value
19
18
  sheet[1,1] = first_cell == "simple" ? "complex" : "simple" # change a cell
@@ -33,6 +32,6 @@ begin
33
32
  another_book.close(:if_unsaved => :forget ) # close the last book without saving it.
34
33
  book.close(:if_unsaved => :save) # close the first book and save it before
35
34
  ensure
36
- Excel.close_all # close all workbooks, quit Excel application
35
+ Excel.kill_all # close all workbooks, quit Excel application
37
36
  rm_tmp(dir)
38
37
  end
@@ -1,7 +1,7 @@
1
1
  # example_read_only: open with read_only mode. save, close
2
2
 
3
- require File.join(File.dirname(__FILE__), '../../lib/general')
4
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
3
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
4
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
5
5
  require "fileutils"
6
6
 
7
7
  include RobustExcelOle
@@ -1,8 +1,8 @@
1
1
  # example_simple.rb:
2
2
  # open a book, simple save, save_as, close
3
3
 
4
- require File.join(File.dirname(__FILE__), '../../lib/general')
5
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
4
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
5
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
6
6
  require "fileutils"
7
7
 
8
8
  include RobustExcelOle
@@ -17,7 +17,7 @@ begin
17
17
  workbook = book.ole_workbook
18
18
  fullname = workbook.Fullname
19
19
  puts "fullname: #{fullname}"
20
- sheet.add_name(1,1,"a_name") # rename cell A1 to "a_name"
20
+ sheet.set_name("a_name",1,1) # rename cell A1 to "a_name"
21
21
  number = workbook.Names.Count
22
22
  puts "number of name objects :#{number}"
23
23
  name_object = workbook.Names("a_name")
@@ -1,7 +1,7 @@
1
1
  # example_reuse.rb: open a book in a new Excel and a running Excel instance. make visible
2
2
 
3
- require File.join(File.dirname(__FILE__), '../../lib/general')
4
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
3
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
4
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
5
5
  require "fileutils"
6
6
 
7
7
  include RobustExcelOle
@@ -5,15 +5,14 @@ LOG_TO_STDOUT = false
5
5
  REO_LOG_FILE = "reo2.log"
6
6
  REO_LOG_DIR = "C:/"
7
7
 
8
- require File.join(File.dirname(__FILE__), '../../lib/general')
9
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
8
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
9
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
10
10
  require "fileutils"
11
11
 
12
12
  include RobustExcelOle
13
13
 
14
14
  Excel.kill_all
15
15
  begin
16
- trace "hello"
17
16
  dir = create_tmpdir
18
17
  file_name = dir + 'workbook.xls'
19
18
  other_file_name = dir + 'different_workbook.xls'
@@ -34,6 +33,6 @@ begin
34
33
  book.close # close the book
35
34
  ensure
36
35
  Excel.close_all # close workbooks, quit Excel application
37
- rm_tmp(dir)
36
+ #rm_tmp(dir)
38
37
  end
39
38
 
@@ -1,7 +1,7 @@
1
1
  # example_unobtrusively.rb:
2
2
 
3
- require File.join(File.dirname(__FILE__), '../../lib/general')
4
- require File.join(File.dirname(__FILE__), '../../spec/helpers/create_temporary_dir')
3
+ require File.expand_path('../../lib/robust_excel_ole', File.dirname(__FILE__))
4
+ require File.join(File.dirname(File.expand_path(__FILE__)), '../../spec/helpers/create_temporary_dir')
5
5
  require "fileutils"
6
6
 
7
7
  include RobustExcelOle
@@ -15,13 +15,13 @@ module RobustExcelOle
15
15
  alias ole_object ole_workbook
16
16
 
17
17
  DEFAULT_OPEN_OPTS = {
18
- :excel => :active,
19
- :default_excel => :active,
18
+ :default_excel => :current,
20
19
  :if_unsaved => :raise,
21
20
  :if_obstructed => :raise,
22
21
  :if_absent => :raise,
23
22
  :read_only => false,
24
- :check_compatibility => true
23
+ :check_compatibility => true,
24
+ :update_links => :never
25
25
  }
26
26
 
27
27
  class << self
@@ -29,26 +29,26 @@ module RobustExcelOle
29
29
  # opens a workbook.
30
30
  # @param [String] file the file name
31
31
  # @param [Hash] opts the options
32
- # @option opts [Variant] :default_excel :active (default), :new, or <excel-instance>
33
- # @option opts [Variant] :force_excel :active, :new, or <excel-instance>
32
+ # @option opts [Variant] :default_excel :current (or :active, or :reuse) (default), :new, or <excel-instance>
33
+ # @option opts [Variant] :force_excel :current, :new, or <excel-instance>
34
34
  # @option opts [Symbol] :if_unsaved :raise (default), :forget, :accept, :alert, :excel, or :new_excel
35
35
  # @option opts [Symbol] :if_obstructed :raise (default), :forget, :save, :close_if_saved, or _new_excel
36
- # @option opts [Symbol] :if_absent :raise (default), or :create
37
- # @option opts [Boolean] :read_only true (default), or false
38
- # @option opts [Boolean] :displayalerts true, or false (default)
39
- # @option opts [Boolean] :visible true, or false (default)
36
+ # @option opts [Symbol] :if_absent :raise (default) or :create
37
+ # @option opts [Boolean] :read_only true (default) or false
38
+ # @option opts [Boolean] :update_links :never (default), :always, :alert
39
+ # @option opts [Boolean] :visible true or false (default)
40
40
  # options:
41
41
  # :default_excel if the workbook was already open in an Excel instance, then open it in that Excel instance,
42
42
  # where it was opened most recently
43
43
  # Otherwise, i.e. if the workbook was not open before or the Excel instance is not alive
44
- # :active or :reuse -> connects to a running (the first opened) Excel instance,
45
- # excluding the hidden Excel instance, if it exists,
46
- # otherwise opens in a new Excel instance.
47
- # :new -> opens in a new Excel instance
48
- # <excel-instance> -> opens in the given Excel instance
44
+ # :current -> connects to a running (the first opened) Excel instance,
45
+ # (or :active, :reuse) excluding the hidden Excel instance, if it exists,
46
+ # otherwise opens in a new Excel instance.
47
+ # :new -> opens in a new Excel instance
48
+ # <excel-instance> -> opens in the given Excel instance
49
49
  # :force_excel no matter whether the workbook was already open
50
- # :new -> connects to a running (the first opened) Excel instance
51
- # :active or :reuse -> opens in the active Excel instance
50
+ # :new -> opens in a new Exceö instance
51
+ # :current (or :active, :reuse) -> opens in the current Excel instance
52
52
  # <excel-instance> -> opens in the given Excel instance
53
53
  # :if_unsaved if an unsaved workbook with the same name is open, then
54
54
  # :raise -> raises an exception
@@ -65,22 +65,20 @@ module RobustExcelOle
65
65
  # :new_excel -> opens the new workbook in a new Excel instance
66
66
  # :if_absent :raise -> raises an exception , if the file does not exists
67
67
  # :create -> creates a new Excel file, if it does not exists
68
- #
69
- # :read_only opens in read-only mode
70
- # :displayalerts enables DisplayAlerts in Excel
71
- # :visible makes visible in Excel
72
- # :check_compatibility check compatibility when saving
73
- # if :default_excel is set, then DisplayAlerts and Visible are set only if these parameters are given
68
+ # :read_only true -> opens in read-only mode
69
+ # :update_links true -> user is being asked how to update links, false -> links are never updated
70
+ # :visible true -> makes the window of the workbook visible
71
+ # :check_compatibility true -> check compatibility when saving
74
72
  # @return [Book] a workbook
75
73
  def open(file, opts={ }, &block)
76
74
  options = DEFAULT_OPEN_OPTS.merge(opts)
77
- options[:default_excel] = :active if options[:default_excel] == :reuse
78
- options[:force_excel] = :active if options[:force_excel] == :reuse
75
+ options[:default_excel] = :current if (options[:default_excel] == :reuse || options[:default_excel] == :active)
76
+ options[:force_excel] = :current if (options[:force_excel] == :reuse || options[:force_excel] == :active)
79
77
  book = nil
80
78
  if (not (options[:force_excel] == :new))
81
79
  # if readonly is true, then prefer a book that is given in force_excel if this option is set
82
80
  forced_excel = if options[:force_excel]
83
- options[:force_excel] == :active ? excel_class.new(:reuse => true) : excel_of(options[:force_excel])
81
+ options[:force_excel] == :current ? excel_class.new(:reuse => true) : excel_of(options[:force_excel])
84
82
  end
85
83
  book = bookstore.fetch(file,
86
84
  :prefer_writable => (not options[:read_only]),
@@ -94,6 +92,7 @@ module RobustExcelOle
94
92
  book.close if (book.alive? && (not book.writable) && (not options[:read_only]))
95
93
  # reopens the book
96
94
  book.ensure_workbook(file,options) unless book.alive?
95
+ book.visible = options[:visible] unless options[:visible].nil?
97
96
  return book
98
97
  end
99
98
  end
@@ -102,7 +101,8 @@ module RobustExcelOle
102
101
  end
103
102
  end
104
103
 
105
- # creates a Book object for a given workbook or file name
104
+ # creates a Book object by opening an Excel file given its filename workbook or
105
+ # by lifting a Win32OLE object representing an Excel file
106
106
  # @param [WIN32OLE] workbook a workbook
107
107
  # @param [Hash] opts the options
108
108
  # @option opts [Symbol] see above
@@ -113,7 +113,7 @@ module RobustExcelOle
113
113
  if filename
114
114
  book = bookstore.fetch(filename)
115
115
  if book && book.alive?
116
- book.apply_options(opts)
116
+ book.visible = opts[:visible] unless opts[:visible].nil?
117
117
  return book
118
118
  end
119
119
  end
@@ -135,13 +135,15 @@ module RobustExcelOle
135
135
  # use the Excel instance where the workbook is opened
136
136
  win32ole_excel = WIN32OLE.connect(workbook.Fullname).Application rescue nil
137
137
  @excel = excel_class.new(win32ole_excel)
138
- self.apply_options(options)
138
+ @excel.visible = options[:visible] unless options[:visible].nil?
139
139
  # if the Excel could not be promoted, then create it
140
140
  ensure_excel(options)
141
141
  else
142
142
  file = file_or_workbook
143
143
  ensure_excel(options)
144
144
  ensure_workbook(file, options)
145
+ @ole_workbook.CheckCompatibility = options[:check_compatibility]
146
+ @can_be_closed = false if @can_be_closed.nil?
145
147
  end
146
148
  bookstore.store(self)
147
149
  if block
@@ -153,11 +155,6 @@ module RobustExcelOle
153
155
  end
154
156
  end
155
157
 
156
- def apply_options(options) # :nodoc: #
157
- @excel.visible = options[:visible] unless options[:visible].nil?
158
- @excel.displayalerts = options[:displayalerts] unless options[:displayalerts].nil?
159
- end
160
-
161
158
  private
162
159
 
163
160
  # returns an Excel object when given Excel, Book or Win32ole object representing a Workbook or an Excel
@@ -187,16 +184,14 @@ module RobustExcelOle
187
184
  def ensure_excel(options) # :nodoc: #
188
185
  return if @excel && @excel.alive?
189
186
  options[:excel] = options[:force_excel] ? options[:force_excel] : options[:default_excel]
190
- options[:excel] = :active if options[:excel == :reuse]
191
- excel_options = {:displayalerts => false, :visible => false}.merge(options)
192
- excel_options[:reuse] = (options[:excel] == :active)
193
- @excel = self.class.excel_of(options[:excel]) unless (options[:excel] == :active || options[:excel] == :new)
194
- @excel = excel_class.new(excel_options) unless (@excel && @excel.alive?)
195
- apply_options unless excel_options
196
- end
187
+ options[:excel] = :current if (options[:excel] == :reuse || options[:excel] == :active)
188
+ @excel = self.class.excel_of(options[:excel]) unless (options[:excel] == :current || options[:excel] == :new)
189
+ @excel = excel_class.new(:reuse => (options[:excel] == :current)) unless (@excel && @excel.alive?)
190
+ end
197
191
 
198
192
  def ensure_workbook(file, options) # :nodoc: #
199
193
  file = @stored_filename ? @stored_filename : file
194
+ raise(ExcelErrorOpen, "filename is nil") if file.nil?
200
195
  unless File.exist?(file)
201
196
  if options[:if_absent] == :create
202
197
  @ole_workbook = excel_class.current.generate_workbook(file)
@@ -231,7 +226,7 @@ module RobustExcelOle
231
226
  open_or_create_workbook(file, options)
232
227
  end
233
228
  when :new_excel
234
- excel_options = {:displayalerts => false, :visible => false}.merge(options)
229
+ excel_options = {:visible => false}.merge(options)
235
230
  excel_options[:reuse] = false
236
231
  @excel = excel_class.new(excel_options)
237
232
  open_or_create_workbook(file, options)
@@ -255,7 +250,7 @@ module RobustExcelOle
255
250
  open_or_create_workbook(file,options)
256
251
  end
257
252
  when :new_excel
258
- excel_options = {:displayalerts => false, :visible => false}.merge(options)
253
+ excel_options = {:visible => false}.merge(options)
259
254
  excel_options[:reuse] = false
260
255
  @excel = excel_class.new(excel_options)
261
256
  open_or_create_workbook(file, options)
@@ -294,10 +289,19 @@ module RobustExcelOle
294
289
  # delay: with visible: 0.2 sec, without visible almost none
295
290
  count = workbooks.Count
296
291
  workbooks.Add if @excel.Version == "12.0" && count == 0
297
- workbooks.Open(filename,{ 'ReadOnly' => options[:read_only] })
298
- workbooks.Item(1).Close if @excel.Version == "12.0" && count == 0
299
- workbooks.Item(1).CheckCompatibility = options[:check_compatibility]
300
- @can_be_closed = false if @can_be_closed.nil?
292
+ update_links_opt =
293
+ case options[:update_links]
294
+ when :alert; RobustExcelOle::XlUpdateLinksUserSetting
295
+ when :never; RobustExcelOle::XlUpdateLinksNever
296
+ when :always; RobustExcelOle::XlUpdateLinksAlways
297
+ else RobustExcelOle::XlUpdateLinksNever
298
+ end
299
+ @excel.with_displayalerts(update_links_opt == :alert ? true : @excel.displayalerts) do
300
+ # ??? determining update_links_opt here does not work, it is always XlUpdateLinksNever afterwords
301
+ workbooks.Open(filename, { 'ReadOnly' => options[:read_only] , 'UpdateLinks' => update_links_opt } )
302
+ end
303
+ workbooks.Open(filename, { 'ReadOnly' => options[:read_only] } )
304
+ workbooks.Item(1).Close if @excel.Version == "12.0" && count == 0
301
305
  rescue WIN32OLERuntimeError => msg
302
306
  trace "WIN32OLERuntimeError: #{msg.message}"
303
307
  if msg.message =~ /800A03EC/
@@ -307,12 +311,13 @@ module RobustExcelOle
307
311
  end
308
312
  end
309
313
  begin
310
- # workaround for bug in Excel 2010: workbook.Open does not always return
311
- # the workbook with given file name
312
- @ole_workbook = workbooks.Item(File.basename(filename))
314
+ # workaround for bug in Excel 2010: workbook.Open does not always return the workbook with given file name
315
+ @ole_workbook = workbooks.Item(File.basename(filename))
316
+ self.visible = options[:visible] unless options[:visible].nil?
317
+ @ole_workbook.UpdateLinks = update_links_opt
313
318
  rescue WIN32OLERuntimeError
314
319
  raise ExcelErrorOpen, "cannot find the file #{File.basename(filename).inspect}"
315
- end
320
+ end
316
321
  end
317
322
  end
318
323
 
@@ -385,34 +390,30 @@ module RobustExcelOle
385
390
  # @param [String] file the file name
386
391
  # @param [Hash] if_closed an option
387
392
  # @param [Hash] opts the options
388
- # @option opts [Variant] :if_closed :active or :reuse (default), :hidden or a Excel instance
393
+ # @option opts [Variant] :if_closed :current (or :reuse, :active) (default), :hidden or a Excel instance
389
394
  # @option opts [Boolean] :read_only whether the file is opened for read-only
390
395
  # @option opts [Boolean] :readonly_excel behaviour when workbook is opened read-only and shall be modified
391
396
  # @option opts [Boolean] :keep_open whether the workbook shall be kept open after unobtrusively opening
392
- # @option opts [Boolean] :displayalerts true, or false (default)
393
397
  # @option opts [Boolean] :visible true, or false (default)
394
398
  # options:
395
399
  # :if_closed : if the workbook is closed, then open it in
396
- # :active or :reuse -> the Excel instance of the workbook, if it exists,
397
- # reuse another Excel, otherwise
400
+ # :current (or :active, :reuse) -> the Excel instance of the workbook, if it exists,
401
+ # reuse another Excel, otherwise
398
402
  # :hidden -> a separate Excel instance that is not visible and has no displayaslerts
399
403
  # <excel-instance> -> the given Excel instance
400
- # :read_only : opens the workbook unobtrusively for reading only (default: false)
401
404
  # :readonly_excel: if the workbook is opened only as ReadOnly and shall be modified, then
402
405
  # true: closes it and open it as writable in the Excel instance where it was open so far
403
406
  # false (default) opens it as writable in another running excel instance, if it exists,
404
407
  # otherwise open in a new Excel instance.
405
- # :displayalerts enables DisplayAlerts in Excel
406
- # :visible makes visible in Excel
407
- # :check_compatibility checks compatibility when saving
408
+ # :visible, :readl_only, :update_links, :check_compatibility : see options in #open
408
409
  # @return [Book] a workbook
409
410
  def self.unobtrusively(file, if_closed = nil, opts = { }, &block)
410
411
  if if_closed.is_a? Hash
411
412
  opts = if_closed
412
413
  if_closed = nil
413
414
  end
414
- if_closed = :active if if_closed == :reuse
415
- if_closed = :active unless if_closed
415
+ if_closed = :current if (if_closed == :reuse || if_closed == :active)
416
+ if_closed = :current unless if_closed
416
417
  options = {
417
418
  :read_only => false,
418
419
  :readonly_excel => false,
@@ -435,8 +436,8 @@ module RobustExcelOle
435
436
  book =
436
437
  if was_not_alive_or_nil
437
438
  case if_closed
438
- when :active
439
- open(file, :read_only => options[:read_only])
439
+ when :current
440
+ open(file, :default_excel => :current, :read_only => options[:read_only])
440
441
  when :hidden
441
442
  open(file, :force_excel => bookstore.hidden_excel, :read_only => options[:read_only])
442
443
  else
@@ -450,7 +451,6 @@ module RobustExcelOle
450
451
  open(file, :force_excel => :new, :read_only => options[:read_only])
451
452
  end
452
453
  end
453
- book.excel.displayalerts = options[:displayalerts] unless options[:displayalerts].nil?
454
454
  book.excel.visible = options[:visible] unless options[:visible].nil?
455
455
  old_check_compatibility = book.CheckCompatibility
456
456
  book.CheckCompatibility = options[:check_compatibility]
@@ -477,7 +477,7 @@ module RobustExcelOle
477
477
  # @raise ExcelErrorSave if workbook is not alive or opened for read-only, or another error occurs
478
478
  # @return [Boolean] true, if successfully saved, nil otherwise
479
479
  def save
480
- raise ExcelErrorSave, "Workbook is not alive" if (not alive?)
480
+ raise ExcelErrorSave, "workbook is not alive" if (not alive?)
481
481
  raise ExcelErrorSave, "Not opened for writing (opened with :read_only option)" if @ole_workbook.ReadOnly
482
482
  begin
483
483
  @ole_workbook.Save
@@ -511,8 +511,9 @@ module RobustExcelOle
511
511
  # the file already exists (with option :if_exists :raise),
512
512
  # the workbook is blocked by another one (with option :if_obstructed :raise)
513
513
  # @return [Book], the book itself, if successfully saved, raises an exception otherwise
514
- def save_as(file = nil, opts = { } )
515
- raise ExcelErrorSave, "Workbook is not alive" if (not alive?)
514
+ def save_as(file, opts = { } )
515
+ raise(ExcelErrorSave, "filename is nil") if file.nil?
516
+ raise ExcelErrorSave, "workbook is not alive" if (not alive?)
516
517
  raise ExcelErrorSave, "Not opened for writing (opened with :read_only option)" if @ole_workbook.ReadOnly
517
518
  options = {
518
519
  :if_exists => :raise,
@@ -704,16 +705,20 @@ module RobustExcelOle
704
705
  # returns the contents of a range with given name
705
706
  # evaluates formula contents of the range is a formula
706
707
  # if no contents could be returned, then return default value, if provided, raise error otherwise
708
+ # Excel Bug: if a local name without a qualifier is given, then by default Excel takes the first worksheet,
709
+ # even if a different worksheet is active
707
710
  # @param [String] name the name of the range
708
711
  # @param [Hash] opts the options
709
712
  # @option opts [Symbol] :default the default value that is provided if no contents could be returned
710
713
  # @raise ExcelError if range name is not in the workbook or if range value could not be evaluated
711
714
  # @return [Variant] the contents of a range with given name
715
+
712
716
  def nameval(name, opts = {:default => nil})
717
+ default_val = opts[:default]
713
718
  begin
714
719
  name_obj = self.Names.Item(name)
715
720
  rescue WIN32OLERuntimeError
716
- return opts[:default] if opts[:default]
721
+ return default_val if default_val
717
722
  raise ExcelError, "name #{name.inspect} not in #{File.basename(self.stored_filename).inspect}"
718
723
  end
719
724
  begin
@@ -722,15 +727,15 @@ module RobustExcelOle
722
727
  begin
723
728
  value = self.sheet(1).Evaluate(name_obj.Name)
724
729
  rescue WIN32OLERuntimeError
725
- return opts[:default] if opts[:default]
726
- raise SheetError, "cannot evaluate name #{name.inspect} in #{File.basename(self.stored_filename).inspect}"
730
+ return default_val if default_val
731
+ raise ExcelError, "cannot evaluate name #{name.inspect} in #{File.basename(self.stored_filename).inspect}"
727
732
  end
728
733
  end
729
- if value == -2146826259
730
- return opts[:default] if opts[:default]
731
- raise SheetError, "cannot evaluate name #{name.inspect} in #{File.basename(self.stored_filename).inspect}"
734
+ if value == RobustExcelOle::XlErrName # -2146826259
735
+ return default_val if default_val
736
+ raise ExcelError, "cannot evaluate name #{name.inspect} in #{File.basename(self.stored_filename).inspect}"
732
737
  end
733
- return opts[:default] if (value.nil? && opts[:default])
738
+ return default_val if default_val && value.nil?
734
739
  value
735
740
  end
736
741
 
@@ -782,15 +787,16 @@ module RobustExcelOle
782
787
 
783
788
  # returns true, if the workbook is visible, false otherwise
784
789
  def visible
785
- @excel.Windows(@ole_workbook.Name).Visible
790
+ @excel.visible && @ole_workbook.Windows(@ole_workbook.Name).Visible
786
791
  end
787
792
 
788
- # makes a workbook visible or invisible
793
+ # makes the window of the workbook visible or invisible
789
794
  # @param [Boolean] visible_value value that determines whether the workbook shall be visible
790
795
  def visible= visible_value
791
796
  saved = @ole_workbook.Saved
792
- @excel.Windows(@ole_workbook.Name).Visible = visible_value
793
- save if saved
797
+ @excel.visible = true if visible_value
798
+ @ole_workbook.Windows(@ole_workbook.Name).Visible = visible_value if @excel.Visible
799
+ save if saved && (not self.ReadOnly)
794
800
  end
795
801
 
796
802
  # returns true, if the workbook reacts to methods, false otherwise
@@ -837,7 +843,7 @@ module RobustExcelOle
837
843
  self.class.bookstore
838
844
  end
839
845
 
840
- def self.show_books # :nodoc: #
846
+ def self.all_books # :nodoc: #
841
847
  bookstore.books
842
848
  end
843
849