Skip to content

Commit

Permalink
Merge pull request #1335 from burnash/1330-combining-merged-cells-pro…
Browse files Browse the repository at this point in the history
…ducing-incorrect-result-when-used-on-a-non-default-cell-range

fix `combine_merged_cells` when using from a range that doesn't start at `A1`
  • Loading branch information
alifeee authored Nov 29, 2023
2 parents 0932358 + bcac8cb commit c1f324c
Show file tree
Hide file tree
Showing 7 changed files with 2,250 additions and 1,300 deletions.
30 changes: 23 additions & 7 deletions gspread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ def wrapper(*args, **kwargs):
return decorate


def combined_merge_values(worksheet_metadata, values):
def combined_merge_values(worksheet_metadata, values, start_row_index, start_col_index):
"""For each merged region, replace all values with the value of the top-left cell of the region.
e.g., replaces
[
Expand All @@ -761,6 +761,12 @@ def combined_merge_values(worksheet_metadata, values):
Should have a "merges" key.
:param values: The values returned by the Google API for the worksheet. 2D array.
:param start_row_index: The index of the first row of the values in the worksheet.
e.g., if the values are in rows 3-5, this should be 2.
:param start_col_index: The index of the first column of the values in the worksheet.
e.g., if the values are in columns C-E, this should be 2.
"""
merges = worksheet_metadata.get("merges", [])
# each merge has "startRowIndex", "endRowIndex", "startColumnIndex", "endColumnIndex
Expand All @@ -771,14 +777,24 @@ def combined_merge_values(worksheet_metadata, values):
max_col_index = len(values[0]) - 1

for merge in merges:
start_row, end_row = merge["startRowIndex"], merge["endRowIndex"]
start_col, end_col = merge["startColumnIndex"], merge["endColumnIndex"]
merge_start_row, merge_end_row = merge["startRowIndex"], merge["endRowIndex"]
merge_start_col, merge_end_col = (
merge["startColumnIndex"],
merge["endColumnIndex"],
)
# subtract offset
merge_start_row -= start_row_index
merge_end_row -= start_row_index
merge_start_col -= start_col_index
merge_end_col -= start_col_index
# if out of bounds, ignore
if start_row > max_row_index or start_col > max_col_index:
if merge_start_row > max_row_index or merge_start_col > max_col_index:
continue
if merge_start_row < 0 or merge_start_col < 0:
continue
top_left_value = values[start_row][start_col]
row_indices = range(start_row, end_row)
col_indices = range(start_col, end_col)
top_left_value = values[merge_start_row][merge_start_col]
row_indices = range(merge_start_row, merge_end_row)
col_indices = range(merge_start_col, merge_end_col)
for row_index in row_indices:
for col_index in col_indices:
# if out of bounds, ignore
Expand Down
30 changes: 29 additions & 1 deletion gspread/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,13 +485,41 @@ def get_values(self, range_name=None, combine_merged_cells=False, **kwargs):
"""
try:
vals = fill_gaps(self.get(range_name, **kwargs))

if combine_merged_cells is True:
spreadsheet_meta = self.spreadsheet.fetch_sheet_metadata()
worksheet_meta = finditem(
lambda x: x["properties"]["title"] == self.title,
spreadsheet_meta["sheets"],
)
return combined_merge_values(worksheet_meta, vals)

# deal with named ranges
named_ranges = spreadsheet_meta.get("namedRanges", [])
# if there is a named range with the name range_name
if any(
range_name == ss_namedRange["name"]
for ss_namedRange in named_ranges
if ss_namedRange.get("name")
):
ss_named_range = finditem(
lambda x: x["name"] == range_name, named_ranges
)
grid_range = ss_named_range.get("range", {})
# norrmal range_name, i.e., A1:B2
elif range_name is not None:
a1 = get_a1_from_absolute_range(range_name)
grid_range = a1_range_to_grid_range(a1)
# no range_name, i.e., all values
else:
grid_range = worksheet_meta.get("basicFilter", {}).get("range", {})

return combined_merge_values(
worksheet_metadata=worksheet_meta,
values=vals,
start_row_index=grid_range.get("startRowIndex", 0),
start_col_index=grid_range.get("startColumnIndex", 0),
)

return vals
except KeyError:
return []
Expand Down
1,617 changes: 327 additions & 1,290 deletions tests/cassettes/WorksheetTest.test_get_values_and_combine_merged_cells.json

Large diffs are not rendered by default.

Loading

0 comments on commit c1f324c

Please sign in to comment.