robust_excel_ole 0.5.1 → 0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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