Permalink
Browse files

work out correct datatype for excel formula cell values

  • Loading branch information...
1 parent a71d60d commit 9b323f5d2968e362387d54f69f7f5d0eeaf0cc02 Hugh McGowan committed Jun 28, 2009
Showing with 41 additions and 12 deletions.
  1. +24 −8 lib/roo/excel.rb
  2. BIN test/1900_base.xls
  3. BIN test/1904_base.xls
  4. +17 −4 test/test_roo.rb
View
@@ -20,6 +20,7 @@ def _date data # :nodoc:
end
date
end
+ public :_datetime
end
end
end
@@ -386,13 +387,20 @@ def read_cells(sheet=nil)
end # worksheet
@cells_read[sheet] = true
end
-
+
+ # Get the contents of a cell, accounting for the
+ # way formula stores the value
+ def read_cell_content(row, idx)
+ cell = row.at(idx)
+ cell = cell.value if cell.class == Spreadsheet::Formula
+ cell
+ end
+
# Test the cell to see if it's a valid date/time.
def date_or_time?(row, idx)
- return false if row.at(idx).class == Spreadsheet::Formula
format = row.format(idx)
if format.date_or_time?
- cell = row.at(idx)
+ cell = read_cell_content(row, idx)
true if Float(cell) > 0 rescue false
else
false
@@ -403,7 +411,8 @@ def date_or_time?(row, idx)
# Read the date-time cell and convert to,
# the date-time values for Roo
def read_cell_date_or_time(row, idx)
- cell = row.at(idx).to_s.to_f
+ cell = read_cell_content(row, idx)
+ cell = cell.to_s.to_f
if cell < 1.0
value_type = :time
f = cell*24.0*60.0*60.0
@@ -415,15 +424,23 @@ def read_cell_date_or_time(row, idx)
s = secs
value = h*3600+m*60+s
else
- datetime = row.datetime(idx)
+ if row.at(idx).class == Spreadsheet::Formula
+ datetime = row._datetime(cell)
+ else
+ datetime = row.datetime(idx)
+ end
if datetime.hour != 0 or
datetime.min != 0 or
datetime.sec != 0
value_type = :datetime
value = datetime
else
value_type = :date
- value = row.date(idx)
+ if row.at(idx).class == Spreadsheet::Formula
+ value = row._date(cell)
+ else
+ value = row.date(idx)
+ end
value = sprintf("%04d-%02d-%02d",value.year,value.month,value.day)
end
end
@@ -434,8 +451,7 @@ def read_cell_date_or_time(row, idx)
# Read the cell and based on the class,
# return the values for Roo
def read_cell(row, idx)
- cell = row.at(idx)
- cell = cell.value if cell.class == Spreadsheet::Formula
+ cell = read_cell_content(row, idx)
case cell
when Float, Integer, Fixnum, Bignum
value_type = :float
View
Binary file not shown.
View
Binary file not shown.
View
@@ -130,7 +130,7 @@ class TestRoo < Test::Unit::TestCase
OPENOFFICE = true # do Openoffice-Spreadsheet Tests?
EXCEL = true # do Excel Tests?
- GOOGLE = true # do Google-Spreadsheet Tests?
+ GOOGLE = false # do Google-Spreadsheet Tests?
EXCELX = true # do Excel-X Tests? (.xlsx-files)
ONLINE = true
@@ -572,6 +572,15 @@ def test_formula_excelx
end
end
+ # Excel can only read the cell's value
+ def test_formula_excel
+ with_each_spreadsheet(:name=>'formula', :format=>:excel) do |oo|
+ assert_equal 21, oo.cell('A',7)
+ assert_equal 21, oo.cell('B',7)
+ end
+ end
+
+
def test_borders_sheets
with_each_spreadsheet(:name=>'borders') do |oo|
oo.default_sheet = oo.sheets[1]
@@ -1046,17 +1055,19 @@ def test_bug_false_borders_with_formulas
end
end
+ # We'ce added minimal formula support so we can now read these
+ # though not sure how the spreadsheet reports older values....
def test_fe
with_each_spreadsheet(:name=>'false_encoding', :format=>:excel) do |oo|
- #DOES NOT WORK IN EXCEL FILES: assert_equal Date.new(2007,11,1), oo.cell('a',1)
+ assert_equal Date.new(2007,11,1), oo.cell('a',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal true, oo.formula?('a',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal '=TODAY()', oo.formula('a',1)
- #DOES NOT WORK IN EXCEL FILES: assert_equal Date.new(2008,2,9), oo.cell('B',1)
+ assert_equal Date.new(2008,2,9), oo.cell('B',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal true, oo.formula?('B',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal "=A1+100", oo.formula('B',1)
- #DOES NOT WORK IN EXCEL FILES: assert_equal Date.new(2008,2,9), oo.cell('C',1)
+ assert_kind_of DateTime, oo.cell('C',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal true, oo.formula?('C',1)
#DOES NOT WORK IN EXCEL FILES: assert_equal "=C1", oo.formula('C',1)
@@ -1751,10 +1762,12 @@ def test_col_whitespace
def test_base_dates_in_excel
with_each_spreadsheet(:name=>'1900_base', :format=>:excel) do |oo|
assert_equal Date.new(2009,06,15), oo.cell(1,1)
+ assert_equal Date.new(Time.now.year,Time.now.month,Time.now.day), oo.cell(2,1) #formula for TODAY()
assert_equal :date, oo.celltype(1,1)
end
with_each_spreadsheet(:name=>'1904_base', :format=>:excel) do |oo|
assert_equal Date.new(2009,06,15), oo.cell(1,1)
+ assert_equal Date.new(Time.now.year,Time.now.month,Time.now.day), oo.cell(2,1) #formula for TODAY()
assert_equal :date, oo.celltype(1,1)
end
end

0 comments on commit 9b323f5

Please sign in to comment.