Search code examples
pythongoogle-sheetscheckboxgoogle-sheets-api

How to create a checkbox with value with Python using gspread and gspread_formatting


I'm using google spreadsheets threw python and I want to create a checkbox. The checkbox is been create successfully but unfortunately without any value (When unchecked we expect FALSE). In the meanwhile, I have the following code

from time import localtime, time, sleep
from typing import Iterable, Dict, List, Set, Tuple
from gspread_formatting import DataValidationRule, BooleanCondition, set_data_validation_for_cell_range
import gspread
from oauth2client.service_account import ServiceAccountCredentials

validation_rule = DataValidationRule(
        BooleanCondition('BOOLEAN', ['TRUE', 'FALSE']),  # condition'type' and 'values', defaulting to TRUE/FALSE
        showCustomUi=True)

    
def update_sheet(sheet: 'Google_WorkSheet', org_name: str, error_type: str, num_of_rows: int) -> None:
    """
    This function updates a worksheet by inserting the parameters
    in the last row of the sheet
    :param sheet: the worksheet we modify
    :param org_name: the organization name to put in the row
    :param error_type: the FinOps error type to put in the row
    :param num_of_rows: the number of rows in the sheet
    :return: None
    """
    current_time = localtime(time())  # current_time : time.struct
    current_time = '{0}/{1}/{2}'.format(current_time[2], current_time[1], current_time[0])  # current_time : str

    note = check_error_type(error_type)
    new_row = [current_time, org_name, error_type, note]

sheet.append_row(new_row)
set_data_validation_for_cell_range(sheet, f'G{num_of_rows + 1}', validation_rule)  # inserting checkbox

This code creates the checkbox successfully but with no value in it. I know that I can use the gspread.initialize_spreadsheet().worksheet().update_cell() But I have a limited number of API calls so I don't want to use it. For example: Empty Checkbox

This checkbox has been created by the script above but we can see that there is no value in it.


Solution

  • In this case, the method of batchUpdate in Sheets API is used for putting the checkbox. But the method of set_data_validation_for_cell_ranges uses the batch update request for only creating checkbox. Ref It seems that in this method, several batch requests cannot be included. By this, the initial value cannot be seen. So in order to put the checkbox and give the initial value using one API call, in this answer, I would like to propose to use the method of batch_update in gspread. The sample script is as follows.

    Sample script:

    spreadsheetId = "###"  # Please set the Spreadsheet ID.
    sheetName = "Sheet1"  # Please set the sheet name.
    
    client = gspread.authorize(credentials)
    spreadsheet = client.open_by_key(spreadsheetId)
    sheet = spreadsheet.worksheet(sheetName)
    sheetId = sheet._properties['sheetId']
    requests = {"requests": [
        {
            "repeatCell": {
                "cell": {"dataValidation": {"condition": {"type": "BOOLEAN"}}},
                "range": {"sheetId": sheetId, "startRowIndex": 0, "endRowIndex": 3, "startColumnIndex": 0, "endColumnIndex": 3},
                "fields": "dataValidation"
            }
        },
        {
            "updateCells": {
                "rows": [
                    {"values": [{"userEnteredValue": {"boolValue": True}}, {"userEnteredValue": {
                        "boolValue": False}}, {"userEnteredValue": {"boolValue": False}}]},
                    {"values": [{"userEnteredValue": {"boolValue": True}}, {"userEnteredValue": {
                        "boolValue": True}}, {"userEnteredValue": {"boolValue": False}}]},
                    {"values": [{"userEnteredValue": {"boolValue": True}}, {"userEnteredValue": {
                        "boolValue": True}}, {"userEnteredValue": {"boolValue": True}}]}
                ],
                "start": {"rowIndex": 0, "columnIndex": 0, "sheetId": sheetId},
                "fields": "userEnteredValue"
            }
        }
    ]}
    res = spreadsheet.batch_update(requests)
    print(res)
    

    Result:

    When above sample script is run, the checkboxes are put to the cells "A1:C3" on "Sheet1" with the initial values like below.

    enter image description here

    References: