module AspireBudget::CoreExtensions::Worksheet

rubocop:disable all

Public Instance Methods

[]=(*args) click to toggle source
# File lib/aspire_budget/core_extensions.rb, line 29
def []=(*args) # rubocop:disable all
  (row, col) = parse_cell_args(args[0...-1])
  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
  @modified.add([row, col])
  self.max_rows = row if row > @max_rows
  self.max_cols = col if col > @max_cols
  if value.empty?
    @num_rows = nil
    @num_cols = nil
  else
    @num_rows = row if @num_rows && row > @num_rows
    @num_cols = col if @num_cols && col > @num_cols
  end
end
rows(skip = 0) { |row, col| ... } click to toggle source
# File lib/aspire_budget/core_extensions.rb, line 9
def rows(skip = 0)
  nc = num_cols
  result = ((1 + skip)..num_rows).map do |row|
    (1..nc).map do |col|
      block_given? ? yield(row, col) : self[row, col]
    end.freeze
  end
  result.freeze
end
rows_with_numerics(skip = 0) click to toggle source

Same as #rows, but replacing cells with numeric values where they exist. Please note that this will NOT replace dirty cells with their numeric value.

@see rows @see numeric_value

# File lib/aspire_budget/core_extensions.rb, line 25
def rows_with_numerics(skip = 0)
  rows(skip) { |row, col| numeric_value(row, col) || self[row, col] }
end
save() click to toggle source
# File lib/aspire_budget/core_extensions.rb, line 52
def save # rubocop:disable all
  sent = false

  if @meta_modified
    add_request({
      update_sheet_properties: {
        properties: {
          sheet_id: sheet_id,
          title: title,
          index: index,
          grid_properties: {row_count: max_rows, column_count: max_cols},
        },
        fields: '*',
      },
    })
  end

  if !@v4_requests.empty?
    self.spreadsheet.batch_update(@v4_requests)
    @v4_requests = []
    sent = true
  end

  @remote_title = @title

  unless @modified.empty?
    min_modified_row = 1.0 / 0.0
    max_modified_row = 0
    min_modified_col = 1.0 / 0.0
    max_modified_col = 0
    @modified.each do |r, c|
      min_modified_row = r if r < min_modified_row
      max_modified_row = r if r > max_modified_row
      min_modified_col = c if c < min_modified_col
      max_modified_col = c if c > max_modified_col
    end

    # Uses update_spreadsheet_value instead batch_update_spreadsheet with
    # update_cells. batch_update_spreadsheet has benefit that the request
    # can be batched with other requests. But it has drawback that the
    # type of the value (string_value, number_value, etc.) must be
    # explicitly specified in user_entered_value. Since I don't know exact
    # logic to determine the type from text, I chose to use
    # update_spreadsheet_value here.
    range = "'%s'!R%dC%d:R%dC%d" %
        [@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|
        next unless @modified.include?([r, c])

        @numeric_values[[r, c]] || @cells[[r, c]] || ''
      end
    end
    value_range = Google::Apis::SheetsV4::ValueRange.new(values: values)
    @session.sheets_service.update_spreadsheet_value(
        spreadsheet.id, range, value_range, value_input_option: 'USER_ENTERED')

    @modified.clear
    sent = true
  end

  sent
end