简体   繁体   中英

Google Sheets API v4 - How to get the last row with value?

How to get the last row with value in the new Google Sheets API v4?

i use this to get a range from a sheet:

mService.spreadsheets().values().get("ID_SHEET", "Sheet1!A2:B50").execute();

how to detect the last row with value in the sheet?

您可以将范围设置为“A2:D”,这将获取到工作表中的最后一个数据行。

I managed to get it by counting the total rows from current Sheets. Then append the data to the next row.

rowcount = this.mService.spreadsheets().values().get(spreadsheetId, range).execute().getValues().size()

Rather than retrieving all the rows into memory just to get the values in the last row, you can use the append API to append an empty table to the end of the sheet, and then parse the range that comes back in the response. You can then use the index of the last row to request just the data you want.

This example is in Python:

#empty table
table = {
    'majorDimension': 'ROWS',
    'values': []
}

# append the empty table
request = service.spreadsheets().values().append(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE_NAME,
    valueInputOption='USER_ENTERED',
    insertDataOption='INSERT_ROWS',
    body=table)

result = request.execute()

# get last row index
p = re.compile('^.*![A-Z]+\d+:[A-Z]+(\d+)$')
match = p.match(result['tableRange'])
lastrow = match.group(1)

# lookup the data on the last row
result = service.spreadsheets().values().get(
    spreadsheetId=SPREADSHEET_ID,
    range=f'Sheetname!A{lastrow}:ZZ{lastrow}'
).execute()

print(result)

You don't need to. Set a huge range (for example A2:D5000 ) to guarantee that all your rows will be located in it. I don't know if it has some further impact, may be increased memory consumption or something, but for now it's OK.

private List<String> getDataFromApi() throws IOException {
        String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"; 
        String range = "A2:D5000";
        List<String> results = new ArrayList<String>();
        ValueRange response = this.mService.spreadsheets().values()
                .get(spreadsheetId, range)
                .execute();
        List<List<Object>> values = response.getValues();
        if (values != null) {
            results.add("Name, Major");
            for (List row : values) {
                results.add(row.get(0) + ", " + row.get(3));
            }
        }
        return results;
    }

Look at the loop for (List row : values) . If you have two rows in your table you will get two elements in values list.

😢 Google Sheets API v4 does not have a response that help you to get the index of the last written row in a sheet (row that all cells below it are empty). Sadly, you'll have to workaround and fetch all sheet rows' into memory (I urge you to comment if I'm mistaken)

Example:

spreadsheet_id = '1TfWKWaWypbq7wc4gbe2eavRBjzuOcpAD028CH4esgKw'
range = 'Sheet1!A:Z'

rows = service.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range).execute().get('values', [])
last_row = rows[-1] if rows else None
last_row_id = len(rows)
print(last_row_id, last_row)

Output:

13 ['this', 'is ', 'my', 'last', 'row']

在此处输入图片说明


💡 If you wish to append more rows to the last row, see this

Have a cell somewhere that doesn't interfere with your datarange with =COUNTA(A:A) formula and get that value. In your case

=MAX(COUNTA(A:A50),COUNTA(B:B50))

?

If there could be empty cells inbetween the formula would be a little more tricky but I believe it saves you some memories.

2022 Update

II don't know if this will be relevant for someone in 2022, but now you can do it differently. You can just set next value as range :

const column = "A"
const startIndex = 2
const range = column + startIndex + ":" + column

In resolve you get all data in column and range with last index. I tested it on js and php

Following Mark B's answer, I created a function that performs a dummy append and then extracts the last row info from the dummy append's response.

def get_last_row_with_data(service, value_input_option="USER_ENTERED"):
    last_row_with_data = '1'
    try:

        dummy_request_append = service.spreadsheets().values().append(
            spreadsheetId='<spreadsheet id>',
            range="{0}!A:{1}".format('Tab Name', 'ZZZ'),
            valueInputOption='USER_ENTERED',
            includeValuesInResponse=True,
            responseValueRenderOption='UNFORMATTED_VALUE',
            body={
                "values": [['']]
            }
        ).execute()

        a1_range = dummy_request_append.get('updates', {}).get('updatedRange', 'dummy_tab!a1')
        bottom_right_range = a1_range.split('!')[1]
        number_chars = [i for i in list(bottom_right_range) if i.isdigit()]
        last_row_with_data = ''.join(number_chars)

    except Exception as e:
        last_row_with_data = '1'

    return last_row_with_data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM