44
55module AspireBudget
66 module CoreExtensions
7+ # rubocop:disable all
78 module Worksheet
89 def rows ( skip = 0 )
910 nc = num_cols
@@ -24,9 +25,98 @@ def rows(skip = 0)
2425 def rows_with_numerics ( skip = 0 )
2526 rows ( skip ) { |row , col | numeric_value ( row , col ) || self [ row , col ] }
2627 end
28+
29+ def []=( *args ) # rubocop:disable all
30+ ( row , col ) = parse_cell_args ( args [ 0 ...-1 ] )
31+ value = args [ -1 ]
32+
33+ reload_cells unless @cells
34+ @numeric_values [ [ row , col ] ] = value . is_a? ( Numeric ) ? value : nil
35+ value = value . to_s
36+ validate_cell_value ( value )
37+
38+ @cells [ [ row , col ] ] = value
39+ @input_values [ [ row , col ] ] = value
40+ @modified . add ( [ row , col ] )
41+ self . max_rows = row if row > @max_rows
42+ self . max_cols = col if col > @max_cols
43+ if value . empty?
44+ @num_rows = nil
45+ @num_cols = nil
46+ else
47+ @num_rows = row if @num_rows && row > @num_rows
48+ @num_cols = col if @num_cols && col > @num_cols
49+ end
50+ end
51+
52+ def save # rubocop:disable all
53+ sent = false
54+
55+ if @meta_modified
56+ add_request ( {
57+ update_sheet_properties : {
58+ properties : {
59+ sheet_id : sheet_id ,
60+ title : title ,
61+ index : index ,
62+ grid_properties : { row_count : max_rows , column_count : max_cols } ,
63+ } ,
64+ fields : '*' ,
65+ } ,
66+ } )
67+ end
68+
69+ if !@v4_requests . empty?
70+ self . spreadsheet . batch_update ( @v4_requests )
71+ @v4_requests = [ ]
72+ sent = true
73+ end
74+
75+ @remote_title = @title
76+
77+ unless @modified . empty?
78+ min_modified_row = 1.0 / 0.0
79+ max_modified_row = 0
80+ min_modified_col = 1.0 / 0.0
81+ max_modified_col = 0
82+ @modified . each do |r , c |
83+ min_modified_row = r if r < min_modified_row
84+ max_modified_row = r if r > max_modified_row
85+ min_modified_col = c if c < min_modified_col
86+ max_modified_col = c if c > max_modified_col
87+ end
88+
89+ # Uses update_spreadsheet_value instead batch_update_spreadsheet with
90+ # update_cells. batch_update_spreadsheet has benefit that the request
91+ # can be batched with other requests. But it has drawback that the
92+ # type of the value (string_value, number_value, etc.) must be
93+ # explicitly specified in user_entered_value. Since I don't know exact
94+ # logic to determine the type from text, I chose to use
95+ # update_spreadsheet_value here.
96+ range = "'%s'!R%dC%d:R%dC%d" %
97+ [ @title , min_modified_row , min_modified_col , max_modified_row , max_modified_col ]
98+ values = ( min_modified_row ..max_modified_row ) . map do |r |
99+ ( min_modified_col ..max_modified_col ) . map do |c |
100+ next unless @modified . include? ( [ r , c ] )
101+
102+ @numeric_values [ [ r , c ] ] || @cells [ [ r , c ] ] || ''
103+ end
104+ end
105+ value_range = Google ::Apis ::SheetsV4 ::ValueRange . new ( values : values )
106+ @session . sheets_service . update_spreadsheet_value (
107+ spreadsheet . id , range , value_range , value_input_option : 'USER_ENTERED' )
108+
109+ @modified . clear
110+ sent = true
111+ end
112+
113+ sent
114+ end
27115 end
116+ # rubocop:enable all
28117 end
29118end
30119
31120# https://github.com/gimite/google-drive-ruby/issues/378 (PR #377)
121+ # https://github.com/gimite/google-drive-ruby/issues/380 (PR #379)
32122GoogleDrive ::Worksheet . prepend AspireBudget ::CoreExtensions ::Worksheet
0 commit comments