Find if a range exists in a spreadsheet - google-sheets-api

How can I list the names of the worksheets in a Google SpreadSheet? I am trying to find if a worksheet exists using DataFilters
This is my function
public bool RangeExists(string sheet, string range)
{
BatchGetValuesByDataFilterRequest r = new BatchGetValuesByDataFilterRequest();
DataFilter filter = new DataFilter();
filter.A1Range = range;
r.DataFilters = new List<DataFilter>() { filter };
var a = service.Spreadsheets.Values.BatchGetByDataFilter(r, sheet).Execute();
return a.ValueRange.Count>0;
}
This code throws this exception when I try to find if my spreadsheet has a sheet called "Sheet":
Google.Apis.Requests.RequestError
Invalid dataFilter[0]: Unable to parse range: Sheet!A:ZZ [400]
Errors [
Message[Invalid dataFilter[0]: Unable to parse range: Sheet!A:ZZ] Location[ - ] Reason[badRequest] Domain[global]
]
Thank you.

If you check REST Resource: spreadsheets you'll notice that there's a sheets property that should display all the sheets within a spreadsheet.
"sheets": [
{
object(Sheet)
}
]
So, what you can do is to make a call to spreadsheets.get. This will return that sheets object which you're looking for. You can use the Try-it from that link and indicate '*' in the "fields" parameter to return all properties (that includes the sheets).

Related

How to delete a worksheet if it exists and create a new worksheet with the same name with Office Scripts

I have a script that makes a copy of an existing worksheet and generates a table within this new worksheet called Lists.
Looking for a way to delete the new worksheet whenever the script runs again, but I keep getting the 'Worksheet activate: The requested resource doesn't exist' error with selectedSheet.activate();
let selectedSheet = workbook.getWorksheets()[0];
selectedSheet.getAutoFilter().remove();
// Duplicate worksheet.
let itemsName = "Lists";
let sheetItem = workbook.getWorksheet(itemsName);
// If `null` wasn't returned, then there's already a worksheet with the same name.
if (sheetItem) {
console.log(`Worksheet ${itemsName} already exists. Deleting...`);
// Delete the sheet.
sheetItem.delete();
} else {
let selectedSheet = workbook.getWorksheets()[0];
}
selectedSheet.activate();
let itemsSheet = selectedSheet.copy(ExcelScripWorksheetPositionType.before, selectedSheet);
itemsSheet.setName("Lists");
itemsSheet.activate();
I suggest to use the optional chaining operator (?.).
function main(workbook: ExcelScript.Workbook)
{
const itemsName = "Lists";
workbook.getWorksheet(itemsName)?.delete();
const selectedSheet = workbook.getFirstWorksheet();
const itemsSheet = selectedSheet.copy(ExcelScript.WorksheetPositionType.before, selectedSheet);
itemsSheet.setName(itemsName);
itemsSheet.activate();
}
Please refer to the below link.
https://learn.microsoft.com/en-us/office/dev/scripts/develop/best-practices#verify-an-object-is-present
https://github.com/sumurthy/officescripts-projects/tree/main/Top%205%20Tips

Date format messed up while copying data from one spreadsheet to another using Google Sheets API batchUpdate

I am copying a dataset from one spreadsheet to another and all is fine except the dates.
In the source file the dates are like "2020-07-27", but after I run the script, the dates in the destination file are in completely different format like "Sun Jul 26 18:00:00 GMT-04:00 2020".
What should I do in order to copy the date as it is - YYYY-MM-DD?
My code:
function myFunction() {
var sheet_source_values = SpreadsheetApp.openById("1JfjXPPFj08p6cxjdsdcBhTMkl6yXLJkhASG0dv4").getSheetByName(Utilities.formatDate(now,"GMT+1", "dd.MM")).getRange('A:AD').getValues()
var sheet_destination = SpreadsheetApp.openById("GTjEfvjoTJ7U7ZXwYUEnSkKtfudXZuCP0dyq").getSheetByName("Updated_sheet")
var request = {
'responseValueRenderOption' : 'UNFORMATTED_VALUE',
'valueInputOption': 'RAW',
'responseDateTimeRenderOption' : 'SERIAL_NUMBER',
'data': [
{
'range': "'Updated_sheet'!" + sheet_destination.getRange(2,1,sheet_source_values.length,sheet_source_values[0].length).getA1Notation(),
'majorDimension': 'ROWS',
'values': sheet_source_values
}
]
};
Sheets.Spreadsheets.Values.batchUpdate(request, "GTjEfvjoTJ7U7ZXwYUEnSkKtfudXZuCP0dyq");
}
I tried changing "responseValueRenderOption" and "responseDateTimeRenderOption" but could find solution :(
The problem here is not with the Sheets API, but with the way you are retrieving the values from the source spreadsheet.
According to the getValues method documentation:
getValues - Returns a two-dimensional array of values, indexed by row, then by column. The values may be of type Number, Boolean, Date, or String, depending on the value of the cell.
In this way, the values will be retrieved as a Date type, but this type is the Google default one, hence the results you are getting on the destination sheet.
In order to fix this, I suggest you use getDisplayValues instead as this will return the displayed values from the source sheet. As for the Sheets API request, you can simply keep the 'valueInputOption': 'RAW' option only.
Modified sheet_source_values
var sheet_source_values = SpreadsheetApp.openById("1bGCXCUe6cgyLQRUQrOIAT2BruBH95ybAX7iG_pyk4Q0").getSheetByName("Sheet1").getRange('A1:A4').getDisplayValues();
Modified Sheets API request
var request = {
'valueInputOption': 'RAW',
'data': [{
'range': "'Updated_sheet'!" + sheet_destination.getRange(2, 1, sheet_source_values.length, sheet_source_values[0].length).getA1Notation(),
'majorDimension': 'ROWS',
'values': sheet_source_values
}]
};
Reference
Google Apps Script Range Class - getDisplayValues();
Google Apps Script Range Class - getValues().

Google Sheets API Node.js Append Overwrite

I have a dumb question. I have a script running on google sheets. Every week, I would like to run a script and replace the data on a specific sheets.
I tried to do it through insertDataOption = OVERWRITE, but it does not work.
When I read the documentation, here what is written:
OVERWRITE The new data overwrites existing data in the areas it is written. (Note: adding data to the end of the sheet will still insert new rows or columns so the data can be written.)
Do you have any idea what I do wrong?
You are using the spreadsheets.values.append endpoint. From the documentation:
Appends values to a spreadsheet. The input range is used to search for existing data and find a "table" within that range. Values will be appended to the next row of the table, starting with the first column of the table.
If what you want, instead of appending data is to replace data in a range of your sheet, you should instead be using the spreadsheets.values.update endpoint. For your case, it can be used as follows:
function insertData(auth) {
const sheets = google.sheets({version: 'v4', auth});
var request = {
spreadsheetId: '###',
range: 'A1:D48',
valueInputOption: 'RAW',
resource: {
values: [[getting_company_name, duration_event, current_date, getting_profesional_service]]
}
};
sheets.spreadsheets.values.update(request,
(err, res) => {
if (err) return console.log('The API returned an error: ' + err);
});
}
You can find more information on creating a node js application for Sheets here
#Frenchcooc
var request = {
// The ID of the spreadsheet to update.
spreadsheetId: '###',
range: 'A1:D48',
valueInputOption: 'RAW',
insertDataOption: 'OVERWRITE',
resource: {
values: [[getting_company_name, duration_event, current_date, getting_profesional_service]]
},
auth: authClient,
};

Is there a way to get 'named' cells using EPPlus?

I have an Excel file that I am populating programmatically with EPPlus.
I have tried the following:
// provides access to named ranges, does not appear to work with single cells
worksheet.Names["namedCell1"].Value = "abc123";
// provides access to cells by address
worksheet.Cells["namedCell1"].Value = "abc123";
The following does work - so I know I am at least close.
worksheet.Cells["A1"].Value = "abc123";
Actually, its a bit misleading. The Named Ranges are stored at the workBOOK level and not the workSHEET level. So if you do something like this:
[TestMethod]
public void Get_Named_Range_Test()
{
//http://stackoverflow.com/questions/30494913/is-there-a-way-to-get-named-cells-using-epplus
var existingFile = new FileInfo(#"c:\temp\NamedRange.xlsx");
using (var pck = new ExcelPackage(existingFile))
{
var wb = pck.Workbook; //Not workSHEET
var namedCell1 = wb.Names["namedCell1"];
Console.WriteLine("{{\"before\": {0}}}", namedCell1.Value);
namedCell1.Value = "abc123";
Console.WriteLine("{{\"after\": {0}}}", namedCell1.Value);
}
}
You get this in the output (using an excel file with dummy data in it):
{"before": Range1 B2}
{"after": abc123}

EPPLUS - Get Name Of Cell//Range

I know it is possible to give a cell a name, as answered in the following question:
EPPLUS - Rename Cell
How can you see if a given cell/range has a name and retrieve that name?
There is a property i.e. IsName that can determine the range has a name or not. But it seems not to work properly. I suppose you to query the named cells collection i.e. sheet.Names or book.Names (they contains all the names in the sheet or the book). Then compare FullAddressAbsolute to the given cell to get the named cell you want.
var cell = sheet.Cells["C1"]; // cell you wanna find the name
ExcelNamedRange namedCell = null;
foreach (var item in book.Names)
{
if (item.FullAddressAbsolute.Equals(cell.FullAddressAbsolute))
{
namedCell = item;
break; // if you don't wanna find all
}
}
// if (namedCell == null) --> NOT FOUND
// else
// namedCell.Name : contains the name you wanna retrieve
LINQ can also be used instead of the loop:
namedCell = book.Names.Where(item => item.FullAddressAbsolute.Equals(cell.FullAddressAbsolute)).FirstOrDefault();