robust_excel_ole 1.8 → 1.9

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.
@@ -33,15 +33,49 @@ module General
33
33
 
34
34
  end
35
35
 
36
+ # @private
37
+ class Integer
38
+
39
+ alias old_spaceship <=>
40
+
41
+ def <=> other
42
+ # p other
43
+ if other.is_a? Array
44
+ self <=> other.first
45
+ else
46
+ old_spaceship other
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ # @private
53
+ class Array
54
+
55
+ alias old_spaceship <=>
56
+
57
+ def <=> other
58
+ # p other
59
+ if other.is_a? Integer
60
+ self <=> [other]
61
+ else
62
+ old_spaceship other
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+
36
69
  # @private
37
70
  class WIN32OLE
71
+
38
72
  # promoting WIN32OLE objects to RobustExcelOle objects
39
73
  def to_reo
40
74
  case ole_type.name
41
75
  when 'Range' then RobustExcelOle::Range.new(self)
42
- when '_Worksheet' then Worksheet.new(self)
43
- when '_Workbook' then Workbook.new(self)
44
- when '_Application' then Excel.new(self)
76
+ when '_Worksheet' then RobustExcelOle::Worksheet.new(self)
77
+ when '_Workbook' then RobustExcelOle::Workbook.new(self)
78
+ when '_Application' then RobustExcelOle::Excel.new(self)
45
79
  else
46
80
  self
47
81
  end
@@ -73,18 +73,18 @@ module RobustExcelOle
73
73
  { }
74
74
  end
75
75
  end
76
- address = Address.new(dest_address)
76
+ rows, columns = Address.int_range(dest_address)
77
77
  dest_sheet = @worksheet if dest_sheet == :__not_provided
78
- dest_address_is_position = (address.rows.min == address.rows.max && address.columns.min == address.columns.max)
78
+ dest_address_is_position = (rows.min == rows.max && columns.min == columns.max)
79
79
  dest_range_address = if (not dest_address_is_position)
80
- [address.rows.min..address.rows.max,address.columns.min..address.columns.max]
80
+ [rows.min..rows.max,columns.min..columns.max]
81
81
  else
82
82
  if (not options[:transpose])
83
- [address.rows.min..address.rows.min+self.Rows.Count-1,
84
- address.columns.min..address.columns.min+self.Columns.Count-1]
83
+ [rows.min..rows.min+self.Rows.Count-1,
84
+ columns.min..columns.min+self.Columns.Count-1]
85
85
  else
86
- [address.rows.min..address.rows.min+self.Columns.Count-1,
87
- address.columns.min..address.columns.min+self.Rows.Count-1]
86
+ [rows.min..rows.min+self.Columns.Count-1,
87
+ columns.min..columns.min+self.Rows.Count-1]
88
88
  end
89
89
  end
90
90
  dest_range = dest_sheet.range(dest_range_address)
@@ -95,9 +95,9 @@ module RobustExcelOle
95
95
  if dest_range.worksheet.workbook.excel == @worksheet.workbook.excel
96
96
  if options[:transpose]
97
97
  self.Copy
98
- dest_range.PasteSpecial(:transpose => true)
98
+ dest_range.PasteSpecial('transpose' => true)
99
99
  else
100
- self.Copy(:destination => dest_range.ole_range)
100
+ self.Copy('destination' => dest_range.ole_range)
101
101
  end
102
102
  else
103
103
  if options[:transpose]
@@ -107,7 +107,7 @@ module RobustExcelOle
107
107
  @worksheet.workbook.excel.with_displayalerts(false) {added_sheet.Delete}
108
108
  else
109
109
  self.Copy
110
- dest_sheet.Paste(:destination => dest_range.ole_range)
110
+ dest_sheet.Paste('destination' => dest_range.ole_range)
111
111
  end
112
112
  end
113
113
  end
@@ -122,18 +122,18 @@ module RobustExcelOle
122
122
  # @options [Worksheet] the destination worksheet
123
123
  # @options [Hash] options: :transpose, :values_only
124
124
  def copy_special(dest_address, dest_sheet = :__not_provided, options = { })
125
- address = Address.new(dest_address)
125
+ rows, columns = Address.int_range(dest_address)
126
126
  dest_sheet = @worksheet if dest_sheet == :__not_provided
127
- dest_address_is_position = (address.rows.min == address.rows.max && address.columns.min == address.columns.max)
127
+ dest_address_is_position = (rows.min == rows.max && columns.min == columns.max)
128
128
  dest_range_address = if (not dest_address_is_position)
129
- [address.rows.min..address.rows.max,address.columns.min..address.columns.max]
129
+ [rows.min..rows.max,columns.min..columns.max]
130
130
  else
131
131
  if (not options[:transpose])
132
- [address.rows.min..address.rows.min+self.Rows.Count-1,
133
- address.columns.min..address.columns.min+self.Columns.Count-1]
132
+ [rows.min..rows.min+self.Rows.Count-1,
133
+ columns.min..columns.min+self.Columns.Count-1]
134
134
  else
135
- [address.rows.min..address.rows.min+self.Columns.Count-1,
136
- address.columns.min..address.columns.min+self.Rows.Count-1]
135
+ [rows.min..rows.min+self.Columns.Count-1,
136
+ columns.min..columns.min+self.Rows.Count-1]
137
137
  end
138
138
  end
139
139
  dest_range = dest_sheet.range(dest_range_address)
@@ -144,9 +144,9 @@ module RobustExcelOle
144
144
  if dest_range.worksheet.workbook.excel == @worksheet.workbook.excel
145
145
  if options[:transpose]
146
146
  self.Copy
147
- dest_range.PasteSpecial(:transpose => true)
147
+ dest_range.PasteSpecial('transpose' => true)
148
148
  else
149
- self.Copy(:destination => dest_range.ole_range)
149
+ self.Copy('destination' => dest_range.ole_range)
150
150
  end
151
151
  else
152
152
  if options[:transpose]
@@ -156,7 +156,7 @@ module RobustExcelOle
156
156
  @worksheet.workbook.excel.with_displayalerts(false) {added_sheet.Delete}
157
157
  else
158
158
  self.Copy
159
- dest_sheet.Paste(:destination => dest_range.ole_range)
159
+ dest_sheet.Paste('destination' => dest_range.ole_range)
160
160
  end
161
161
  end
162
162
  end
@@ -0,0 +1,236 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module RobustExcelOle
4
+
5
+ class RangeOwners < REOCommon
6
+
7
+ # returns the contents of a range with given name
8
+ # if the name could not be found or the value could not be determined,
9
+ # then return default value, if provided, raise error otherwise
10
+ # Excel Bug: if a local name without a qualifier is given,
11
+ # then by default Excel takes the first worksheet,
12
+ # even if a different worksheet is active
13
+ # @param [String] name the name of the range
14
+ # @param [Hash] opts the options
15
+ # @option opts [Symbol] :default the default value that is provided if no contents could be returned
16
+ # @return [Variant] the contents of a range with given name
17
+ def namevalue_glob(name, opts = { :default => :__not_provided })
18
+ name_obj = begin
19
+ name_object(name)
20
+ rescue NameNotFound => msg
21
+ return opts[:default] unless opts[:default] == :__not_provided
22
+ raise
23
+ end
24
+ value = begin
25
+ name_obj.RefersToRange.Value
26
+ rescue WIN32OLERuntimeError
27
+ sheet = if self.is_a?(Worksheet) then self
28
+ elsif self.is_a?(Workbook) then self.sheet(1)
29
+ elsif self.is_a?(Excel) then self.workbook.sheet(1)
30
+ end
31
+ begin
32
+ sheet.Evaluate(name_obj.Name).Value
33
+ rescue # WIN32OLERuntimeError
34
+ return opts[:default] unless opts[:default] == :__not_provided
35
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{self}"
36
+ end
37
+ end
38
+ if value == -2146828288 + RobustExcelOle::XlErrName
39
+ return opts[:default] unless opts[:default] == :__not_provided
40
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
41
+ end
42
+ return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
43
+ value
44
+ end
45
+
46
+ # sets the contents of a range
47
+ # @param [String] name the name of a range
48
+ # @param [Variant] value the contents of the range
49
+ # @param [FixNum] color the color when setting a value
50
+ # @param [Hash] opts :color [FixNum] the color when setting the contents
51
+ def set_namevalue_glob(name, value, opts = { :color => 0 })
52
+ cell = name_object(name).RefersToRange
53
+ cell.Interior.ColorIndex = opts[:color]
54
+ workbook.modified_cells << cell if workbook # unless cell_modified?(cell)
55
+ cell.Value = value
56
+ rescue WIN32OLERuntimeError
57
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
58
+ end
59
+
60
+ # returns the contents of a range with a locally defined name
61
+ # evaluates the formula if the contents is a formula
62
+ # if the name could not be found or the range or value could not be determined,
63
+ # then return default value, if provided, raise error otherwise
64
+ # @param [String] name the name of a range
65
+ # @param [Hash] opts the options
66
+ # @option opts [Symbol] :default the default value that is provided if no contents could be returned
67
+ # @return [Variant] the contents of a range with given name
68
+ def namevalue(name, opts = { :default => :__not_provided })
69
+ return namevalue_glob(name, opts) if self.is_a?(Workbook)
70
+ begin
71
+ range = self.Range(name)
72
+ rescue WIN32OLERuntimeError
73
+ return opts[:default] unless opts[:default] == :__not_provided
74
+ raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
75
+ end
76
+ begin
77
+ value = range.Value
78
+ rescue WIN32OLERuntimeError
79
+ return opts[:default] unless opts[:default] == :__not_provided
80
+ raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}"
81
+ end
82
+ if value == -2146828288 + RobustExcelOle::XlErrName
83
+ return opts[:default] unless opts[:default] == __not_provided
84
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
85
+ end
86
+ return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
87
+ value
88
+ end
89
+
90
+ # assigns a value to a range given a locally defined name
91
+ # @param [String] name the name of a range
92
+ # @param [Variant] value the assigned value
93
+ # @param [Hash] opts :color [FixNum] the color when setting the contents
94
+ def set_namevalue(name, value, opts = { :color => 0 })
95
+ begin
96
+ return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
97
+ range = self.Range(name)
98
+ rescue WIN32OLERuntimeError
99
+ raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
100
+ end
101
+ begin
102
+ range.Interior.ColorIndex = opts[:color]
103
+ workbook.modified_cells << range if workbook # unless cell_modified?(range)
104
+ range.Value = value
105
+ rescue WIN32OLERuntimeError
106
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
107
+ end
108
+ end
109
+
110
+ # @private
111
+ def nameval(name, opts = { :default => :__not_provided }) # :deprecated: #
112
+ namevalue_glob(name, opts)
113
+ end
114
+
115
+ # @private
116
+ def set_nameval(name, value, opts = { :color => 0 }) # :deprecated: #
117
+ set_namevalue_glob(name, value, opts)
118
+ end
119
+
120
+ # @private
121
+ def rangeval(name, opts = { :default => :__not_provided }) # :deprecated: #
122
+ namevalue(name, opts)
123
+ end
124
+
125
+ # @private
126
+ def set_rangeval(name, value, opts = { :color => 0 }) # :deprecated: #
127
+ set_namevalue(name, value, opts)
128
+ end
129
+
130
+ # creates a range from a given defined name or address
131
+ # range(address) does work for Worksheet objects only
132
+ # @params [Variant] range name or address
133
+ # @return [Range] a range
134
+ def range(name_or_address, address2 = :__not_provided)
135
+ begin
136
+ if address2 == :__not_provided
137
+ range = begin
138
+ RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange)
139
+ rescue NameNotFound
140
+ nil
141
+ end
142
+ end
143
+ if self.is_a?(Worksheet) && (range.nil? || (address2 != :__not_provided))
144
+ address = name_or_address
145
+ address = [name_or_address,address2] unless address2 == :__not_provided
146
+ self.Names.Add('Name' => '__dummy001', 'RefersToR1C1' => '=' + Address.r1c1(address))
147
+ range = RobustExcelOle::Range.new(name_object('__dummy001').RefersToRange)
148
+ self.Names.Item('__dummy001').Delete
149
+ range
150
+ # variant via rows, columns:
151
+ #rows, columns = Address.int_range(address)
152
+ #ole_range = if rows.nil?
153
+ # self.Range(self.Columns(columns.min), self.Columns(columns.max))
154
+ #elsif columns.nil?
155
+ # self.Range(self.Rows(rows.min), self.Rows(rows.max))
156
+ #else
157
+ # self.Range(self.Cells(rows.min, columns.min), self.Cells(rows.max, columns.max))
158
+ #end
159
+ ##range = ole_range.to_reo
160
+ #range = Range.new(ole_range)
161
+ end
162
+ rescue WIN32OLERuntimeError
163
+ address2_string = address2.nil? ? "" : ", #{address2.inspect}"
164
+ raise RangeNotCreated, "cannot create range (#{name_or_address.inspect}#{address2_string})"
165
+ end
166
+ range
167
+ end
168
+
169
+ def name2range(name) # :deprecated: #
170
+ range(name)
171
+ end
172
+
173
+ # adds a name referring to a range given by the row and column
174
+ # @param [String] name the range name
175
+ # @params [Address] address of the range
176
+ def add_name(name, addr, addr_deprecated = :__not_provided)
177
+ addr = [addr,addr_deprecated] unless addr_deprecated == :__not_provided
178
+ begin
179
+ self.Names.Add('Name' => name, 'RefersToR1C1' => '=' + Address.r1c1(addr))
180
+ rescue WIN32OLERuntimeError => msg
181
+ raise RangeNotEvaluatable, "cannot add name #{name.inspect} to range #{addr.inspect}"
182
+ end
183
+ name
184
+ end
185
+
186
+ def set_name(name,row,column) # :deprecated :#
187
+ add_name(name,row,column)
188
+ end
189
+
190
+ # renames a range
191
+ # @param [String] name the previous range name
192
+ # @param [String] new_name the new range name
193
+ def rename_range(name, new_name)
194
+ begin
195
+ item = self.Names.Item(name)
196
+ rescue WIN32OLERuntimeError
197
+ raise NameNotFound, "name #{name.inspect} not in #{File.basename(self.stored_filename).inspect}"
198
+ end
199
+ begin
200
+ item.Name = new_name
201
+ rescue WIN32OLERuntimeError
202
+ raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
203
+ end
204
+ end
205
+
206
+ # deletes a name of a range
207
+ # @param [String] name the previous range name
208
+ # @param [String] new_name the new range name
209
+ def delete_name(name)
210
+ begin
211
+ item = self.Names.Item(name)
212
+ rescue WIN32OLERuntimeError
213
+ raise NameNotFound, "name #{name.inspect} not in #{File.basename(self.stored_filename).inspect}"
214
+ end
215
+ begin
216
+ item.Delete
217
+ rescue WIN32OLERuntimeError
218
+ raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
219
+ end
220
+ end
221
+
222
+ private
223
+
224
+ def name_object(name)
225
+ self.Names.Item(name)
226
+ rescue WIN32OLERuntimeError
227
+ begin
228
+ self.Parent.Names.Item(name)
229
+ rescue WIN32OLERuntimeError
230
+ raise RobustExcelOle::NameNotFound, "name #{name.inspect} not in #{self.inspect}"
231
+ end
232
+ end
233
+
234
+ end
235
+
236
+ end
@@ -1,11 +1,21 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- LOG_TO_STDOUT = true unless Object.const_defined?(:LOG_TO_STDOUT)
3
+ LOG_TO_STDOUT = false unless Object.const_defined?(:LOG_TO_STDOUT)
4
4
  REO_LOG_DIR = ''.freeze unless Object.const_defined?(:REO_LOG_DIR)
5
5
  REO_LOG_FILE = 'reo.log'.freeze unless Object.const_defined?(:REO_LOG_FILE)
6
6
 
7
7
  File.delete REO_LOG_FILE rescue nil
8
8
 
9
+ unless "any string".respond_to?(:end_with?)
10
+ class String
11
+ def end_with?(*suffixes)
12
+ suffixes.any? do |suffix|
13
+ self[-suffix.size .. -1] == suffix
14
+ end
15
+ end
16
+ end
17
+ end
18
+
9
19
  module RobustExcelOle
10
20
 
11
21
  # @private
@@ -21,7 +31,7 @@ module RobustExcelOle
21
31
  end
22
32
 
23
33
  # @private
24
- class SheetREOError < REOError
34
+ class WorksheetREOError < REOError
25
35
  end
26
36
 
27
37
  # @private
@@ -122,18 +132,22 @@ module RobustExcelOle
122
132
 
123
133
  class REOCommon
124
134
 
135
+ # @private
125
136
  def excel
126
137
  raise TypeREOError, 'receiver instance is neither an Excel nor a Workbook'
127
138
  end
128
139
 
140
+ # @private
129
141
  def own_methods
130
142
  (self.methods - Object.methods).sort
131
143
  end
132
144
 
145
+ # @private
133
146
  def self.tr1(_text)
134
147
  puts :text
135
148
  end
136
149
 
150
+ # @private
137
151
  def self.trace(text)
138
152
  if LOG_TO_STDOUT
139
153
  puts text
@@ -144,6 +158,7 @@ module RobustExcelOle
144
158
  reo_log_dir = ENV[home]
145
159
  else
146
160
  reo_log_dir = REO_LOG_DIR
161
+ #reo_log_dir = "C:/Users/User"
147
162
  end
148
163
  File.open(reo_log_dir + '/' + REO_LOG_FILE,'a') do |file|
149
164
  file.puts text
@@ -151,6 +166,7 @@ module RobustExcelOle
151
166
  end
152
167
  end
153
168
 
169
+ # @private
154
170
  def self.puts_hash(hash)
155
171
  hash.each do |e|
156
172
  if e[1].is_a?(Hash)
@@ -166,278 +182,4 @@ module RobustExcelOle
166
182
 
167
183
  end
168
184
 
169
- class Address < REOCommon
170
-
171
- attr_reader :rows
172
- attr_reader :columns
173
-
174
- def initialize(address)
175
- address = [address] unless address.is_a?(Array)
176
- raise AddressInvalid, 'more than two components' if address.size > 2
177
- begin
178
- if address.size == 1
179
- comp1, comp2 = address[0].split(':')
180
- address_comp1 = comp1.gsub(/[A-Z]/,'')
181
- address_comp2 = comp1.gsub(/[0-9]/,'')
182
- if comp1 != address_comp2 + address_comp1
183
- raise AddressInvalid, "address #{comp1.inspect} not in A1-format"
184
- end
185
- unless comp2.nil?
186
- address_comp3 = comp2.gsub(/[A-Z]/,'')
187
- address_comp4 = comp2.gsub(/[0-9]/,'')
188
- if comp2 != address_comp4 + address_comp3
189
- raise AddressInvalid, "address #{comp2.inspect} not in A1-format"
190
- end
191
- address_comp1 = address_comp1..address_comp3
192
- address_comp2 = address_comp2..address_comp4
193
- end
194
- else
195
- address_comp1, address_comp2 = address
196
- end
197
- address_comp1 = address_comp1..address_comp1 unless address_comp1.is_a?(Object::Range)
198
- address_comp2 = address_comp2..address_comp2 unless address_comp2.is_a?(Object::Range)
199
- @rows = address_comp1.min.to_i..address_comp1.max.to_i
200
- if address_comp2.min.to_i == 0
201
- raise AddressInvalid, "address (#{address_comp1.inspect}, #{address_comp2.inspect}) not in A1-format" if address_comp1.min.to_i == 0
202
- @columns = str2num(address_comp2.begin)..str2num(address_comp2.end)
203
- else
204
- @columns = address_comp2.min.to_i..address_comp2.max.to_i
205
- end
206
- rescue
207
- raise AddressInvalid, "address (#{address.inspect}) not in A1- or R1C1-format"
208
- end
209
- end
210
-
211
- private
212
-
213
- def str2num(str)
214
- str = str.upcase
215
- sum = 0
216
- (1..str.length).each { |i| sum += (str[i - 1].ord - 64) * 26**(str.length - i) }
217
- sum
218
- end
219
-
220
- end
221
-
222
- class RangeOwners < REOCommon
223
-
224
- # returns the contents of a range with given name
225
- # if the name could not be found or the value could not be determined,
226
- # then return default value, if provided, raise error otherwise
227
- # Excel Bug: if a local name without a qualifier is given,
228
- # then by default Excel takes the first worksheet,
229
- # even if a different worksheet is active
230
- # @param [String] name the name of the range
231
- # @param [Hash] opts the options
232
- # @option opts [Symbol] :default the default value that is provided if no contents could be returned
233
- # @return [Variant] the contents of a range with given name
234
- def namevalue_glob(name, opts = { :default => :__not_provided })
235
- name_obj = begin
236
- name_object(name)
237
- rescue NameNotFound => msg
238
- return opts[:default] unless opts[:default] == :__not_provided
239
- raise
240
- end
241
- value = begin
242
- name_obj.RefersToRange.Value
243
- rescue WIN32OLERuntimeError
244
- sheet = if self.is_a?(Worksheet) then self
245
- elsif self.is_a?(Workbook) then self.sheet(1)
246
- elsif self.is_a?(Excel) then self.workbook.sheet(1)
247
- end
248
- begin
249
- sheet.Evaluate(name_obj.Name).Value
250
- rescue # WIN32OLERuntimeError
251
- return opts[:default] unless opts[:default] == :__not_provided
252
- raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{self}"
253
- end
254
- end
255
- if value == -2146828288 + RobustExcelOle::XlErrName
256
- return opts[:default] unless opts[:default] == :__not_provided
257
- raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
258
- end
259
- return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
260
- value
261
- end
262
-
263
- # sets the contents of a range
264
- # @param [String] name the name of a range
265
- # @param [Variant] value the contents of the range
266
- # @param [FixNum] color the color when setting a value
267
- # @param [Hash] opts :color [FixNum] the color when setting the contents
268
- def set_namevalue_glob(name, value, opts = { :color => 0 })
269
- cell = name_object(name).RefersToRange
270
- cell.Interior.ColorIndex = opts[:color]
271
- workbook.modified_cells << cell if workbook # unless cell_modified?(cell)
272
- cell.Value = value
273
- rescue WIN32OLERuntimeError
274
- raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
275
- end
276
-
277
- # returns the contents of a range with a locally defined name
278
- # evaluates the formula if the contents is a formula
279
- # if the name could not be found or the range or value could not be determined,
280
- # then return default value, if provided, raise error otherwise
281
- # @param [String] name the name of a range
282
- # @param [Hash] opts the options
283
- # @option opts [Symbol] :default the default value that is provided if no contents could be returned
284
- # @return [Variant] the contents of a range with given name
285
- def namevalue(name, opts = { :default => :__not_provided })
286
- return namevalue_glob(name, opts) if self.is_a?(Workbook)
287
- begin
288
- range = self.Range(name)
289
- rescue WIN32OLERuntimeError
290
- return opts[:default] unless opts[:default] == :__not_provided
291
- raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
292
- end
293
- begin
294
- value = range.Value
295
- rescue WIN32OLERuntimeError
296
- return opts[:default] unless opts[:default] == :__not_provided
297
- raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}"
298
- end
299
- if value == -2146828288 + RobustExcelOle::XlErrName
300
- return opts[:default] unless opts[:default] == __not_provided
301
- raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
302
- end
303
- return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
304
- value
305
- end
306
-
307
- # assigns a value to a range given a locally defined name
308
- # @param [String] name the name of a range
309
- # @param [Variant] value the assigned value
310
- # @param [Hash] opts :color [FixNum] the color when setting the contents
311
- def set_namevalue(name, value, opts = { :color => 0 })
312
- begin
313
- return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
314
- range = self.Range(name)
315
- rescue WIN32OLERuntimeError
316
- raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
317
- end
318
- begin
319
- range.Interior.ColorIndex = opts[:color]
320
- workbook.modified_cells << range if workbook # unless cell_modified?(range)
321
- range.Value = value
322
- rescue WIN32OLERuntimeError
323
- raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
324
- end
325
- end
326
-
327
- def nameval(name, opts = { :default => :__not_provided }) # :deprecated: #
328
- namevalue_glob(name, opts)
329
- end
330
-
331
- def set_nameval(name, value, opts = { :color => 0 }) # :deprecated: #
332
- set_namevalue_glob(name, value, opts)
333
- end
334
-
335
- def rangeval(name, opts = { :default => :__not_provided }) # :deprecated: #
336
- namevalue(name, opts)
337
- end
338
-
339
- def set_rangeval(name, value, opts = { :color => 0 }) # :deprecated: #
340
- set_namevalue(name, value, opts)
341
- end
342
-
343
- # creates a range from a given defined name or address
344
- # @params [Variant] range name or address
345
- # @return [Range] a range
346
- def range(name_or_address, address2 = :__not_provided)
347
- begin
348
- if address2 == :__not_provided
349
- range = RobustExcelOle::Range.new(name_object(name_or_address).RefersToRange) rescue nil
350
- end
351
- if self.is_a?(Worksheet) && (range.nil? || (address2 != :__not_provided))
352
- address = name_or_address
353
- address = [name_or_address,address2] unless address2 == :__not_provided
354
- address = Address.new(address)
355
- range = RobustExcelOle::Range.new(@ole_worksheet.Range(
356
- @ole_worksheet.Cells(address.rows.min, address.columns.min),
357
- @ole_worksheet.Cells(address.rows.max, address.columns.max)
358
- ))
359
- end
360
- rescue WIN32OLERuntimeError
361
- address2_string = address2.nil? ? "" : ", #{address2.inspect}"
362
- raise RangeNotCreated, "cannot create range (#{name_or_address.inspect}#{address2_string})"
363
- end
364
- range
365
- end
366
-
367
- def name2range(name) # :deprecated: #
368
- range(name)
369
- end
370
-
371
- # adds a name referring to a range given by the row and column
372
- # @param [String] name the range name
373
- # @params [Address] address of the range
374
- def add_name(name, addr, addr_deprecated = :__not_provided)
375
- addr = [addr,addr_deprecated] unless addr_deprecated == :__not_provided
376
- address = Address.new(addr)
377
- address_string = 'Z' + address.rows.min.to_s + 'S' + address.columns.min.to_s +
378
- ':Z' + address.rows.max.to_s + 'S' + address.columns.max.to_s
379
- begin
380
- self.Names.Add('Name' => name, 'RefersToR1C1' => '=' + address_string)
381
- rescue WIN32OLERuntimeError => msg
382
- # trace "WIN32OLERuntimeError: #{msg.message}"
383
- raise RangeNotEvaluatable, "cannot add name #{name.inspect} to range #{addr.inspect}"
384
- end
385
- name
386
- end
387
-
388
- def set_name(name,row,column) # :deprecated :#
389
- add_name(name,row,column)
390
- end
391
-
392
- # renames a range
393
- # @param [String] name the previous range name
394
- # @param [String] new_name the new range name
395
- def rename_range(name, new_name)
396
- begin
397
- item = self.Names.Item(name)
398
- rescue WIN32OLERuntimeError
399
- raise NameNotFound, "name #{name.inspect} not in #{File.basename(self.stored_filename).inspect}"
400
- end
401
- begin
402
- item.Name = new_name
403
- rescue WIN32OLERuntimeError
404
- raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
405
- end
406
- end
407
-
408
- # deletes a name of a range
409
- # @param [String] name the previous range name
410
- # @param [String] new_name the new range name
411
- def delete_name(name)
412
- begin
413
- item = self.Names.Item(name)
414
- rescue WIN32OLERuntimeError
415
- raise NameNotFound, "name #{name.inspect} not in #{File.basename(self.stored_filename).inspect}"
416
- end
417
- begin
418
- item.Delete
419
- rescue WIN32OLERuntimeError
420
- raise UnexpectedREOError, "name error in #{File.basename(self.stored_filename).inspect}"
421
- end
422
- end
423
-
424
- private
425
-
426
- def name_object(name)
427
- self.Names.Item(name)
428
- rescue WIN32OLERuntimeError
429
- begin
430
- self.Parent.Names.Item(name)
431
- rescue WIN32OLERuntimeError
432
- raise RobustExcelOle::NameNotFound, "name #{name.inspect} not in #{self.inspect}"
433
- end
434
- end
435
-
436
- # def cell_modified?(cell)
437
- # workbook.modified_cells.each{|c| return true if c.Name.Value == cell.Name.Value}
438
- # false
439
- # end
440
-
441
- end
442
-
443
185
  end