rubyexcel 0.3.9 → 0.4.0

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.
@@ -1,71 +1,71 @@
1
- require_relative 'address.rb'
2
- require_relative 'data.rb'
3
- require_relative 'element.rb'
4
- #require_relative 'excel_tools.rb'
5
- require_relative 'section.rb'
6
- require_relative 'sheet.rb'
7
-
8
- module RubyExcel
9
-
10
- #
11
- # Example data to use in tests / demos
12
- #
13
-
14
- def self.sample_data
15
- [
16
- [ 'Part', 'Ref1', 'Ref2', 'Qty', 'Cost' ],
17
- [ 'Type1', 'QT1', '231', 1, 35.15 ],
18
- [ 'Type2', 'QT3', '123', 1, 40 ],
19
- [ 'Type3', 'XT1', '321', 3, 0.1 ],
20
- [ 'Type1', 'XY2', '132', 1, 30.00 ],
21
- [ 'Type4', 'XT3', '312', 2, 3 ],
22
- [ 'Type2', 'QY2', '213', 1, 99.99 ],
23
- [ 'Type1', 'QT4', '123', 2, 104 ]
24
- ]
25
-
26
- end
27
-
28
- #
29
- # Example hash to demonstrate imports
30
- #
31
-
32
- def self.sample_hash
33
-
34
- {
35
- Part1: {
36
- Type1: {
37
- SubType1: 1, SubType2: 2, SubType3: 3
38
- },
39
- Type2: {
40
- SubType1: 4, SubType2: 5, SubType3: 6
41
- }
42
- },
43
- Part2: {
44
- Type1: {
45
- SubType1: 1, SubType2: 2, SubType3: 3
46
- },
47
- Type2: {
48
- SubType1: 4, SubType2: 5, SubType3: 6
49
- }
50
- }
51
- }
52
-
53
- end
54
-
55
- #
56
- # Shortcut to create a Sheet with example data
57
- #
58
-
59
- def self.sample_sheet
60
- Workbook.new.load RubyExcel.sample_data
61
- end
62
-
63
- #
64
- # Shortcut to import a WIN32OLE Workbook or Sheet
65
- #
66
-
67
- def self.import( *args )
68
- Workbook.new.import( *args )
69
- end
70
-
1
+ require_relative 'address.rb'
2
+ require_relative 'data.rb'
3
+ require_relative 'element.rb'
4
+ #require_relative 'excel_tools.rb'
5
+ require_relative 'section.rb'
6
+ require_relative 'sheet.rb'
7
+
8
+ module RubyExcel
9
+
10
+ #
11
+ # Example data to use in tests / demos
12
+ #
13
+
14
+ def self.sample_data
15
+ [
16
+ [ 'Part', 'Ref1', 'Ref2', 'Qty', 'Cost' ],
17
+ [ 'Type1', 'QT1', '231', 1, 35.15 ],
18
+ [ 'Type2', 'QT3', '123', 1, 40 ],
19
+ [ 'Type3', 'XT1', '321', 3, 0.1 ],
20
+ [ 'Type1', 'XY2', '132', 1, 30.00 ],
21
+ [ 'Type4', 'XT3', '312', 2, 3 ],
22
+ [ 'Type2', 'QY2', '213', 1, 99.99 ],
23
+ [ 'Type1', 'QT4', '123', 2, 104 ]
24
+ ]
25
+
26
+ end
27
+
28
+ #
29
+ # Example hash to demonstrate imports
30
+ #
31
+
32
+ def self.sample_hash
33
+
34
+ {
35
+ Part1: {
36
+ Type1: {
37
+ SubType1: 1, SubType2: 2, SubType3: 3
38
+ },
39
+ Type2: {
40
+ SubType1: 4, SubType2: 5, SubType3: 6
41
+ }
42
+ },
43
+ Part2: {
44
+ Type1: {
45
+ SubType1: 1, SubType2: 2, SubType3: 3
46
+ },
47
+ Type2: {
48
+ SubType1: 4, SubType2: 5, SubType3: 6
49
+ }
50
+ }
51
+ }
52
+
53
+ end
54
+
55
+ #
56
+ # Shortcut to create a Sheet with example data
57
+ #
58
+
59
+ def self.sample_sheet
60
+ Workbook.new.load RubyExcel.sample_data
61
+ end
62
+
63
+ #
64
+ # Shortcut to import a WIN32OLE Workbook or Sheet
65
+ #
66
+
67
+ def self.import( *args )
68
+ Workbook.new.import( *args )
69
+ end
70
+
71
71
  end
@@ -1,377 +1,377 @@
1
- module RubyExcel
2
-
3
- #
4
- # Superclass for Row and Column
5
- #
6
-
7
- class Section
8
- include Address
9
- include Enumerable
10
-
11
- # The Sheet parent of the Section
12
- attr_reader :sheet
13
- alias parent sheet
14
-
15
- # The Data underlying the Sheet
16
- attr_reader :data
17
-
18
- #
19
- # Creates a RubyExcel::Section instance
20
- #
21
- # @param [RubyExcel::Sheet] sheet the parent Sheet
22
- #
23
-
24
- def initialize( sheet )
25
- @sheet = sheet
26
- @data = sheet.data
27
- end
28
-
29
- #
30
- # Access a cell by its index within the Section
31
- #
32
-
33
- def cell( ref )
34
- Cell.new( sheet, translate_address( ref ) )
35
- end
36
-
37
- #
38
- # Delete the data referenced by self
39
- #
40
-
41
- def delete
42
- data.delete( self ); self
43
- end
44
-
45
- #
46
- # Yields each value
47
- #
48
-
49
- def each
50
- return to_enum(:each) unless block_given?
51
- each_address { |addr| yield data[ addr ] }
52
- end
53
-
54
- #
55
- # Yields each value, skipping headers
56
- #
57
-
58
- def each_without_headers
59
- return to_enum( :each_without_headers ) unless block_given?
60
- each_address( false ) { |addr| yield data[ addr ] }
61
- end
62
- alias each_wh each_without_headers
63
-
64
- #
65
- # Yields each cell
66
- #
67
-
68
- def each_cell
69
- return to_enum( :each_cell ) unless block_given?
70
- each_address { |addr| yield Cell.new( sheet, addr ) }
71
- end
72
-
73
- #
74
- # Yields each cell, skipping headers
75
- #
76
-
77
- def each_cell_without_headers
78
- return to_enum( :each_cell_without_headers ) unless block_given?
79
- each_address( false ) { |addr| yield Cell.new( sheet, addr ) }
80
- end
81
- alias each_cell_wh each_cell_without_headers
82
-
83
- #
84
- # Check whether the data in self is empty
85
- #
86
-
87
- def empty?
88
- each_wh.all? { |val| val.to_s.empty? }
89
- end
90
-
91
- #
92
- # Return the address of a given value
93
- #
94
- # @yield [Object] yields each cell value to the block
95
- # @return [String, nil] the address of the value or nil
96
- #
97
-
98
- def find
99
- return to_enum( :find ) unless block_given?
100
- each_cell { |ce| return ce.address if yield ce.value }; nil
101
- end
102
-
103
- #
104
- # View the object for debugging
105
- #
106
-
107
- def inspect
108
- "#{ self.class }:0x#{ '%x' % (object_id << 1) }: #{ idx }"
109
- end
110
-
111
- #
112
- # Return the value of the last cell
113
- #
114
-
115
- def last
116
- last_cell.value
117
- end
118
-
119
- #
120
- # Return the last cell
121
- #
122
- # @return [RubyExcel::Cell]
123
- #
124
-
125
- def last_cell
126
- Cell.new( sheet, each_address.to_a.last )
127
- end
128
-
129
- #
130
- # Replaces each value with the result of the block
131
- #
132
-
133
- def map!
134
- return to_enum( :map! ) unless block_given?
135
- each_address { |addr| data[addr] = ( yield data[addr] ) }
136
- end
137
-
138
- #
139
- # Replaces each value with the result of the block, skipping headers
140
- #
141
-
142
- def map_without_headers!
143
- return to_enum( :map_without_headers! ) unless block_given?
144
- each_address( false ) { |addr| data[addr] = ( yield data[addr] ) }
145
- end
146
- alias map_wh! map_without_headers!
147
-
148
- #
149
- # Read a value by address
150
- #
151
- # @param [String, Fixnum, ::Range] start an index or Range of indices.
152
- # @param [Fixnum] slice if the first argument is an index, how many cells to read.
153
- #
154
-
155
- def read( start, slice=nil )
156
- if slice
157
- ( start..( step_index( start, slice ) ) ).map { |n| data[ translate_address( n ) ] }
158
- else
159
- if start.is_a?( ::Range ) # Standard Ruby Range
160
- start.map { |n| data[ translate_address( n ) ] }
161
- else # Single value
162
- data[ translate_address( start ) ]
163
- end
164
- end
165
- end
166
- alias [] read
167
-
168
- #
169
- # Summarise the values of a Section into a Hash
170
- #
171
- # @return [Hash]
172
- #
173
-
174
- def summarise
175
- each_wh.inject( Hash.new(0) ) { |h, v| h[v]+=1; h }
176
- end
177
- alias summarize summarise
178
-
179
- #
180
- # The Section as a seperated value String
181
- #
182
-
183
- def to_s
184
- to_a.map { |v| v.to_s.gsub(/\t|\n|\r/,' ') }.join ( self.is_a?( Row ) ? "\t" : "\n" )
185
- end
186
-
187
- #
188
- # Write a value by address
189
- #
190
- # @param [Array<String, Fixnum, ::Range, Object>] args the address to write the data to, and the data to write.
191
- #
192
-
193
- def write( *args )
194
- val = args.pop
195
- if args.length == 1
196
- if args[0].is_a?( ::Range ) # Standard Ruby Range
197
- sheet.range( to_range_address( translate_address( args[0].first ), translate_address( args[0].last ) ) ).value = val
198
- else # Single value
199
- data[ translate_address( args[0] ) ] = val
200
- end
201
- else # Slice
202
- sheet.range( to_range_address( translate_address( args[0] ), translate_address( step_index( args[0], args[1] ) ) ) ).value = val
203
- end
204
- end
205
- alias []= write
206
-
207
- end # Section
208
-
209
- #
210
- # A Row in the Sheet
211
- # @attr_reader [Fixnum] idx the Row index
212
- # @attr_reader [Fixnum] length the Row length
213
- #
214
-
215
- class Row < Section
216
-
217
- # The Row number
218
- attr_reader :idx
219
- alias index idx
220
-
221
- #
222
- # Creates a RubyExcel::Row instance
223
- #
224
- # @param [RubyExcel::Sheet] sheet the Sheet which holds this Row
225
- # @param [Fixnum] idx the index of this Row
226
- #
227
-
228
- def initialize( sheet, idx )
229
- @idx = Integer( idx )
230
- super( sheet )
231
- end
232
-
233
- #
234
- # Append a value to the Row.
235
- #
236
- # @param [Object] value the object to append
237
- # @note This only adds an extra cell if it is the first Row
238
- # This prevents a loop through Rows from extending diagonally away from the main data.
239
- #
240
-
241
- def <<( value )
242
- data[ translate_address( idx == 1 ? data.cols + 1 : data.cols ) ] = value
243
- end
244
-
245
- #
246
- # Access a Cell by its header
247
- #
248
- # @param [String] header the header to search for
249
- # @return [RubyExcel::Cell] the cell
250
- #
251
-
252
- def cell_by_header( header )
253
- cell( getref( header ) )
254
- end
255
- alias cell_h cell_by_header
256
-
257
- #
258
- # Find the Address of a header
259
- #
260
- # @param [String] header the header to search for
261
- # @return [String] the address of the header
262
- #
263
-
264
- def getref( header )
265
- sheet.header_rows.times do |t|
266
- res = sheet.row( t + 1 ).find { |v| v == header }
267
- return column_id( res ) if res
268
- end
269
- fail ArgumentError, 'Invalid header: ' + header.to_s
270
- end
271
-
272
- #
273
- # The number of Columns in the Row
274
- #
275
-
276
- def length
277
- data.cols
278
- end
279
-
280
- #
281
- # Find a value in this Row by its header
282
- #
283
- # @param [String] header the header to search for
284
- # @return [Object] the value at the address
285
- #
286
-
287
- def value_by_header( header )
288
- self[ getref( header ) ]
289
- end
290
- alias val value_by_header
291
-
292
- #
293
- # Set a value in this Row by its header
294
- #
295
- # @param [String] header the header to search for
296
- # @param [Object] val the value to write
297
- #
298
-
299
- def set_value_by_header( header, val )
300
- self[ getref( header ) ] = val
301
- end
302
- alias set_val set_value_by_header
303
-
304
- private
305
-
306
- def each_address( unused=nil )
307
- return to_enum( :each_address ) unless block_given?
308
- ( 'A'..col_letter( data.cols ) ).each { |col_id| yield translate_address( col_id ) }
309
- end
310
-
311
- def translate_address( addr )
312
- col_letter( addr ) + idx.to_s
313
- end
314
-
315
- end # Row
316
-
317
- #
318
- # A Column in the Sheet
319
- #
320
- # @attr_reader [String] idx the Column index
321
- # @attr_reader [Fixnum] length the Column length
322
- #
323
-
324
- class Column < Section
325
-
326
- # The Column letter
327
- attr_reader :idx
328
- alias index idx
329
-
330
- #
331
- # Creates a RubyExcel::Column instance
332
- #
333
- # @param [RubyExcel::Sheet] sheet the Sheet which holds this Column
334
- # @param [String, Fixnum] idx the index of this Column
335
- #
336
-
337
- def initialize( sheet, idx )
338
- @idx = idx
339
- super( sheet )
340
- end
341
-
342
- #
343
- # Append a value to the Column.
344
- #
345
- # @param [Object] value the object to append
346
- # @note This only adds an extra cell if it is the first Column.
347
- # This prevents a loop through Columns from extending diagonally away from the main data.
348
- #
349
-
350
- def <<( value )
351
- data[ translate_address( idx == 'A' ? data.rows + 1 : data.rows ) ] = value
352
- end
353
-
354
- #
355
- # The number of Rows in the Column
356
- #
357
-
358
- def length
359
- data.rows
360
- end
361
-
362
- private
363
-
364
- def each_address( headers=true )
365
- return to_enum( :each_address ) unless block_given?
366
- ( headers ? 1 : sheet.header_rows + 1 ).upto( data.rows ) { |row_id| yield translate_address( row_id ) }
367
- end
368
-
369
- def translate_address( addr )
370
- addr = addr.to_s unless addr.is_a?( String )
371
- fail ArgumentError, "Invalid address : #{ addr }" if addr =~ /[^\d]/
372
- idx + addr
373
- end
374
-
375
- end # Column
376
-
1
+ module RubyExcel
2
+
3
+ #
4
+ # Superclass for Row and Column
5
+ #
6
+
7
+ class Section
8
+ include Address
9
+ include Enumerable
10
+
11
+ # The Sheet parent of the Section
12
+ attr_reader :sheet
13
+ alias parent sheet
14
+
15
+ # The Data underlying the Sheet
16
+ attr_reader :data
17
+
18
+ #
19
+ # Creates a RubyExcel::Section instance
20
+ #
21
+ # @param [RubyExcel::Sheet] sheet the parent Sheet
22
+ #
23
+
24
+ def initialize( sheet )
25
+ @sheet = sheet
26
+ @data = sheet.data
27
+ end
28
+
29
+ #
30
+ # Access a cell by its index within the Section
31
+ #
32
+
33
+ def cell( ref )
34
+ Cell.new( sheet, translate_address( ref ) )
35
+ end
36
+
37
+ #
38
+ # Delete the data referenced by self
39
+ #
40
+
41
+ def delete
42
+ data.delete( self ); self
43
+ end
44
+
45
+ #
46
+ # Yields each value
47
+ #
48
+
49
+ def each
50
+ return to_enum(:each) unless block_given?
51
+ each_address { |addr| yield data[ addr ] }
52
+ end
53
+
54
+ #
55
+ # Yields each value, skipping headers
56
+ #
57
+
58
+ def each_without_headers
59
+ return to_enum( :each_without_headers ) unless block_given?
60
+ each_address( false ) { |addr| yield data[ addr ] }
61
+ end
62
+ alias each_wh each_without_headers
63
+
64
+ #
65
+ # Yields each cell
66
+ #
67
+
68
+ def each_cell
69
+ return to_enum( :each_cell ) unless block_given?
70
+ each_address { |addr| yield Cell.new( sheet, addr ) }
71
+ end
72
+
73
+ #
74
+ # Yields each cell, skipping headers
75
+ #
76
+
77
+ def each_cell_without_headers
78
+ return to_enum( :each_cell_without_headers ) unless block_given?
79
+ each_address( false ) { |addr| yield Cell.new( sheet, addr ) }
80
+ end
81
+ alias each_cell_wh each_cell_without_headers
82
+
83
+ #
84
+ # Check whether the data in self is empty
85
+ #
86
+
87
+ def empty?
88
+ each_wh.all? { |val| val.to_s.empty? }
89
+ end
90
+
91
+ #
92
+ # Return the address of a given value
93
+ #
94
+ # @yield [Object] yields each cell value to the block
95
+ # @return [String, nil] the address of the value or nil
96
+ #
97
+
98
+ def find
99
+ return to_enum( :find ) unless block_given?
100
+ each_cell { |ce| return ce.address if yield ce.value }; nil
101
+ end
102
+
103
+ #
104
+ # View the object for debugging
105
+ #
106
+
107
+ def inspect
108
+ "#{ self.class }:0x#{ '%x' % (object_id << 1) }: #{ idx }"
109
+ end
110
+
111
+ #
112
+ # Return the value of the last cell
113
+ #
114
+
115
+ def last
116
+ last_cell.value
117
+ end
118
+
119
+ #
120
+ # Return the last cell
121
+ #
122
+ # @return [RubyExcel::Cell]
123
+ #
124
+
125
+ def last_cell
126
+ Cell.new( sheet, each_address.to_a.last )
127
+ end
128
+
129
+ #
130
+ # Replaces each value with the result of the block
131
+ #
132
+
133
+ def map!
134
+ return to_enum( :map! ) unless block_given?
135
+ each_address { |addr| data[addr] = ( yield data[addr] ) }
136
+ end
137
+
138
+ #
139
+ # Replaces each value with the result of the block, skipping headers
140
+ #
141
+
142
+ def map_without_headers!
143
+ return to_enum( :map_without_headers! ) unless block_given?
144
+ each_address( false ) { |addr| data[addr] = ( yield data[addr] ) }
145
+ end
146
+ alias map_wh! map_without_headers!
147
+
148
+ #
149
+ # Read a value by address
150
+ #
151
+ # @param [String, Fixnum, ::Range] start an index or Range of indices.
152
+ # @param [Fixnum] slice if the first argument is an index, how many cells to read.
153
+ #
154
+
155
+ def read( start, slice=nil )
156
+ if slice
157
+ ( start..( step_index( start, slice ) ) ).map { |n| data[ translate_address( n ) ] }
158
+ else
159
+ if start.is_a?( ::Range ) # Standard Ruby Range
160
+ start.map { |n| data[ translate_address( n ) ] }
161
+ else # Single value
162
+ data[ translate_address( start ) ]
163
+ end
164
+ end
165
+ end
166
+ alias [] read
167
+
168
+ #
169
+ # Summarise the values of a Section into a Hash
170
+ #
171
+ # @return [Hash]
172
+ #
173
+
174
+ def summarise
175
+ each_wh.inject( Hash.new(0) ) { |h, v| h[v]+=1; h }
176
+ end
177
+ alias summarize summarise
178
+
179
+ #
180
+ # The Section as a seperated value String
181
+ #
182
+
183
+ def to_s
184
+ to_a.map { |v| v.to_s.gsub(/\t|\n|\r/,' ') }.join ( self.is_a?( Row ) ? "\t" : "\n" )
185
+ end
186
+
187
+ #
188
+ # Write a value by address
189
+ #
190
+ # @param [Array<String, Fixnum, ::Range, Object>] args the address to write the data to, and the data to write.
191
+ #
192
+
193
+ def write( *args )
194
+ val = args.pop
195
+ if args.length == 1
196
+ if args[0].is_a?( ::Range ) # Standard Ruby Range
197
+ sheet.range( to_range_address( translate_address( args[0].first ), translate_address( args[0].last ) ) ).value = val
198
+ else # Single value
199
+ data[ translate_address( args[0] ) ] = val
200
+ end
201
+ else # Slice
202
+ sheet.range( to_range_address( translate_address( args[0] ), translate_address( step_index( args[0], args[1] ) ) ) ).value = val
203
+ end
204
+ end
205
+ alias []= write
206
+
207
+ end # Section
208
+
209
+ #
210
+ # A Row in the Sheet
211
+ # @attr_reader [Fixnum] idx the Row index
212
+ # @attr_reader [Fixnum] length the Row length
213
+ #
214
+
215
+ class Row < Section
216
+
217
+ # The Row number
218
+ attr_reader :idx
219
+ alias index idx
220
+
221
+ #
222
+ # Creates a RubyExcel::Row instance
223
+ #
224
+ # @param [RubyExcel::Sheet] sheet the Sheet which holds this Row
225
+ # @param [Fixnum] idx the index of this Row
226
+ #
227
+
228
+ def initialize( sheet, idx )
229
+ @idx = Integer( idx )
230
+ super( sheet )
231
+ end
232
+
233
+ #
234
+ # Append a value to the Row.
235
+ #
236
+ # @param [Object] value the object to append
237
+ # @note This only adds an extra cell if it is the first Row
238
+ # This prevents a loop through Rows from extending diagonally away from the main data.
239
+ #
240
+
241
+ def <<( value )
242
+ data[ translate_address( idx == 1 ? data.cols + 1 : data.cols ) ] = value
243
+ end
244
+
245
+ #
246
+ # Access a Cell by its header
247
+ #
248
+ # @param [String] header the header to search for
249
+ # @return [RubyExcel::Cell] the cell
250
+ #
251
+
252
+ def cell_by_header( header )
253
+ cell( getref( header ) )
254
+ end
255
+ alias cell_h cell_by_header
256
+
257
+ #
258
+ # Find the Address of a header
259
+ #
260
+ # @param [String] header the header to search for
261
+ # @return [String] the address of the header
262
+ #
263
+
264
+ def getref( header )
265
+ sheet.header_rows.times do |t|
266
+ res = sheet.row( t + 1 ).find { |v| v == header }
267
+ return column_id( res ) if res
268
+ end
269
+ fail ArgumentError, 'Invalid header: ' + header.to_s
270
+ end
271
+
272
+ #
273
+ # The number of Columns in the Row
274
+ #
275
+
276
+ def length
277
+ data.cols
278
+ end
279
+
280
+ #
281
+ # Find a value in this Row by its header
282
+ #
283
+ # @param [String] header the header to search for
284
+ # @return [Object] the value at the address
285
+ #
286
+
287
+ def value_by_header( header )
288
+ self[ getref( header ) ]
289
+ end
290
+ alias val value_by_header
291
+
292
+ #
293
+ # Set a value in this Row by its header
294
+ #
295
+ # @param [String] header the header to search for
296
+ # @param [Object] val the value to write
297
+ #
298
+
299
+ def set_value_by_header( header, val )
300
+ self[ getref( header ) ] = val
301
+ end
302
+ alias set_val set_value_by_header
303
+
304
+ private
305
+
306
+ def each_address( unused=nil )
307
+ return to_enum( :each_address ) unless block_given?
308
+ ( 'A'..col_letter( data.cols ) ).each { |col_id| yield translate_address( col_id ) }
309
+ end
310
+
311
+ def translate_address( addr )
312
+ col_letter( addr ) + idx.to_s
313
+ end
314
+
315
+ end # Row
316
+
317
+ #
318
+ # A Column in the Sheet
319
+ #
320
+ # @attr_reader [String] idx the Column index
321
+ # @attr_reader [Fixnum] length the Column length
322
+ #
323
+
324
+ class Column < Section
325
+
326
+ # The Column letter
327
+ attr_reader :idx
328
+ alias index idx
329
+
330
+ #
331
+ # Creates a RubyExcel::Column instance
332
+ #
333
+ # @param [RubyExcel::Sheet] sheet the Sheet which holds this Column
334
+ # @param [String, Fixnum] idx the index of this Column
335
+ #
336
+
337
+ def initialize( sheet, idx )
338
+ @idx = idx
339
+ super( sheet )
340
+ end
341
+
342
+ #
343
+ # Append a value to the Column.
344
+ #
345
+ # @param [Object] value the object to append
346
+ # @note This only adds an extra cell if it is the first Column.
347
+ # This prevents a loop through Columns from extending diagonally away from the main data.
348
+ #
349
+
350
+ def <<( value )
351
+ data[ translate_address( idx == 'A' ? data.rows + 1 : data.rows ) ] = value
352
+ end
353
+
354
+ #
355
+ # The number of Rows in the Column
356
+ #
357
+
358
+ def length
359
+ data.rows
360
+ end
361
+
362
+ private
363
+
364
+ def each_address( headers=true )
365
+ return to_enum( :each_address ) unless block_given?
366
+ ( headers ? 1 : sheet.header_rows + 1 ).upto( data.rows ) { |row_id| yield translate_address( row_id ) }
367
+ end
368
+
369
+ def translate_address( addr )
370
+ addr = addr.to_s unless addr.is_a?( String )
371
+ fail ArgumentError, "Invalid address : #{ addr }" if addr =~ /[^\d]/
372
+ idx + addr
373
+ end
374
+
375
+ end # Column
376
+
377
377
  end # RubyExcel