From c9f1560b6eabbb0489e2d1397565b6d26f5a441a Mon Sep 17 00:00:00 2001 From: Drowze Date: Thu, 23 Jul 2020 21:12:37 +0100 Subject: [PATCH] Insert serial dates Numeric values should added as-is and not converted to strings. This is specially important if the user is trying to add dates in their serial form. --- lib/google_drive/worksheet.rb | 19 ++++++++++++------- test/test_google_drive.rb | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/google_drive/worksheet.rb b/lib/google_drive/worksheet.rb index b461630f..22b648d5 100644 --- a/lib/google_drive/worksheet.rb +++ b/lib/google_drive/worksheet.rb @@ -183,12 +183,15 @@ def [](*args) # worksheet[1, 3] = "=A1+B1" def []=(*args) (row, col) = parse_cell_args(args[0...-1]) - value = args[-1].to_s - validate_cell_value(value) + value = args[-1] + reload_cells unless @cells + @numeric_values[[row, col]] = value.is_a?(Numeric) ? value : nil + value = value.to_s + validate_cell_value(value) + @cells[[row, col]] = value @input_values[[row, col]] = value - @numeric_values[[row, col]] = nil @modified.add([row, col]) self.max_rows = row if row > @max_rows self.max_cols = col if col > @max_cols @@ -237,8 +240,8 @@ def input_value(*args) # # Returns nil if the cell is empty or contains non-number. # - # If you modify the cell, its numeric_value is nil until you call save() - # and reload(). + # If you modify the cell to a non-numeric object (i.e. '3' instead of 3), + # its numeric_value is nil until you call save() and reload(). # # For details, see: # https://developers.google.com/google-apps/spreadsheets/#working_with_cell-based_feeds @@ -447,7 +450,9 @@ def save [@title, min_modified_row, min_modified_col, max_modified_row, max_modified_col] values = (min_modified_row..max_modified_row).map do |r| (min_modified_col..max_modified_col).map do |c| - @modified.include?([r, c]) ? (@cells[[r, c]] || '') : nil + next unless @modified.include?([r, c]) + + @numeric_values[[r, c]] || @cells[[r, c]] || '' end end value_range = Google::Apis::SheetsV4::ValueRange.new(values: values) @@ -558,7 +563,7 @@ def merge_cells(top_row, left_col, num_rows, num_cols, merge_type: 'MERGE_ALL') # Changes the formatting of a range of cells to match the given number format. # For example to change A1 to a percentage with 1 decimal point: # worksheet.set_number_format(1, 1, 1, 1, "##.#%") - # Google API reference: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#numberformat + # Google API reference: https://developers.google.com/sheets/api/guides/formats def set_number_format(top_row, left_col, num_rows, num_cols, pattern, type: "NUMBER") number_format = Google::Apis::SheetsV4::NumberFormat.new(type: type, pattern: pattern) format = Google::Apis::SheetsV4::CellFormat.new(number_format: number_format) diff --git a/test/test_google_drive.rb b/test/test_google_drive.rb index a773ea8d..50d07793 100644 --- a/test/test_google_drive.rb +++ b/test/test_google_drive.rb @@ -44,27 +44,36 @@ def test_spreadsheet_online ws[1, 2] = '5' ws[1, 3] = '=A1+B1' ws[1, 4] = 13 + + ws.set_number_format(1, 5, 1, 2, 'yyyy-mm-dd h:mm:ss') + ws[1, 5] = 25569 + ws[1, 6] = 25570.5 + assert { ws.max_rows == 20 } assert { ws.max_cols == 10 } assert { ws.num_rows == 1 } - assert { ws.num_cols == 4 } + assert { ws.num_cols == 6 } assert { ws[1, 1] == '3' } assert { ws[1, 2] == '5' } assert { ws[1, 4] == '13' } + assert { ws[1, 5] == '25569' } + assert { ws[1, 6] == '25570.5' } ws.save ws.reload assert { ws.max_rows == 20 } assert { ws.max_cols == 10 } assert { ws.num_rows == 1 } - assert { ws.num_cols == 4 } + assert { ws.num_cols == 6 } assert { ws[1, 1] == '3' } assert { ws[1, 2] == '5' } assert { ws[1, 3] == '8' } assert { ws[1, 4] == '13' } + assert { ws[1, 5] == '1970-01-01 0:00:00' } + assert { ws[1, 6] == '1970-01-02 12:00:00' } assert { ws[1, 1].encoding == Encoding::UTF_8 } - assert { ss.export_as_string('csv') == '3,5,8,13' } + assert { ss.export_as_string('csv') == '3,5,8,13,1970-01-01 0:00:00,1970-01-02 12:00:00' } assert { ss.available_content_types.empty? } ss2 = session.spreadsheet_by_key(ss.key)