robust_excel_ole 1.8 → 1.9

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