I have a DataFrame "budget" that im trying to upload in a heavy spreadsheet with 22 tabs and more than 1 with RawData in some form in their name: "Raw Data >>", "RawData", "RawData_TargetCompletion"
I have the following code:
class GoogleSheets():
def __init__(self):
google_service_account_path = 'some_path'
scopes = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
self.credentials = ServiceAccountCredentials.from_json_keyfile_name(google_service_account_path, scopes)
self.sheets_connection = gspread.authorize(self.credentials)
def load_spreadsheet(self, spreadsheet_key):
self.sheet = self.sheets_connection.open_by_key(spreadsheet_key)
def load_worksheet(self, worksheet_name):
self.worksheet = self.sheet.worksheet(worksheet_name)
def clear_range(self, data_range):
self.sheet.values_clear(data_range)
spreadsheet_key = "this is a spreadsheet key"
worksheet_name = "RawData"
cell_ref = 'A:AT'
google_sheets = sheets.GoogleSheets()
google_sheets.load_spreadsheet(spreadsheet_key)
google_sheets.load_worksheet(worksheet_name)
google_sheets.clear_range(cell_ref)
google_sheets.upload_dataframe(budget)
I have a problem that in that heavy spreadsheet, its clearing the first tab (not the RawData), and updating in the RawData sheet.
This exact same code, but with another spreadsheet_key works fine and clears and updates the correct RawData tab regardless of the position of that RawData tab.
But in this heavy one, RawData has to be the first tab in the document because the clear part is not mapping correctly and clears the first tab always.
Is there a problem you see in the code I'm not seeing or have you encountered the same problem when updating heavy spreadsheets?
I believe your goal as situation as follows.
You want to clear the range using gspread.
You have already been able to use Sheets API.
Modification points:
When I saw values_clear(range) in the document of gspread, it seems that it is the method of class gspread.models.Spreadsheet. Ref And, range of values_clear(range) is A1Notation.
In your script, self.sheet.values_clear('A:AT') is run. In this case, 1st tab is always used because the sheet name is not used. I thouthg that this is the reason of your issue.
In order to remove your issue, I would like to propose to use the sheet name to the A1Notation for values_clear(range).
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
google_sheets.clear_range(cell_ref)
To:
google_sheets.clear_range("'{0}'!{1}".format(worksheet_name, cell_ref))
References:
values_clear(range)
A1 notation
Related
Can't seem to find any answer to this, but are there any functions/methods which can get a worksheet ID?
Currently, my code looks like this:
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
....code to authorize credentials goes here....
sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet))
client.import_csv('abcdefg1234567abcdefg1234567', contents)
but I don't want to hardcode the abcdefg1234567abcdefg1234567. Is there anything I can do, like sheet.id()?
I believe your goal as follows.
In order to use import_csv, you want to retrieve the Spreadsheet ID from sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet)).
You want to achieve this using gspread with python.
In this case, you can retrieve the Spreadsheet ID from client.open(str(self.googleSheetFile)). So please modify your script as follows.
From:
sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet))
client.import_csv('abcdefg1234567abcdefg1234567', contents)
To:
spreadsheet = client.open(str(self.googleSheetFile))
sheet = spreadsheet.worksheet(str(self.worksheet))
client.import_csv(spreadsheet.id, contents)
Note:
When I saw the document of gspread, it says as follows. So please be careful this.
This method removes all other worksheets and then entirely replaces the contents of the first worksheet.
This modified script supposes that you have already been able to get and put values for Google Spreadsheet using Sheets API with gspread.
Reference:
import_csv(file_id, data)
As above I'm trying to update more than one sheet file with the same information using the sheet IDs as the identifier. I''ve attempted to achieve this with for loops with no success. Some of the basic code that I'm trying to achieve this with is:
conn = gspread.authorize(credentials)
sheets = ['sheetid1', 'sheetid2']
worksheet_list = conn.open_by_key(sheets).worksheet("Rack Layout")
worksheet_list.update_acell('Q1', 'some cell value')
So if I define 'sheets' as one sheetid the updates work fine, however if I define 'sheets' as more than one sheet I get the error. I know this is really basic and I think the issue is its trying to open the full list (i.e. both sheetids) on the same line, rather than saying 'run this line for one sheetID and then the next'. I think the way to achieve this is a for loop, but I've yet to get this to work with a for loop. I know this is a nube question, but I've been trying for a while now, and from my searching I haven't found any other forum posts about getting gspread to do this.
You have 2 Google Spreadsheets.
2 Google Spreadsheets have the sheet of "Rack Layout", respectively.
You want to put the value of "some cell value" to the cell "Q1" in the sheet of "Rack Layout" for each Spreadsheet.
You want to achieve this using gspread with python.
You have already been able to get and put values for Spreadsheet using Sheets API.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In this modified script, the value is put to each Spreadsheet using the for loop.
Modified script:
conn = gspread.authorize(credentials)
sheets = ['sheetid1', 'sheetid2']
for sheet in sheets: # Added
worksheet_list = conn.open_by_key(sheet).worksheet("Rack Layout")
worksheet_list.update_acell('Q1', 'some cell value')
If I misunderstood your question and this was not the direction you want, I apologize.
Using pygsheets, I was looking around for a good way to open a Google sheet (by title) if it already exists, otherwise create it.
At the same time, I also wanted to make it r/w to myself and r/o to the rest of the world upon creating it.
Here's something that does just that:
import pygsheets
creds_file = "/path/to/your_creds_file.json"
gc = pygsheets.authorize(service_file=creds_file)
sheet_title = "my_google_sheet"
# Try to open the Google sheet based on its title and if it fails, create it
try:
sheet = gc.open(sheet_title)
print(f"Opened spreadsheet with id:{sheet.id} and url:{sheet.url}")
except pygsheets.SpreadsheetNotFound as error:
# Can't find it and so create it
res = gc.sheet.create(sheet_title)
sheet_id = res['spreadsheetId']
sheet = gc.open_by_key(sheet_id)
print(f"Created spreadsheet with id:{sheet.id} and url:{sheet.url}")
# Share with self to allow to write to it
sheet.share('YOUR_EMAIL#gmail.com', role='writer', type='user')
# Share to all for reading
sheet.share('', role='reader', type='anyone')
# Write something into it
wks = sheet.sheet1
wks.update_value('A1', "something")
My work here is to get data from google sheets and put those values in the webpage text box - using python
In my google sheet, I have 450 rows which are comma-separated values.
I need put all the 450 rows data into the webpage text box using selenium send.key().
##getting data from google sheets.
scope = ['https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('json',scope)
client = gspread.authorize(credentials)
workbook = client.open_by_url("https://docs.googlesheet") # using google sheet here
sheet1 = workbook.worksheet("Sheet1")
##converted sheet1 data into a dataframe called dera.
dera = gd.get_as_dataframe(sheet1, evaluate_formulas=True, skiprows=0, has_header=True)
##from dera dataframe reading 'names' column and removing null values.
del = dera[['names']].dropna()
##Converted my dataframe into list- I have read it will be easy to put list(z) values in send keys
z = del['names'].values.tolist()
Selenium code:
driver = webdriver.Chrome(executable_path="/Users/naveenbabudadla/Documents/automation/chromedriver")
driver.get("https://google.com/") # using google.com as example
driver.find_element_by_xpath("//div[text()='Maximum 5000 names'] /..//textarea").send_keys(z) ## got stuck here.
time.sleep(2)
not able to define "z" to selenium send keys correctly.
Can someone help me with this?
So let's forget about whole code before z = del['names'].values.tolist() and assume it works, you could change del name to some other name as del is a build in symbol in python. But if it works then it wokrs.
So it seems that z is some list, let's say it's a list of strings then it would look like ['value1', 'value2']. If you want to send it to your browser as is you should change it to string with str(z). Perhaps you want to send some value of your list then you chould send z[0]. But still all of these are my quesses, you should provide exact stacktrace of your errror.
I am a beginner in python. I have written few DBQ statements in excel to fetch
result in excel which should be refreshed whenever the excel is opened. Have given the correct setting in connection properties.
Below is my python code for refreshall:-
import win32com.client
import time
xl = win32com.client.DispatchEx("Excel.Application")
wb = xl.workbooks.open("D:\\Excel sheets\\Test_consolidation.xlsx")
xl.Visible = True
time.sleep(10)
wb.Refreshall()
I have 3 sheets in the excel file, which has 3 different connections. I want to refresh one after the other.
Can someone help me with the python code to refresh the connections individually ? I would be really grateful for your help.
So if you want to refresh all of them but one after the other, instead of wb.Refreshall(), the command would be:
for conn in wb.connections:
conn.Refresh()
If you want to link (in a dictionary for example) a connection to a sheet:
dict_conn_sheet = {} # create a new dict
for conn in wb.connections: # iterate over each connection in your excel file
name_conn = conn.Name # get the name of the connection
sheet_conn = conn.Ranges(1).Parent.Name # get the name of the sheet linked to this connection
# add a key (the name of the sheet) and the value (the name of the connection) into the dictionary
dict_conn_sheet[sheet_conn] = name_conn
Note: if one sheet has more than one connection, this is not a good way.
Then, if you want to update only one connection on a specific sheet (in my example it is called Sheet1):
sheet_name = 'Sheet1'
# refresh the connection linked to the sheet_name
# if existing in the dictionnary dict_conn_sheet
wb.connections(dict_conn_sheet[sheet_name]).Refresh()
Finally, if you know directly the name of the connection you want to update (let's say connection_Raj), just enter:
name_conn = 'connection_Raj'
wb.connections(name_conn).Refresh()
I hope it's clear even if it does not answer exactly to your question as I'm not sure I understood what you want to do.