2

When I use gspread to copy a cell formula from (target_cell) to (target_cell+1 row) the formula is correctly passed, however it is still referencing data from (target_cell)'s row. I need it to reference the new row's data. Similar to when you use the "drag" or copy+shift+select all appropriate cells+paste method in excel/google sheets.

look at image below: here is what I am trying to do, start at C3 and go up to C1, copying and pasting C3 formula but referencing data in rows 2 and 1

I currently can use gspread to get a formula from a particular cell using this: ([source] How to copy a formula from one gsheet to another using python?)

formula = sheet.acell("C3", value_render_option='FORMULA').value
    print(formula)

I want to copy this formula (=B3+A3) in the row above but reference A2 and B2 isntead. The only way I can see so far to update a cell is like this, however can I manipulate the formula in between?

sheet.update_acell("C2", formula)

trying to upload image again

Here is the entire code using the first response I got:

import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)

#this portion is to ensure I can reach the target spreadsheet and manipulate the spreadsheet. It does work.
sheet = client.open("stocks").worksheet("sandbox")
input=sheet.find(r"start")
tgtrow=input.row
tgtcol=(input.col)
sheet.insert_row(["",""],tgtrow+1)
sheet.update_cell(tgtrow,tgtcol+4, "hi")

#running recomended code
spreadsheetId = "stocks"
sheetName = "sandbox"

client = gspread.authorize(creds)
ss = client.open_by_key(spreadsheetId)
sheetId = ss.worksheet(sheetName)._properties['sheetId']
body = {
    "requests": [
        {
            "copyPaste": {
                "source": {
                    "sheetId": sheetId,
                    "startRowIndex": 2,
                    "endRowIndex": 3,
                    "startColumnIndex": 2,
                    "endColumnIndex": 3
                },
                "destination": {
                    "sheetId": sheetId,
                    "startRowIndex": 1,
                    "endRowIndex": 2,
                    "startColumnIndex": 2,
                    "endColumnIndex": 3
                },
                "pasteType": "PASTE_FORMULA"
            }
        }
    ]
}
res = ss.batch_update(body)
seeker407
  • 43
  • 7

1 Answers1

4
  • You want to copy a formula to a cell using gspread.
  • For example, when there is a formula of =B3+A3 in the cell "C3", you want to put the formula =B2+A2 to the cell "C2".
  • You have already been used Sheets API with gspread.

If my understanding is correct, how about this modification? I think that there are several solutions for your situation. So please think of this as just one of them.

Modification point:

  • In this modification, the copyPaste request is used by the method of batchUpdate in Sheets API.

Modified script:

When you use this, please set the variables of spreadsheetId and sheetName. In this sample script, for the sheet name of "Sheet1", the formula of the cell "C3" is copied to the cell "C2". At that time, =B3+A3 is automatically modified to =B2+A2.

spreadsheetId = "###"
sheetName = "Sheet1"

client = gspread.authorize(credentials)
ss = client.open_by_key(spreadsheetId)
sheetId = ss.worksheet(sheetName)._properties['sheetId']
body = {
    "requests": [
        {
            "copyPaste": {
                "source": {
                    "sheetId": sheetId,
                    "startRowIndex": 2,
                    "endRowIndex": 3,
                    "startColumnIndex": 2,
                    "endColumnIndex": 3
                },
                "destination": {
                    "sheetId": sheetId,
                    "startRowIndex": 1,
                    "endRowIndex": 2,
                    "startColumnIndex": 2,
                    "endColumnIndex": 3
                },
                "pasteType": "PASTE_FORMULA"
            }
        }
    ]
}
res = ss.batch_update(body)

References:

If I misunderstood your question and this was not the result you want, I apologize.

Edit:

Issue:

From your additional script, I could understand about the issue. The issue was that you are using the filename of Spreadsheet (in your case, it's stocks.) as the Spreadsheet ID. If you want to use the filename of Spreadsheet, please modify as follows.

From:

spreadsheetId = "stocks"

To:

spreadsheetId = client.open("stocks").id
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • I tried your code, but I keep getting an error: line 26 is: sheetId = ss.worksheet(sheetName)._properties['sheetId'] the error I am getting is: File "D:\....filepath...\filename.py", line 26, in sheetId = ss.worksheet(sheetName)._properties['sheetId'] .......... "code": 404, "message": "Requested entity was not found.", "status": "NOT_FOUND" – seeker407 Jul 07 '19 at 22:47
  • @seeker407 Thank you for replying. I apologize for the inconvenience. The error message means that the Spreadsheet ID declared as ``spreadsheetId = "###"`` cannot be found. If you ran the script without replacing `###` to your Spreadsheet ID, please replace it. And if you have already replaced `###` to the Spreadsheet ID, please check the Spreadsheet ID is correct. – Tanaike Jul 07 '19 at 23:03
  • @seeker407 I'm not sure about your environment, if you use Service account, please check whether Spreadsheet is shared with the Service account. If the same error occurs after above modification was done, can you provide your whole script? Of course, please remove your personal information. – Tanaike Jul 07 '19 at 23:03
  • Thank you so much for the responses! I am very grateful! I have posted the entire code that I am using. I am able to succesfully access "sandbox" sheet and manipulate it. (find "start" and add "hi" 4 columns right of "start"; as well as add a new row under the row that "start" is in). Thank you again! – seeker407 Jul 08 '19 at 01:01
  • @seeker407 I updated my answer because I could understand about your issue. Could you please confirm it? If the same error occurs, I apologize. – Tanaike Jul 08 '19 at 01:24
  • @seeker407 Thank you for replying and testing it. I'm glad your issue was resolved. – Tanaike Jul 08 '19 at 04:01