robust_excel_ole 1.15 → 1.18.2
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.
- checksums.yaml +4 -4
- data/Changelog +27 -0
- data/README.rdoc +18 -1
- data/___dummy_workbook.xls +0 -0
- data/docs/README_excel.rdoc +6 -0
- data/docs/README_open.rdoc +18 -2
- data/docs/README_ranges.rdoc +11 -2
- data/examples/example_ruby_library.rb +27 -0
- data/extconf.rb +13 -0
- data/lib/robust_excel_ole.rb +4 -3
- data/lib/robust_excel_ole/{address.rb → address_tool.rb} +23 -22
- data/lib/robust_excel_ole/{reo_common.rb → base.rb} +2 -90
- data/lib/robust_excel_ole/bookstore.rb +14 -77
- data/lib/robust_excel_ole/cell.rb +30 -18
- data/lib/robust_excel_ole/excel.rb +71 -41
- data/lib/robust_excel_ole/general.rb +39 -14
- data/lib/robust_excel_ole/range.rb +42 -19
- data/lib/robust_excel_ole/range_owners.rb +40 -25
- data/lib/robust_excel_ole/vba_objects.rb +30 -0
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +241 -235
- data/lib/robust_excel_ole/worksheet.rb +42 -21
- data/lib/rubygems_plugin.rb +3 -0
- data/robust_excel_ole.gemspec +1 -0
- data/spec/address_tool_spec.rb +175 -0
- data/spec/{reo_common_spec.rb → base_spec.rb} +11 -30
- data/spec/bookstore_spec.rb +3 -3
- data/spec/cell_spec.rb +67 -25
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +41 -275
- data/spec/general_spec.rb +17 -23
- data/spec/range_spec.rb +57 -3
- data/spec/workbook_spec.rb +7 -75
- data/spec/workbook_specs/workbook_misc_spec.rb +11 -21
- data/spec/workbook_specs/workbook_open_spec.rb +570 -30
- data/spec/workbook_specs/workbook_unobtr_spec.rb +33 -33
- data/spec/worksheet_spec.rb +36 -4
- metadata +10 -6
- data/spec/address_spec.rb +0 -174
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module RobustExcelOle
|
4
4
|
|
5
|
-
class RangeOwners <
|
5
|
+
class RangeOwners < VbaObjects
|
6
6
|
|
7
7
|
# returns the contents of a range with given name
|
8
8
|
# if the name could not be found or the value could not be determined,
|
@@ -22,12 +22,13 @@ module RobustExcelOle
|
|
22
22
|
raise
|
23
23
|
end
|
24
24
|
ole_range = name_obj.RefersToRange
|
25
|
+
worksheet = self if self.is_a?(Worksheet)
|
25
26
|
value = begin
|
26
27
|
#name_obj.RefersToRange.Value
|
27
|
-
if !::
|
28
|
+
if !::RANGES_JRUBY_BUG
|
28
29
|
ole_range.Value
|
29
30
|
else
|
30
|
-
values = RobustExcelOle::Range.new(ole_range).v
|
31
|
+
values = RobustExcelOle::Range.new(ole_range, worksheet).v
|
31
32
|
(values.size==1 && values.first.size==1) ? values.first.first : values
|
32
33
|
end
|
33
34
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
@@ -39,10 +40,10 @@ module RobustExcelOle
|
|
39
40
|
#sheet.Evaluate(name_obj.Name).Value
|
40
41
|
# does it result in a range?
|
41
42
|
ole_range = sheet.Evaluate(name_obj.Name)
|
42
|
-
if !::
|
43
|
+
if !::RANGES_JRUBY_BUG
|
43
44
|
ole_range.Value
|
44
45
|
else
|
45
|
-
values = RobustExcelOle::Range.new(ole_range).v
|
46
|
+
values = RobustExcelOle::Range.new(ole_range, worksheet).v
|
46
47
|
(values.size==1 && values.first.size==1) ? values.first.first : values
|
47
48
|
end
|
48
49
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
@@ -61,7 +62,8 @@ module RobustExcelOle
|
|
61
62
|
# sets the contents of a range
|
62
63
|
# @param [String] name the name of a range
|
63
64
|
# @param [Variant] value the contents of the range
|
64
|
-
|
65
|
+
# @option opts [Symbol] :color the color of the cell when set
|
66
|
+
def set_namevalue_glob(name, value, opts = { })
|
65
67
|
begin
|
66
68
|
name_obj = begin
|
67
69
|
name_object(name)
|
@@ -69,13 +71,12 @@ module RobustExcelOle
|
|
69
71
|
raise
|
70
72
|
end
|
71
73
|
ole_range = name_object(name).RefersToRange
|
72
|
-
|
73
|
-
|
74
|
-
if !::JRUBY_BUG_RANGES
|
74
|
+
ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
|
75
|
+
if !::RANGES_JRUBY_BUG
|
75
76
|
ole_range.Value = value
|
76
77
|
else
|
77
78
|
address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
|
78
|
-
row, col =
|
79
|
+
row, col = address_tool.as_integer_ranges(address_r1c1)
|
79
80
|
row.each_with_index do |r,i|
|
80
81
|
col.each_with_index do |c,j|
|
81
82
|
ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value )
|
@@ -105,11 +106,12 @@ module RobustExcelOle
|
|
105
106
|
raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
|
106
107
|
end
|
107
108
|
begin
|
109
|
+
worksheet = self if self.is_a?(Worksheet)
|
108
110
|
#value = ole_range.Value
|
109
|
-
value = if !::
|
111
|
+
value = if !::RANGES_JRUBY_BUG
|
110
112
|
ole_range.Value
|
111
113
|
else
|
112
|
-
values = RobustExcelOle::Range.new(ole_range).v
|
114
|
+
values = RobustExcelOle::Range.new(ole_range, worksheet).v
|
113
115
|
(values.size==1 && values.first.size==1) ? values.first.first : values
|
114
116
|
end
|
115
117
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
@@ -127,21 +129,21 @@ module RobustExcelOle
|
|
127
129
|
# assigns a value to a range given a locally defined name
|
128
130
|
# @param [String] name the name of a range
|
129
131
|
# @param [Variant] value the assigned value
|
130
|
-
|
132
|
+
# @option opts [Symbol] :color the color of the cell when set
|
133
|
+
def set_namevalue(name, value, opts = { })
|
131
134
|
begin
|
132
|
-
return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
|
135
|
+
return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
|
133
136
|
ole_range = self.Range(name)
|
134
|
-
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
137
|
+
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
|
135
138
|
raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
|
136
139
|
end
|
137
140
|
begin
|
138
|
-
|
139
|
-
|
140
|
-
if !::JRUBY_BUG_RANGES
|
141
|
+
ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
|
142
|
+
if !::RANGES_JRUBY_BUG
|
141
143
|
ole_range.Value = value
|
142
144
|
else
|
143
145
|
address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
|
144
|
-
row, col =
|
146
|
+
row, col = address_tool.as_integer_ranges(address_r1c1)
|
145
147
|
row.each_with_index do |r,i|
|
146
148
|
col.each_with_index do |c,j|
|
147
149
|
ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value)
|
@@ -180,10 +182,11 @@ module RobustExcelOle
|
|
180
182
|
# @return [Range] a range
|
181
183
|
def range(name_or_address, address2 = :__not_provided)
|
182
184
|
begin
|
185
|
+
worksheet = self if self.is_a?(Worksheet)
|
183
186
|
if address2 == :__not_provided
|
184
187
|
range = if name_or_address.is_a?(String)
|
185
188
|
begin
|
186
|
-
RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange)
|
189
|
+
RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange, worksheet)
|
187
190
|
rescue NameNotFound
|
188
191
|
nil
|
189
192
|
end
|
@@ -192,8 +195,8 @@ module RobustExcelOle
|
|
192
195
|
if self.is_a?(Worksheet) && (range.nil? || (address2 != :__not_provided))
|
193
196
|
address = name_or_address
|
194
197
|
address = [name_or_address,address2] unless address2 == :__not_provided
|
195
|
-
self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' +
|
196
|
-
range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange)
|
198
|
+
self.Names.Add('__dummy001',nil,true,nil,nil,nil,nil,nil,nil,'=' + address_tool.as_r1c1(address))
|
199
|
+
range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange, worksheet)
|
197
200
|
self.Names.Item('__dummy001').Delete
|
198
201
|
workbook = self.is_a?(Workbook) ? self : self.workbook
|
199
202
|
workbook.save
|
@@ -216,7 +219,7 @@ module RobustExcelOle
|
|
216
219
|
def add_name(name, addr, addr_deprecated = :__not_provided)
|
217
220
|
addr = [addr,addr_deprecated] unless addr_deprecated == :__not_provided
|
218
221
|
begin
|
219
|
-
self.Names.Add(name, nil, true, nil, nil, nil, nil, nil, nil, '=' +
|
222
|
+
self.Names.Add(name, nil, true, nil, nil, nil, nil, nil, nil, '=' + address_tool.as_r1c1(addr))
|
220
223
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
221
224
|
raise RangeNotEvaluatable, "cannot add name #{name.inspect} to range #{addr.inspect}"
|
222
225
|
end
|
@@ -257,13 +260,13 @@ module RobustExcelOle
|
|
257
260
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
258
261
|
raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
|
259
262
|
end
|
260
|
-
end
|
263
|
+
end
|
261
264
|
|
262
265
|
private
|
263
266
|
|
264
267
|
def name_object(name)
|
265
268
|
self.Names.Item(name)
|
266
|
-
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
269
|
+
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
|
267
270
|
begin
|
268
271
|
self.Parent.Names.Item(name)
|
269
272
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
|
@@ -273,4 +276,16 @@ module RobustExcelOle
|
|
273
276
|
|
274
277
|
end
|
275
278
|
|
279
|
+
# @private
|
280
|
+
class NameNotFound < NamesREOError
|
281
|
+
end
|
282
|
+
|
283
|
+
# @private
|
284
|
+
class NameAlreadyExists < NamesREOError
|
285
|
+
end
|
286
|
+
|
287
|
+
# @private
|
288
|
+
class RangeNotCreated < MiscREOError
|
289
|
+
end
|
290
|
+
|
276
291
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module RobustExcelOle
|
4
|
+
|
5
|
+
class VbaObjects < Base
|
6
|
+
|
7
|
+
def to_reo
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def address_tool
|
13
|
+
excel.address_tool
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# @private
|
19
|
+
class RangeNotEvaluatable < MiscREOError
|
20
|
+
end
|
21
|
+
|
22
|
+
# @private
|
23
|
+
class OptionInvalid < MiscREOError
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
class ObjectNotAlive < MiscREOError
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -12,32 +12,33 @@ module RobustExcelOle
|
|
12
12
|
class Workbook < RangeOwners
|
13
13
|
|
14
14
|
#include General
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
attr_accessor :color_if_modified
|
20
|
-
attr_accessor :was_open
|
15
|
+
|
16
|
+
attr_reader :ole_workbook
|
17
|
+
attr_reader :excel
|
18
|
+
attr_reader :stored_filename
|
21
19
|
|
22
20
|
alias ole_object ole_workbook
|
23
21
|
|
24
|
-
|
25
|
-
:default => {:excel => :current},
|
22
|
+
CORE_DEFAULT_OPEN_OPTS = {
|
23
|
+
:default => {:excel => :current},
|
26
24
|
:force => {},
|
27
|
-
:update_links => :never
|
25
|
+
:update_links => :never
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
DEFAULT_OPEN_OPTS = {
|
28
29
|
:if_unsaved => :raise,
|
29
30
|
:if_obstructed => :raise,
|
30
31
|
:if_absent => :raise,
|
31
32
|
:if_exists => :raise
|
32
|
-
|
33
|
-
}.freeze
|
33
|
+
}.merge(CORE_DEFAULT_OPEN_OPTS).freeze
|
34
34
|
|
35
|
-
|
36
|
-
:default
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
ABBREVIATIONS = [
|
36
|
+
[:default,:d],
|
37
|
+
[:force, :f],
|
38
|
+
[:excel, :e],
|
39
|
+
[:visible, :v],
|
40
|
+
[:if_obstructed, :if_blocked]
|
41
|
+
].freeze
|
41
42
|
|
42
43
|
|
43
44
|
# opens a workbook.
|
@@ -83,51 +84,59 @@ module RobustExcelOle
|
|
83
84
|
# :visible true -> makes the workbook visible
|
84
85
|
# :check_compatibility true -> check compatibility when saving
|
85
86
|
# :update_links true -> user is being asked how to update links, false -> links are never updated
|
86
|
-
# @return [Workbook] a representation of a workbook
|
87
|
-
def self.new(file_or_workbook, opts = { }
|
88
|
-
|
89
|
-
|
87
|
+
# @return [Workbook] a representation of a workbook
|
88
|
+
def self.new(file_or_workbook, opts = { })
|
89
|
+
process_options(opts)
|
90
|
+
case file_or_workbook
|
91
|
+
when NilClass
|
92
|
+
raise FileNameNotGiven, 'filename is nil'
|
93
|
+
when WIN32OLE
|
90
94
|
file = file_or_workbook.Fullname.tr('\\','/')
|
91
|
-
|
95
|
+
when Workbook
|
96
|
+
file = file_or_workbook.Fullname.tr('\\','/')
|
97
|
+
when String
|
92
98
|
file = file_or_workbook
|
93
|
-
raise
|
94
|
-
|
99
|
+
raise FileNotFound, "file #{General.absolute_path(file).inspect} is a directory" if File.directory?(file)
|
100
|
+
else
|
101
|
+
raise TypeREOError, 'given object is neither a filename, a Win32ole, nor a Workbook object'
|
95
102
|
end
|
96
103
|
# try to fetch the workbook from the bookstore
|
104
|
+
set_was_open opts, file_or_workbook.is_a?(WIN32OLE)
|
97
105
|
book = nil
|
98
|
-
if
|
106
|
+
if opts[:force][:excel] != :new
|
99
107
|
# if readonly is true, then prefer a book that is given in force_excel if this option is set
|
100
|
-
forced_excel =
|
101
|
-
(
|
102
|
-
(excel_class.new(:reuse => true) if !::
|
108
|
+
forced_excel = begin
|
109
|
+
(opts[:force][:excel].nil? || opts[:force][:excel] == :current) ?
|
110
|
+
(excel_class.new(:reuse => true) if !::CONNECT_JRUBY_BUG) : opts[:force][:excel].to_reo.excel
|
111
|
+
rescue NoMethodError
|
112
|
+
raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
|
113
|
+
end
|
103
114
|
begin
|
104
115
|
book = if File.exists?(file)
|
105
|
-
bookstore.fetch(file, :prefer_writable => !(
|
106
|
-
:prefer_excel => (
|
116
|
+
bookstore.fetch(file, :prefer_writable => !(opts[:read_only]),
|
117
|
+
:prefer_excel => (opts[:read_only] ? forced_excel : nil))
|
107
118
|
end
|
108
119
|
rescue
|
109
|
-
|
120
|
+
raise
|
121
|
+
#trace "#{$!.message}"
|
110
122
|
end
|
111
123
|
if book
|
112
|
-
|
113
|
-
book.was_open = book.alive? unless file_or_workbook.is_a? WIN32OLE
|
124
|
+
set_was_open opts, book.alive?
|
114
125
|
# drop the fetched workbook if it shall be opened in another Excel instance
|
115
126
|
# or the workbook is an unsaved workbook that should not be accepted
|
116
|
-
if (
|
117
|
-
!(book.alive? && !book.saved && (
|
118
|
-
|
119
|
-
book.ensure_workbook(file,
|
120
|
-
book.
|
127
|
+
if (opts[:force][:excel].nil? || opts[:force][:excel] == :current || forced_excel == book.excel) &&
|
128
|
+
!(book.alive? && !book.saved && (opts[:if_unsaved] != :accept))
|
129
|
+
opts[:force][:excel] = book.excel if book.excel && book.excel.alive?
|
130
|
+
book.ensure_workbook(file,opts)
|
131
|
+
book.send :apply_options, file, opts
|
121
132
|
return book
|
122
133
|
end
|
123
134
|
end
|
124
135
|
end
|
125
|
-
super(file_or_workbook,
|
136
|
+
super(file_or_workbook, opts)
|
126
137
|
end
|
127
138
|
|
128
|
-
|
129
|
-
new(file_or_workbook, opts, &block)
|
130
|
-
end
|
139
|
+
singleton_class.send :alias_method, :open, :new
|
131
140
|
|
132
141
|
# creates a new Workbook object, if a file name is given
|
133
142
|
# Promotes the win32ole workbook to a Workbook object, if a win32ole-workbook is given
|
@@ -135,25 +144,23 @@ module RobustExcelOle
|
|
135
144
|
# @param [Hash] opts
|
136
145
|
# @option opts [Symbol] see above
|
137
146
|
# @return [Workbook] a workbook
|
138
|
-
def initialize(file_or_workbook,
|
147
|
+
def initialize(file_or_workbook, opts)
|
139
148
|
if file_or_workbook.is_a? WIN32OLE
|
140
149
|
@ole_workbook = file_or_workbook
|
141
|
-
ole_excel = begin
|
142
|
-
|
143
|
-
rescue
|
150
|
+
ole_excel = begin
|
151
|
+
@ole_workbook.Application
|
152
|
+
rescue WIN32OLERuntimeError
|
144
153
|
raise ExcelREOError, 'could not determine the Excel instance'
|
145
154
|
end
|
146
155
|
@excel = excel_class.new(ole_excel)
|
147
|
-
filename =
|
156
|
+
filename = @ole_workbook.Fullname.tr('\\','/')
|
148
157
|
else
|
149
158
|
filename = file_or_workbook
|
150
|
-
ensure_workbook(filename,
|
159
|
+
ensure_workbook(filename, opts)
|
151
160
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
address_class.new(r1c1_letters)
|
156
|
-
if block
|
161
|
+
apply_options(filename, opts)
|
162
|
+
store_myself
|
163
|
+
if block_given?
|
157
164
|
begin
|
158
165
|
yield self
|
159
166
|
ensure
|
@@ -164,52 +171,46 @@ module RobustExcelOle
|
|
164
171
|
|
165
172
|
private
|
166
173
|
|
167
|
-
|
168
|
-
|
169
|
-
translator = proc do |opts|
|
170
|
-
erg = {}
|
171
|
-
opts.each do |key,value|
|
172
|
-
new_key = key
|
173
|
-
ABBREVIATIONS.each { |long,short| new_key = long if key == short }
|
174
|
-
if value.is_a?(Hash)
|
175
|
-
erg[new_key] = {}
|
176
|
-
value.each do |k,v|
|
177
|
-
new_k = k
|
178
|
-
ABBREVIATIONS.each { |l,s| new_k = l if k == s }
|
179
|
-
erg[new_key][new_k] = v
|
180
|
-
end
|
181
|
-
else
|
182
|
-
erg[new_key] = value
|
183
|
-
end
|
184
|
-
end
|
185
|
-
erg[:default] ||= {}
|
186
|
-
erg[:force] ||= {}
|
187
|
-
force_list = [:visible, :excel]
|
188
|
-
erg.each { |key,value| erg[:force][key] = value if force_list.include?(key) }
|
189
|
-
erg[:default][:excel] = erg[:default_excel] unless erg[:default_excel].nil?
|
190
|
-
erg[:force][:excel] = erg[:force_excel] unless erg[:force_excel].nil?
|
191
|
-
erg[:default][:excel] = :current if erg[:default][:excel] == :reuse || erg[:default][:excel] == :active
|
192
|
-
erg[:force][:excel] = :current if erg[:force][:excel] == :reuse || erg[:force][:excel] == :active
|
193
|
-
erg
|
194
|
-
end
|
195
|
-
opts = translator.call(options)
|
196
|
-
default_open_opts = proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS : CORE_DEFAULT_OPEN_OPTS
|
197
|
-
default_opts = translator.call(default_open_opts)
|
198
|
-
opts = default_opts.merge(opts)
|
199
|
-
opts[:default] = default_opts[:default].merge(opts[:default]) unless opts[:default].nil?
|
200
|
-
opts[:force] = default_opts[:force].merge(opts[:force]) unless opts[:force].nil?
|
201
|
-
opts
|
174
|
+
def self.set_was_open(hash, value)
|
175
|
+
hash[:was_open] = value if hash.has_key?(:was_open)
|
202
176
|
end
|
203
177
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
178
|
+
def set_was_open(hash, value)
|
179
|
+
self.class.set_was_open(hash, value)
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.process_options(opts, proc_opts = {:use_defaults => true})
|
183
|
+
translate(opts)
|
184
|
+
default_opts = (proc_opts[:use_defaults] ? DEFAULT_OPEN_OPTS : CORE_DEFAULT_OPEN_OPTS).dup
|
185
|
+
translate(default_opts)
|
186
|
+
opts.merge!(default_opts) { |key, v1, v2| !v2.is_a?(Hash) ? v1 : v2.merge(v1 || {}) }
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.translate(opts)
|
190
|
+
erg = {}
|
191
|
+
opts.each do |key,value|
|
192
|
+
new_key = key
|
193
|
+
ABBREVIATIONS.each { |long,short| new_key = long if key == short }
|
194
|
+
if value.is_a?(Hash)
|
195
|
+
erg[new_key] = {}
|
196
|
+
value.each do |k,v|
|
197
|
+
new_k = k
|
198
|
+
ABBREVIATIONS.each { |l,s| new_k = l if k == s }
|
199
|
+
erg[new_key][new_k] = v
|
200
|
+
end
|
201
|
+
else
|
202
|
+
erg[new_key] = value
|
203
|
+
end
|
212
204
|
end
|
205
|
+
opts.merge!(erg)
|
206
|
+
opts[:default] ||= {}
|
207
|
+
opts[:force] ||= {}
|
208
|
+
force_list = [:visible, :excel]
|
209
|
+
opts.each { |key,value| opts[:force][key] = value if force_list.include?(key) }
|
210
|
+
opts[:default][:excel] = opts[:default_excel] unless opts[:default_excel].nil?
|
211
|
+
opts[:force][:excel] = opts[:force_excel] unless opts[:force_excel].nil?
|
212
|
+
opts[:default][:excel] = :current if opts[:default][:excel] == :reuse || opts[:default][:excel] == :active
|
213
|
+
opts[:force][:excel] = :current if opts[:force][:excel] == :reuse || opts[:force][:excel] == :active
|
213
214
|
end
|
214
215
|
|
215
216
|
public
|
@@ -218,20 +219,25 @@ module RobustExcelOle
|
|
218
219
|
# ensures an excel but not for jruby if current Excel shall be used
|
219
220
|
def ensure_excel(options)
|
220
221
|
return if @excel && @excel.alive?
|
221
|
-
excel_option = options[:force][:excel]
|
222
|
+
excel_option = options[:force][:excel] || options[:default][:excel] || :current
|
222
223
|
@excel = if excel_option == :new
|
223
224
|
excel_class.new(:reuse => false)
|
224
|
-
elsif excel_option
|
225
|
+
elsif excel_option == :current
|
225
226
|
excel_class.new(:reuse => true)
|
227
|
+
elsif excel_option.respond_to?(:to_reo)
|
228
|
+
excel_option.to_reo.excel
|
226
229
|
else
|
227
|
-
|
230
|
+
raise TypeREOError, "provided Excel option value is neither an Excel object nor a valid option"
|
228
231
|
end
|
229
|
-
raise ExcelREOError, "
|
232
|
+
raise ExcelREOError, "Excel is not alive" unless @excel && @excel.alive?
|
230
233
|
end
|
231
234
|
|
235
|
+
|
232
236
|
# @private
|
233
237
|
def ensure_workbook(filename, options)
|
238
|
+
set_was_open options, true
|
234
239
|
return if (@ole_workbook && alive? && (options[:read_only].nil? || @ole_workbook.ReadOnly == options[:read_only]))
|
240
|
+
set_was_open options, false
|
235
241
|
if options[:if_unsaved]==:accept &&
|
236
242
|
((options[:read_only]==true && self.ReadOnly==false) || (options[:read_only]==false && self.ReadOnly==true))
|
237
243
|
raise OptionInvalid, ":if_unsaved:accept and change of read-only mode is not possible"
|
@@ -242,27 +248,28 @@ module RobustExcelOle
|
|
242
248
|
ensure_excel(options)
|
243
249
|
workbooks = @excel.Workbooks
|
244
250
|
@ole_workbook = workbooks.Item(File.basename(filename)) rescue nil if @ole_workbook.nil?
|
245
|
-
if @ole_workbook
|
246
|
-
|
251
|
+
if @ole_workbook && alive?
|
252
|
+
set_was_open options, true
|
247
253
|
manage_blocking_or_unsaved_workbook(filename,options)
|
248
254
|
open_or_create_workbook(filename,options) if @ole_workbook.ReadOnly != options[:read_only]
|
249
255
|
else
|
250
|
-
if excel_option.nil? || excel_option == :current &&
|
251
|
-
(
|
252
|
-
workbooks_number_before_connect = @excel.Workbooks.Count
|
256
|
+
if (excel_option.nil? || excel_option == :current) &&
|
257
|
+
!(::CONNECT_JRUBY_BUG && filename[0] == '/')
|
253
258
|
connect(filename,options)
|
254
|
-
@was_open = @excel.Workbooks.Count == workbooks_number_before_connect
|
255
259
|
else
|
256
260
|
open_or_create_workbook(filename,options)
|
257
261
|
end
|
258
262
|
end
|
259
263
|
end
|
260
264
|
|
261
|
-
|
262
|
-
|
263
|
-
|
265
|
+
private
|
266
|
+
|
267
|
+
# applies options to workbook named with filename
|
268
|
+
def apply_options(filename, options)
|
269
|
+
# changing read-only mode
|
270
|
+
#ensure_workbook(filename, options) if options[:read_only] && options[:read_only] != @ole_workbook.ReadOnly
|
264
271
|
if (!options[:read_only].nil?) && options[:read_only] != @ole_workbook.ReadOnly
|
265
|
-
ensure_workbook(filename, options)
|
272
|
+
ensure_workbook(filename, options)
|
266
273
|
end
|
267
274
|
retain_saved do
|
268
275
|
self.visible = options[:force][:visible].nil? ? @excel.Visible : options[:force][:visible]
|
@@ -271,40 +278,32 @@ module RobustExcelOle
|
|
271
278
|
end
|
272
279
|
end
|
273
280
|
|
274
|
-
private
|
275
|
-
|
276
|
-
# @private
|
277
281
|
# connects to an unknown workbook
|
278
|
-
def connect(filename,options)
|
279
|
-
|
280
|
-
workbooks_number = if excels_number>0
|
281
|
-
excel_class.current.Workbooks.Count
|
282
|
-
else 0
|
283
|
-
end
|
284
|
-
abs_filename = General.absolute_path(filename)
|
282
|
+
def connect(filename, options)
|
283
|
+
workbooks_number = excel_class.excels_number==0 ? 0 : excel_class.current.Workbooks.Count
|
285
284
|
@ole_workbook = begin
|
286
|
-
WIN32OLE.connect(
|
285
|
+
WIN32OLE.connect(General.absolute_path(filename))
|
287
286
|
rescue
|
288
287
|
if $!.message =~ /moniker/
|
289
|
-
raise WorkbookConnectingBlockingError
|
290
|
-
else
|
291
|
-
raise WorkbookConnectingUnknownError
|
288
|
+
raise WorkbookConnectingBlockingError, "some workbook is blocking when connecting"
|
289
|
+
else
|
290
|
+
raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
|
292
291
|
end
|
293
292
|
end
|
294
293
|
ole_excel = begin
|
295
294
|
@ole_workbook.Application
|
296
295
|
rescue
|
297
296
|
if $!.message =~ /dispid/
|
298
|
-
raise WorkbookConnectingUnsavedError
|
299
|
-
else
|
300
|
-
raise WorkbookConnectingUnknownError
|
297
|
+
raise WorkbookConnectingUnsavedError, "workbook is unsaved when connecting"
|
298
|
+
else
|
299
|
+
raise WorkbookConnectingUnknownError, "unknown error when connecting to a workbook"
|
301
300
|
end
|
302
301
|
end
|
302
|
+
set_was_open options, (ole_excel.Workbooks.Count == workbooks_number)
|
303
303
|
@excel = excel_class.new(ole_excel)
|
304
304
|
end
|
305
305
|
|
306
|
-
|
307
|
-
def manage_nonexisting_file(filename,options)
|
306
|
+
def manage_nonexisting_file(filename, options)
|
308
307
|
return if File.exist?(filename)
|
309
308
|
abs_filename = General.absolute_path(filename)
|
310
309
|
if options[:if_absent] == :create
|
@@ -322,11 +321,12 @@ module RobustExcelOle
|
|
322
321
|
end
|
323
322
|
end
|
324
323
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
324
|
+
def manage_blocking_or_unsaved_workbook(filename, options)
|
325
|
+
filename = General.absolute_path(filename)
|
326
|
+
filename = General.canonize(filename)
|
327
|
+
previous_file = General.canonize(@ole_workbook.Fullname)
|
328
|
+
obstructed_by_other_book = (File.basename(filename) == File.basename(previous_file)) &&
|
329
|
+
(File.dirname(filename) != File.dirname(previous_file))
|
330
330
|
if obstructed_by_other_book
|
331
331
|
# workbook is being obstructed by a workbook with same name and different path
|
332
332
|
manage_blocking_workbook(filename,options)
|
@@ -338,8 +338,7 @@ module RobustExcelOle
|
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
341
|
-
|
342
|
-
def manage_blocking_workbook(filename,options)
|
341
|
+
def manage_blocking_workbook(filename, options)
|
343
342
|
case options[:if_obstructed]
|
344
343
|
when :raise
|
345
344
|
raise WorkbookBlocked, "can't open workbook #{filename},
|
@@ -353,7 +352,8 @@ module RobustExcelOle
|
|
353
352
|
manage_saving_workbook(filename, options)
|
354
353
|
when :close_if_saved
|
355
354
|
if !@ole_workbook.Saved
|
356
|
-
raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}"
|
355
|
+
raise WorkbookBlocked, "workbook with the same name in a different path is unsaved: #{@ole_workbook.Fullname.tr('\\','/')}" +
|
356
|
+
"\nHint: Use the option :if_blocked => :save to save the workbook"
|
357
357
|
else
|
358
358
|
manage_forgetting_workbook(filename, options)
|
359
359
|
end
|
@@ -365,15 +365,14 @@ module RobustExcelOle
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
-
|
369
|
-
def manage_unsaved_workbook(filename,options)
|
368
|
+
def manage_unsaved_workbook(filename, options)
|
370
369
|
case options[:if_unsaved]
|
371
370
|
when :raise
|
372
371
|
raise WorkbookNotSaved, "workbook is already open but not saved: #{File.basename(filename).inspect}" +
|
373
372
|
"\nHint: Save the workbook or open the workbook using option :if_unsaved with values :forget and :accept to
|
374
373
|
close the unsaved workbook and reopen it, or to let the unsaved workbook open, respectively"
|
375
374
|
when :forget
|
376
|
-
manage_forgetting_workbook(filename,options)
|
375
|
+
manage_forgetting_workbook(filename, options)
|
377
376
|
when :accept
|
378
377
|
# do nothing
|
379
378
|
when :save
|
@@ -388,34 +387,29 @@ module RobustExcelOle
|
|
388
387
|
end
|
389
388
|
end
|
390
389
|
|
391
|
-
# @private
|
392
390
|
def manage_forgetting_workbook(filename, options)
|
393
391
|
@excel.with_displayalerts(false) { @ole_workbook.Close }
|
394
392
|
@ole_workbook = nil
|
395
393
|
open_or_create_workbook(filename, options)
|
396
394
|
end
|
397
395
|
|
398
|
-
# @private
|
399
396
|
def manage_saving_workbook(filename, options)
|
400
397
|
save unless @ole_workbook.Saved
|
401
398
|
manage_forgetting_workbook(filename, options)
|
402
399
|
end
|
403
400
|
|
404
|
-
# @private
|
405
401
|
def manage_new_excel(filename, options)
|
406
402
|
@excel = excel_class.new(:reuse => false)
|
407
403
|
@ole_workbook = nil
|
408
404
|
open_or_create_workbook(filename, options)
|
409
405
|
end
|
410
406
|
|
411
|
-
# @private
|
412
407
|
def open_or_create_workbook(filename, options)
|
413
408
|
return if @ole_workbook && options[:if_unsaved] != :alert && options[:if_unsaved] != :excel &&
|
414
409
|
(options[:read_only].nil? || options[:read_only]==@ole_workbook.ReadOnly )
|
415
410
|
begin
|
416
411
|
abs_filename = General.absolute_path(filename)
|
417
412
|
begin
|
418
|
-
@was_open = false if @was_open.nil?
|
419
413
|
workbooks = @excel.Workbooks
|
420
414
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
421
415
|
raise UnexpectedREOError, "cannot access workbooks: #{msg.message} #{msg.backtrace}"
|
@@ -427,7 +421,7 @@ module RobustExcelOle
|
|
427
421
|
updatelinks_vba(options[:update_links]),
|
428
422
|
options[:read_only] )
|
429
423
|
end
|
430
|
-
rescue WIN32OLERuntimeError => msg
|
424
|
+
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
431
425
|
# for Excel2007: for option :if_unsaved => :alert and user cancels: this error appears?
|
432
426
|
# if yes: distinguish these events
|
433
427
|
raise UnexpectedREOError, "cannot open workbook: #{msg.message} #{msg.backtrace}"
|
@@ -436,29 +430,27 @@ module RobustExcelOle
|
|
436
430
|
# workaround for bug in Excel 2010: workbook.Open does not always return the workbook when given file name
|
437
431
|
begin
|
438
432
|
@ole_workbook = workbooks.Item(File.basename(filename))
|
439
|
-
rescue WIN32OLERuntimeError => msg
|
433
|
+
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
440
434
|
raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message}"
|
441
435
|
end
|
442
|
-
rescue WIN32OLERuntimeError => msg
|
436
|
+
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
443
437
|
raise UnexpectedREOError, "WIN32OLERuntimeError: #{msg.message} #{msg.backtrace}"
|
444
438
|
end
|
445
439
|
end
|
446
440
|
end
|
447
441
|
|
448
|
-
# @private
|
449
442
|
# translating the option UpdateLinks from REO to VBA
|
450
443
|
# setting UpdateLinks works only if calculation mode is automatic,
|
451
444
|
# parameter 'UpdateLinks' has no effect
|
452
445
|
def updatelinks_vba(updatelinks_reo)
|
453
446
|
case updatelinks_reo
|
454
|
-
when :alert
|
455
|
-
when :never
|
447
|
+
when :alert then RobustExcelOle::XlUpdateLinksUserSetting
|
448
|
+
when :never then RobustExcelOle::XlUpdateLinksNever
|
456
449
|
when :always then RobustExcelOle::XlUpdateLinksAlways
|
457
|
-
else
|
450
|
+
else RobustExcelOle::XlUpdateLinksNever
|
458
451
|
end
|
459
452
|
end
|
460
453
|
|
461
|
-
# @private
|
462
454
|
# workaround for linked workbooks for Excel 2007:
|
463
455
|
# opening and closing a dummy workbook if Excel has no workbooks.
|
464
456
|
# delay: with visible: 0.2 sec, without visible almost none
|
@@ -522,13 +514,10 @@ module RobustExcelOle
|
|
522
514
|
else
|
523
515
|
close_workbook
|
524
516
|
end
|
525
|
-
# trace "close: canceled by user" if alive? &&
|
526
|
-
# (opts[:if_unsaved] == :alert || opts[:if_unsaved] == :excel) && (not @ole_workbook.Saved)
|
527
517
|
end
|
528
518
|
|
529
519
|
private
|
530
520
|
|
531
|
-
# @private
|
532
521
|
def close_workbook
|
533
522
|
@ole_workbook.Close if alive?
|
534
523
|
@ole_workbook = nil unless alive?
|
@@ -581,9 +570,10 @@ module RobustExcelOle
|
|
581
570
|
self.class.unobtrusively_opening(file, opts, alive?, &block)
|
582
571
|
end
|
583
572
|
|
584
|
-
|
573
|
+
private
|
574
|
+
|
585
575
|
def self.unobtrusively_opening(file, opts, book_is_alive, &block)
|
586
|
-
|
576
|
+
process_options(opts)
|
587
577
|
opts = {:if_closed => :current, :keep_open => false}.merge(opts)
|
588
578
|
raise OptionInvalid, 'contradicting options' if opts[:writable] && opts[:read_only]
|
589
579
|
if book_is_alive.nil?
|
@@ -598,33 +588,37 @@ module RobustExcelOle
|
|
598
588
|
end
|
599
589
|
open_opts = excel_opts.merge({:if_unsaved => :accept})
|
600
590
|
begin
|
591
|
+
open_opts[:was_open] = nil
|
601
592
|
book = open(file, open_opts)
|
602
593
|
was_visible = book.visible
|
603
594
|
was_writable = book.writable
|
604
595
|
was_saved = book.saved
|
605
596
|
was_check_compatibility = book.check_compatibility
|
606
597
|
was_calculation = book.excel.properties[:calculation]
|
607
|
-
book.
|
598
|
+
book.send :apply_options, file, opts
|
608
599
|
yield book
|
609
600
|
ensure
|
610
601
|
if book && book.alive?
|
611
602
|
do_not_write = opts[:read_only] || opts[:writable]==false
|
612
603
|
book.save unless book.saved || do_not_write || !book.writable
|
613
604
|
if (opts[:read_only] && was_writable) || (!opts[:read_only] && !was_writable)
|
614
|
-
book.
|
615
|
-
|
605
|
+
book.send :apply_options, file, opts.merge({:read_only => !was_writable,
|
606
|
+
:if_unsaved => (opts[:writable]==false ? :forget : :save)})
|
616
607
|
end
|
617
|
-
|
608
|
+
was_open = open_opts[:was_open]
|
609
|
+
if was_open
|
618
610
|
book.visible = was_visible
|
619
611
|
book.CheckCompatibility = was_check_compatibility
|
620
612
|
book.excel.calculation = was_calculation
|
621
613
|
end
|
622
|
-
book.Saved = (was_saved || !
|
623
|
-
book.close unless
|
614
|
+
book.Saved = (was_saved || !was_open)
|
615
|
+
book.close unless was_open || opts[:keep_open]
|
624
616
|
end
|
625
617
|
end
|
626
618
|
end
|
627
619
|
|
620
|
+
public
|
621
|
+
|
628
622
|
# reopens a closed workbook
|
629
623
|
# @options options
|
630
624
|
def reopen(options = { })
|
@@ -638,10 +632,6 @@ module RobustExcelOle
|
|
638
632
|
def save(opts = { }) # option opts is deprecated #
|
639
633
|
raise ObjectNotAlive, 'workbook is not alive' unless alive?
|
640
634
|
raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
|
641
|
-
# if you have open the workbook with :read_only => true,
|
642
|
-
# then you could close the workbook and open it again with option :read_only => false
|
643
|
-
# otherwise the workbook may already be open writable in an another Excel instance
|
644
|
-
# then you could use this workbook or close the workbook there
|
645
635
|
begin
|
646
636
|
@ole_workbook.Save
|
647
637
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
@@ -671,12 +661,12 @@ module RobustExcelOle
|
|
671
661
|
# :close_if_saved -> closes the blocking workbook, if it is saved,
|
672
662
|
# otherwise raises an exception
|
673
663
|
# @return [Workbook], the book itself, if successfully saved, raises an exception otherwise
|
674
|
-
def save_as(file,
|
664
|
+
def save_as(file, options = { })
|
675
665
|
raise FileNameNotGiven, 'filename is nil' if file.nil?
|
676
666
|
raise ObjectNotAlive, 'workbook is not alive' unless alive?
|
677
667
|
raise WorkbookReadOnly, 'Not opened for writing (opened with :read_only option)' if @ole_workbook.ReadOnly
|
678
668
|
raise(FileNotFound, "file #{General.absolute_path(file).inspect} is a directory") if File.directory?(file)
|
679
|
-
|
669
|
+
self.class.process_options(options)
|
680
670
|
if File.exist?(file)
|
681
671
|
case options[:if_exists]
|
682
672
|
when :overwrite
|
@@ -731,7 +721,6 @@ module RobustExcelOle
|
|
731
721
|
|
732
722
|
private
|
733
723
|
|
734
|
-
# @private
|
735
724
|
def save_as_workbook(file, options)
|
736
725
|
dirname, basename = File.split(file)
|
737
726
|
file_format =
|
@@ -741,7 +730,7 @@ module RobustExcelOle
|
|
741
730
|
when '.xlsm' then RobustExcelOle::XlOpenXMLWorkbookMacroEnabled
|
742
731
|
end
|
743
732
|
@ole_workbook.SaveAs(General.absolute_path(file), file_format)
|
744
|
-
|
733
|
+
store_myself
|
745
734
|
rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException => msg
|
746
735
|
if msg.message =~ /SaveAs/ && msg.message =~ /Workbook/
|
747
736
|
# trace "save: canceled by user" if options[:if_exists] == :alert || options[:if_exists] == :excel
|
@@ -751,6 +740,11 @@ module RobustExcelOle
|
|
751
740
|
end
|
752
741
|
end
|
753
742
|
|
743
|
+
def store_myself
|
744
|
+
bookstore.store(self)
|
745
|
+
@stored_filename = filename
|
746
|
+
end
|
747
|
+
|
754
748
|
public
|
755
749
|
|
756
750
|
# closes a given file if it is open
|
@@ -789,12 +783,22 @@ module RobustExcelOle
|
|
789
783
|
raise NameNotFound, "could not return a sheet with name #{name.inspect}"
|
790
784
|
end
|
791
785
|
|
786
|
+
def worksheets_count
|
787
|
+
@ole_workbook.Worksheets.Count
|
788
|
+
end
|
789
|
+
|
792
790
|
def each
|
793
791
|
@ole_workbook.Worksheets.each do |sheet|
|
794
792
|
yield worksheet_class.new(sheet)
|
795
793
|
end
|
796
794
|
end
|
797
795
|
|
796
|
+
def worksheets
|
797
|
+
result = []
|
798
|
+
each { |worksheet| result << worksheet }
|
799
|
+
result
|
800
|
+
end
|
801
|
+
|
798
802
|
def each_with_index(offset = 0)
|
799
803
|
i = offset
|
800
804
|
@ole_workbook.Worksheets.each do |sheet|
|
@@ -819,36 +823,18 @@ module RobustExcelOle
|
|
819
823
|
new_sheet_name = opts.delete(:as)
|
820
824
|
last_sheet_local = last_sheet
|
821
825
|
after_or_before, base_sheet = opts.to_a.first || [:after, last_sheet_local]
|
826
|
+
base_sheet_ole = base_sheet.ole_worksheet
|
822
827
|
begin
|
823
|
-
if !::
|
824
|
-
|
825
|
-
sheet.Copy({ after_or_before.to_s => base_sheet.ole_worksheet })
|
826
|
-
else
|
827
|
-
@ole_workbook.Worksheets.Add({ after_or_before.to_s => base_sheet.ole_worksheet })
|
828
|
-
#@ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
|
829
|
-
end
|
828
|
+
if !::COPYSHEETS_JRUBY_BUG
|
829
|
+
add_or_copy_sheet_simple(sheet, { after_or_before.to_s => base_sheet_ole })
|
830
830
|
else
|
831
831
|
if after_or_before == :before
|
832
|
-
|
833
|
-
sheet.Copy(base_sheet.ole_worksheet)
|
834
|
-
else
|
835
|
-
ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
|
836
|
-
end
|
832
|
+
add_or_copy_sheet_simple(sheet, base_sheet_ole)
|
837
833
|
else
|
838
|
-
#not_given = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_NULL)
|
839
|
-
#ole_workbook.Worksheets.Add(not_given,base_sheet.ole_worksheet)
|
840
834
|
if base_sheet.name != last_sheet_local.name
|
841
|
-
|
842
|
-
sheet.Copy(base_sheet.Next)
|
843
|
-
else
|
844
|
-
ole_workbook.Worksheets.Add(base_sheet.Next)
|
845
|
-
end
|
835
|
+
add_or_copy_sheet_simple(sheet, base_sheet.Next)
|
846
836
|
else
|
847
|
-
|
848
|
-
sheet.Copy(base_sheet.ole_worksheet)
|
849
|
-
else
|
850
|
-
ole_workbook.Worksheets.Add(base_sheet.ole_worksheet)
|
851
|
-
end
|
837
|
+
add_or_copy_sheet_simple(sheet, base_sheet_ole)
|
852
838
|
base_sheet.Move(ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count-1))
|
853
839
|
ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count).Activate
|
854
840
|
end
|
@@ -857,14 +843,23 @@ module RobustExcelOle
|
|
857
843
|
rescue WIN32OLERuntimeError, NameNotFound, Java::OrgRacobCom::ComFailException
|
858
844
|
raise WorksheetREOError, "could not add given worksheet #{sheet.inspect}"
|
859
845
|
end
|
860
|
-
|
861
|
-
ole_sheet = ole_workbook.Activesheet
|
862
|
-
#ole_sheet = ole_sheet.nil? ? ole_workbook.Worksheets.Item(ole_workbook.Worksheets.Count) : ole_sheet
|
863
|
-
new_sheet = worksheet_class.new(ole_sheet)
|
846
|
+
new_sheet = worksheet_class.new(ole_workbook.Activesheet)
|
864
847
|
new_sheet.name = new_sheet_name if new_sheet_name
|
865
848
|
new_sheet
|
866
849
|
end
|
867
850
|
|
851
|
+
private
|
852
|
+
|
853
|
+
def add_or_copy_sheet_simple(sheet, base_sheet_ole_or_hash)
|
854
|
+
if sheet
|
855
|
+
sheet.Copy(base_sheet_ole_or_hash)
|
856
|
+
else
|
857
|
+
ole_workbook.Worksheets.Add(base_sheet_ole_or_hash)
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
public
|
862
|
+
|
868
863
|
# for compatibility to older versions
|
869
864
|
def add_sheet(sheet = nil, opts = { })
|
870
865
|
add_or_copy_sheet(sheet, opts)
|
@@ -894,30 +889,15 @@ module RobustExcelOle
|
|
894
889
|
# @param [String] name the name of the range
|
895
890
|
# @param [Variant] value the contents of the range
|
896
891
|
def []= (name, value)
|
897
|
-
|
898
|
-
workbook.color_if_modified = 42 # 42 - aqua-marin, 4-green
|
899
|
-
set_namevalue_glob(name,value)
|
900
|
-
workbook.color_if_modified = old_color_if_modified
|
892
|
+
set_namevalue_glob(name, value, :color => 42)
|
901
893
|
end
|
902
894
|
|
903
895
|
# sets options
|
904
896
|
# @param [Hash] opts
|
905
897
|
def for_this_workbook(opts)
|
906
898
|
return unless alive?
|
907
|
-
|
908
|
-
|
909
|
-
check_compatibility_before = check_compatibility
|
910
|
-
unless opts[:read_only].nil?
|
911
|
-
# if the ReadOnly status shall be changed, then close and reopen it
|
912
|
-
if (!writable && !(opts[:read_only])) || (writable && opts[:read_only])
|
913
|
-
opts[:check_compatibility] = check_compatibility if opts[:check_compatibility].nil?
|
914
|
-
close(:if_unsaved => true)
|
915
|
-
open_or_create_workbook(@stored_filename, opts)
|
916
|
-
end
|
917
|
-
end
|
918
|
-
self.visible = opts[:force][:visible].nil? ? visible_before : opts[:force][:visible]
|
919
|
-
self.CheckCompatibility = opts[:check_compatibility].nil? ? check_compatibility_before : opts[:check_compatibility]
|
920
|
-
@excel.calculation = opts[:calculation] unless opts[:calculation].nil?
|
899
|
+
self.class.process_options(opts, :use_defaults => false)
|
900
|
+
self.send :apply_options, @stored_filename, opts
|
921
901
|
end
|
922
902
|
|
923
903
|
# brings workbook to foreground, makes it available for heyboard inputs, makes the Excel instance visible
|
@@ -933,7 +913,6 @@ module RobustExcelOle
|
|
933
913
|
true
|
934
914
|
rescue
|
935
915
|
@ole_workbook = nil # dead object won't be alive again
|
936
|
-
# t $!.message
|
937
916
|
false
|
938
917
|
end
|
939
918
|
|
@@ -995,6 +974,7 @@ module RobustExcelOle
|
|
995
974
|
self.filename == other_book.filename
|
996
975
|
end
|
997
976
|
|
977
|
+
# @private
|
998
978
|
def self.books
|
999
979
|
bookstore.books
|
1000
980
|
end
|
@@ -1045,16 +1025,6 @@ module RobustExcelOle
|
|
1045
1025
|
end
|
1046
1026
|
end
|
1047
1027
|
|
1048
|
-
# @private
|
1049
|
-
def self.address_class
|
1050
|
-
@address_class ||= begin
|
1051
|
-
module_name = self.parent_name
|
1052
|
-
"#{module_name}::Address".constantize
|
1053
|
-
rescue NameError => e
|
1054
|
-
Address
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
|
1058
1028
|
# @private
|
1059
1029
|
def excel_class
|
1060
1030
|
self.class.excel_class
|
@@ -1065,11 +1035,6 @@ module RobustExcelOle
|
|
1065
1035
|
self.class.worksheet_class
|
1066
1036
|
end
|
1067
1037
|
|
1068
|
-
# @private
|
1069
|
-
def address_class
|
1070
|
-
self.class.address_class
|
1071
|
-
end
|
1072
|
-
|
1073
1038
|
include MethodHelpers
|
1074
1039
|
|
1075
1040
|
private
|
@@ -1077,7 +1042,7 @@ module RobustExcelOle
|
|
1077
1042
|
def method_missing(name, *args)
|
1078
1043
|
if name.to_s[0,1] =~ /[A-Z]/
|
1079
1044
|
raise ObjectNotAlive, 'method missing: workbook not alive' unless alive?
|
1080
|
-
if ::
|
1045
|
+
if ::ERRORMESSAGE_JRUBY_BUG
|
1081
1046
|
begin
|
1082
1047
|
@ole_workbook.send(name, *args)
|
1083
1048
|
rescue Java::OrgRacobCom::ComFailException
|
@@ -1099,6 +1064,47 @@ module RobustExcelOle
|
|
1099
1064
|
|
1100
1065
|
public
|
1101
1066
|
|
1067
|
+
# @private
|
1068
|
+
class WorkbookBlocked < WorkbookREOError
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
# @private
|
1072
|
+
class WorkbookNotSaved < WorkbookREOError
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
# @private
|
1076
|
+
class WorkbookReadOnly < WorkbookREOError
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
# @private
|
1080
|
+
class WorkbookBeingUsed < WorkbookREOError
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
# @private
|
1084
|
+
class WorkbookConnectingUnsavedError < WorkbookREOError
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
# @private
|
1088
|
+
class WorkbookConnectingBlockingError < WorkbookREOError
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
# @private
|
1092
|
+
class WorkbookConnectingUnknownError < WorkbookREOError
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
# @private
|
1096
|
+
class FileAlreadyExists < FileREOError
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
# @private
|
1100
|
+
class FileNameNotGiven < FileREOError
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
# @private
|
1104
|
+
class FileNotFound < FileREOError
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
|
1102
1108
|
Book = Workbook
|
1103
1109
|
|
1104
1110
|
end
|