So, i've made an application that fetches data from Spreadsheet with a rest api call.
This data is being mapped from the ValueRange object to a list of custom object and cached in the application for 10 minutes.
I'd like to be able to update a single cell of a specified row of which I do not know the range value (for example 'E9') of.
Is there a good way to loop through the items in the spreadsheet and update a cell value where another field value matches?!
public static void UpdateQuantity(string nameToMatch, int quantity)
{
// find row where column A matches nameToMatch
// update value of column B with quantity
// finally clear cache to get the new data
CacheHelper.ClearCache();
}
If else, when iterating through rows in spreadsheet, how do I know the current row number so I would do a REST call to update the specific cell?
Thanks in advance.
Related
We have multiple columns in our google excel sheet as below,
image1
We are trying following API call,
https://sheets.googleapis.com/v4/spreadsheets/7dj1kU54fgrhQk46uMrqq-W-QMlBq45kjiuEdhfjm5zE5gNvUoLk/values/'sheet1'!A2:O200?dateTimeRenderOption=SERIAL_NUMBER&valueRenderOption=UNFORMATTED_VALUE&majorDimension=ROWS
By hitting the above call, we get the output as below,
image2
But, we want the value of column Currency same as available in the sheet. That is $667 where as we just get 667 by the above API call.
If we just replace the value of valueRenderOption with FORMATTED_VALUE, we get the output as below,
image3
But, then it returns the value of all columns as formatted. We just want to get the value particular column as FORMATTED_VALUE. Is there any by which we can do this?
Unfortunately not - you need to make two API calls if you want different cells to have different ValueRenderOptions. This is a limitation of the API itself, as the specified ValueRenderOption must be the same for the whole range in a single call.
I can read whole rows of table using this:
myexcel = pd.ExcelFile("my_Excel.xlsx")
my row = myexcel.parse(2, skiprows=14, skipfooter= 2).dropna(axis=1, how='all')
Using this and some additional params I could read a single specific cell value. But is it possible to just read this single cell from sheet by providing just cell coordinates(let's say cell('J10'))?
UPDATE
I would like to get a solution using pd.ExcelFile if possible...
I have created a spread sheet to track appointments. Within this spread sheet I have dynamic dependent drop down lists, so the choice from list 1 will populate the options in list 2. This is as follows:
Cell C2: Client - Client 1 or Client 2. (this is for the use of the example, the actual lists will expand.)
If cell C2 = Client 1 then the address drop down is as below:
Cell C3: Address - Address 1 or Address 2.
If cell C2 = Client 2 then the address drop down is as below:
Cell C3: Address - Address 3 or Address 4.
The data validation for the client list is simple because this is constant and can be copied from column to column. The data validation for the dependent address list, however, can not be copied across multiple columns as it will always refer to column C and lose connection with the relative client list.
The actual data validation for the cell C3 (Address List) is below:
Cell Range = 'DIARY (V-2.1)'!C3
Criteria = 'DIARY (V-2.1)'!C53:C55
The cells C53:C55 are populated by a filter formula which will sort the relevant addresses dependent on the choice of client in cell C2, this in turn populates the address list in C3.
It may be worth noting that I have 10 sets of these appointment slots per column (10 per day) so I have used a filter function for each of these separate appointments so they work independently, but even this is tedious so my need is to be able to copy the column (or just the data validation) from column C onward and have it stay relative to the filter functions in that column.
Please see the below link to the example spreadsheet and this will all make sense! In the example I have copied column C to column D and the data validation for the address list has detached for all ten appointment slots. (permission is free for all to edit.)
https://docs.google.com/spreadsheets/d/1sOlQEzG1D29RaY86YeR1Da--c8t94J-ZAGjv52U4dsY/edit#gid=1950191921
Note: These cells must be drop down lists - list from range - for the functionality of this specific spreadsheet.
If anyone can help with this it would be MASSIVELY appreciated as I have diligently scoured the forums and cannot find a solution. I did see this video (which is way over my head) that seems to accomplish this using java script:
https://www.youtube.com/watch?v=ZiYnuZ8MwgM&feature=youtu.be
Google Sheets does not currently have a built-in solution for copying/filling data validation references or formulas relatively. But somebody already wrote a nice script in this Google Docs forum post. To avoid just a link as an answer, I'm going to copy in the script and instructions here. Credit to AD:AM from Google Docs forum.
How to use their script:
Select a range of cells across which you want to copy a data validation rule, relatively
From the Validation+ custom menu, select the appropriate option (all references relative, columns absolute, or rows absolute)
The validation of the upper-left cell will be copied to the rest of the range
Link to original solution's example Google Sheets with script already included - you can save your own copy and then start using.
Or to recreate from scratch, here is the script.
function onOpen()
{
SpreadsheetApp.getActiveSpreadsheet().addMenu
(
"Validation+",
[
{name: "Copy validation (all relative references)", functionName: "copyValidation"},
{name: "Copy validation (relative rows, absolute columns)", functionName: "copyValidationColumnsAbsolute"},
{name: "Copy validation (absolute rows, relative columns)", functionName: "copyValidationRowsAbsolute"}
]
);
}
function copyValidation(rowsAbsolute, columnsAbsolute)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var r = ss.getActiveRange();
var dv = r.getDataValidations();
var dvt = dv[0][0].getCriteriaType();
if (dvt != SpreadsheetApp.DataValidationCriteria.VALUE_IN_RANGE) return;
var dvv = dv[0][0].getCriteriaValues();
Logger.log(dvv);
for (var i = 0; i < dv.length; i++)
{
for (var j = i ? 0 : 1; j < dv[0].length; j++)
{
dv[i][j] = dv[0][0].copy().withCriteria(dvt, [dvv[0].offset(rowsAbsolute ? 0 : i, columnsAbsolute ? 0 : j), dvv[1]]).build();
}
}
r.setDataValidations(dv);
}
function copyValidationRowsAbsolute()
{
copyValidation(true, false);
}
function copyValidationColumnsAbsolute()
{
copyValidation(false, true);
}
If you only need the relative copy for a single sheet, you can produce an ods with OpenOffice or LibreOffice that has a relative validation. This is done by removing the $ signs. If you then open load that sheet to your google drive and allow it to be converted to a google sheet, data validation range will be relative if you copy it anywhere in the same sheet. It is not relative if you copied it to another sheet in the same workbook or other google spreadsheets.
For example, if you make the validation for A7 to be the three cells to the right, you'll have something like follows:
Once you save it without the $ it is relative. Then when you upload it you have a sheet with relative validations.
I am currently working with a client that generates their invoices manually in Excel. I have used epplus to generate this file automatically for them.
One of the requirements I have is that each page should have a border around it and start with a header that is about 7 rows long (and each row has different heights based on what I have to put in them). In order to do this, I need to detect when I am at the end of a page so that I can pause my data printing and print out the header, then print out all the data for that page and print the border on the page based on how many rows are on the page.
This was a bit easier when the row heights were static because I could just assume that based on the page settings, that there were a specific amount of rows per page. However, some of the rows on the invoice can have multiple lines which means that WrapText = true. This obviously alters the numbers of rows on the page which throws all my formatting off.
Is there a way to calculate how many rows are on a page and detect when I am on a row where the page ends?
Thanks in advance for any help
To get the row count, and column count, I used the following code:
// get the first worksheet in the workbook
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets[1];
//Gets the row count
var rowCnt = worksheet.Dimension.End.Row;
//Gets the column count
var colCnt = worksheet.Dimension.End.Column;
Is there any way to find the last row you have written in a google spreadsheet in Java?
I tried to do that by having a variable which I keep in another file and I update that every time I do another writing. Is there any other way?
Finding last written row in Google Spreadsheet API
I'll give you a concept first using REST calls but you'll have to apply that in Java.
Exceed the range of cells where you're writing.
So to find last written row between cells A1:A10, use the range A1:A11 or A1:B (using B means all the rows in cell A will be traversed).
Fetch a range of cells, using GET. Parse the response result. And get the length of the parsed values. The length will always indicate the last row since Sheetsv4 ignores blank/empty cells.
So example I have a range of cells between A1:A10. I wrote "hello" in A10. Following the concepts above I do this:
..
xhr.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/'+myspreadsheetId+'/values/Sheet1!A1:A10);
..
xhr.onload = function (oEvent) {
arrayBuffer = xhr.response;
myArray = JSON.parse(arrayBuffer);
console.log("last row is " + myArray.values.length)
.. //output is 'last row is 10'
This part of my XHR request returns 10. Now I know that the last written row in my sheet is A10.
To do this in Java use the solution based on this SO thread.
mService.spreadsheets().values().get("ID_SHEET", "Sheet1!A1:B").execute();
Also check this thread about writing on data cells using Java. I think it offers additional insight as well.