I've been having problems with Highcharts when requesting from a google sheet, few days ago it was all good, but suddenly it was throwing an error 404, and I don't know what to do. Higcharts only ask you to put the google spreadsheet key, and the number of the tab, and nothing else. I want to change the URL that Higcharts makes the request but I don't know how.
Error:
data.src.js:124 GET https://spreadsheets.google.com/feeds/cells/1YtSfF3-9kzx1G6zwllLX9GhkVgufSUjQyKVI3Ken-AA/2/public/values?alt=json 404
It seems like a google issue: https://support.google.com/docs/thread/121088347/retrieving-data-from-sheets-results-in-404-error-50-of-the-time
feeds is the older version of Sheets API and it's shut down.
See Google's announcement here https://cloud.google.com/blog/products/g-suite/migrate-your-apps-use-latest-sheets-api
Try tu use this function to get values as json
function getJson(id,gid){
var txt = UrlFetchApp.fetch(`https://docs.google.com/spreadsheets/d/${id}/gviz/tq?tqx=out:json&tq&gid=${gid}`).getContentText();
var jsonString = txt.match(/(?<="table":).*(?=}\);)/g)[0]
var json = JSON.parse(jsonString)
return(json)
}
with id of the spreadsheet and gid of your sheet (may be 0)
note that first row is dedicated to labels, then rows[0] corresponds to row#2 and c[0] corresponds to column A
if you want to retrieve B1 (column 2 row 1) : json.cols[1].label
if you want to retrieve B2 (column 2 row 2) : json.rows[0].c[1].v
Related
I have the below function trying to convert a webpage to xml, so I can start extracting out some data from tables etc.
function getWebpageContent() {
var url = "https://training.gov.au/Training/Details/BSBCRT501";
var xml = UrlFetchApp.fetch(url).getContentText();
var document = XmlService.parse(xml);
Logger.log(document);
}
I'm recieving this error:
Exception: Error on line 170: The entity name must immediately follow the '&' in the entity reference.
getWebpageContent # Code.gs:6
When I search that webpage for the "&" symbol, (assuming that XmlService is confusing the 'and' symbol for some sort of html code and throwing an error) I can only find one hidden one. And am not sure how to circumvent it.
Any way to dodge that error and get the webpage info as Xml in Apps Script?
From your following replying,
The output I want from this page (https://training.gov.au/Training/Details/BSBCRT501) is each in the 'Elements and Performance Criteria' table. I want to save it as an array to then reformat into my spreadsheet. I might just use IMPORTXML in a spreadsheet formula instead.
In this case, how about the following formula?
Sample formula:
=IMPORTXML("https://training.gov.au/Training/Details/BSBCRT501","//table[2]//tr")
Result:
Reference:
IMPORTXML
Added:
From your following replying,
That's a great answer thanks and the method I think I'll use. It doesn't link break at each point (2.1, 2.2 etc) unfortunately but it's still good. I don't think I can accept it as the answer though as it doesn't solve the specific Apps Script problem, but thanks a lot for this.
I added a sample script for using Google Apps Script. Could you please confirm it?
Sample script:
Before you use this script, please enable Sheets API at Advanced Google services. When you run this script, the table is put to the active sheet.
function myFunction() {
const url = "https://training.gov.au/Training/Details/BSBCRT501";
const res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
if (res.getResponseCode() != 200) throw new Error(res.getContentText());
const table = [...res.getContentText().matchAll(/<TABLE[\s\S\w]+?<\/TABLE>/g)];
if (table && table[1][0]) {
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getActiveSheet();
const resource = {requests: [{pasteData: {html: true, data: table[1][0], coordinate: {sheetId: sheet.getSheetId()}}}]};
Sheets.Spreadsheets.batchUpdate(resource, spreadsheet.getId());
}
}
References:
Class UrlFetchApp
Method: spreadsheets.batchUpdate
This guy here explains the underlying cause, and also gives the solution:
The entity name must immediately follow the '&' in the entity reference
I live oversees (military) and get emails when I have a package that arrives at my Post Office and is ready for pickup. I have a Zapier PARSER email account and associated ZAP setup that pulls the data from the email and updates a Google Sheets document with its shelf location, tracking number, and a few other important things from the email so the clerks can get my stuff quickly. It works great. In that same workbook, I have another sheet that I update using an app on my phone to scan tracking barcodes to when I physically pick up the package. On the first sheet I have a basic VLOOKUP function that looks for the tracking number in the scanned list to mark it off as PICKED UP (I get a lot of packages )
I have to manually go in and drag the function down when the ZAP creates a new row. it's not difficult, but i want to have it all automatic. that's what computers are for! I created a google script from the SCRIPT editor on my sheet to do it (I think)
function onEdit(e)
{
var row = e.range.getRow(); //Determine the Row # Just added
var sheet = e.range.getSheet(); //Determine the Sheet, probably not needed
var row_string = row.toString(); //Convert the Row Number to a string.
var start_string = "=VLOOKUP(B"; //this is a fixed part of the function I need in the E column of this row.
var end_string = ", 'Scanned Packages Fixed'!A:B, 2, FALSE)"; //This is the fixed part of the function at the end of the row.
var set_lookup_cell = start_string.concat(row_string, end_string); //Smash the strings together to build a full function
sheet.getRange(row,5).setValue(set_lookup_cell); //Put the full function of the string into the proper cell (E)
}
I am not 100% up on how this would get called automatically or if I am missing a way to link it to the sheet itself. When I hit "run" on the code I got this:
TypeError: Cannot read property 'range' of undefined (line 3, file "Code")
I went into my sheet and just added something in the first column of a new row to see what happened, nothing did.
Any help would be super appreciated!
EDIT: Basically, I need Column E of the row to say this
=VLOOKUP(B63, 'Scanned Packages Fixed'!A:B, 2, FALSE) [Where 63 is the row#]
Turns out, the code above does work. I am just not patient and didn't let the sheet update and script run automatically after an update to a row.
Turns out, this isn't triggered when the zap populates the sheet... Only if I do.
I am using the Google Sheets API V4 to retrieve its data in JSON like below. That includes all rows, even the ones currently not shown in the Spreadsheet UI because of a filtering in one of the columns.
Is there a way to get only the shown rows or information whether a row is hidden or not?
The Google Apps Script allows such data retrieval using i.e. the .hiddenByFilter Method (see https://cloud.google.com/blog/products/application-development/using-google-sheets-filters-in-add-ons ). However, I am not able to include that in my API Query whatsoever.
$.getJSON("https://sheets.googleapis.com/v4/spreadsheets/" + SpreadsheetID + "/values/Color1!A2:Q?key=<MY_API_KEY>", function(data) {
// data.values contains the array of rows from the spreadsheet. Each row is also an array of cell values.
$(data.values).each(function() {
var location = {};
location.title = this[2];
location.latitude = parseFloat(this[10]);
location.longitude = parseFloat(this[9]);
location.institution = this[3];
//location.hidden = <?>;
locations.push(location);
});
Is there any workaround?
You can use Spreadsheets.get endpoint. Then filter sheets/data/rowData/values using sheets/data/rowMetadata/hiddenByUser field client side.
I recently made a script to get info from the Adwords API report KEYWORDS_PERFORMANCE_REPORT that outputed the information to a google sheet and it worked fine.
I decided to make another report for extensions all i basically did was copy and past the old code changing the URL for the google sheet and which report it should use PLACEHOLDER_REPORT instead of the keyword one, as well as some of the metrics.
The script runs without saying that anything is wrong but it doesn't output the values to where its supposed to, or at all for that matter.
function processAccount()
{
var report = AdWordsApp.report(
"SELECT AccountDescriptiveName, CampaignName, ExtensionPlaceholderCreativeId, ExtensionPlaceholderType " +
"FROM PLACEHOLDER_REPORT " +
"WHERE CampaignStatus = ENABLED " +
"DURING LAST_7_DAYS",
{apiVersion: 'v201705'});
var rows = report.rows();
if (rows.hasNext())
{
writeReport(rows);
}
}
function writeReport(rows)
{
var spreadsheet = validateAndGetSpreadsheet(URL);
// Clear all rows in the Details tab of the spreadsheet below the header row.
var clearRange = spreadsheet.getRangeByName('Headers')
.offset(1, 0, spreadsheet.getSheetByName('Details')
.getDataRange().getLastRow())
.clearContent();
// Build each row of output values in the order of the Report tab columns.
var outputValues = [];
while (rows.hasNext())
{
var row = rows.next();
outputValues.push([
row["AccountDescriptiveName"],
row["CampaignName"],
row["ExtensionPlaceholderCreativeId"],
row["ExtensionPlaceholderType"],
]);
}
// Find the first open row on the Report tab below the headers and create a
// range large enough to hold all of the failures, one per row.
var lastRow = spreadsheet.getSheetByName('Details')
.getDataRange().getLastRow();
var headers = spreadsheet.getRangeByName('Headers');
var outputRange = headers
.offset(lastRow - headers.getRow() + 1, 0, outputValues.length);
Logger.log("outputValue length is "+outputValues.length);
outputRange.setValues(outputValues);
Logger.log(outputValues[0]);
spreadsheet.getRangeByName('Date').setValue(new Date());
}
I know its finding the sheet because it clears the rows below the header like its supposed to and puts the date and time when it is run.
The logger shows that outputValue has a length of 293 so its definitly getting stuff and also logs the stuff at outputValue[0] so i dont know why it wont write to the sheet.
I called the adwords helpline but they said thearen't't trained in the api stuff so they don't know whats up, and i've googled it with no success
Everytime it runs you just want the new values, so I suggest using
spreadsheet.getRange(1, 1, data.length, 4).setValues(outputValues);
Replace your last line with this one, the last arguments is how many columns you will write, so in your case is 4, also change your code's logic so it will write the values in the end, not at every iteration!
Turns out i had messed up the output range it was outputting it about 120 rows lower than it was supposed toi do if id just scrolled down i would of seen it. fixed that and now all is fine.
I'm trying to connect Google Sheets to JIRA to gather the data for updating reports automatically.
I'm struggling however with a couple of points in this modified script.
I want to return the component field but calling the name field returns undefined.
var components = data["issues"][id].fields.components.name;
If I remove the name field, then I get the following response:
{name=#####, self=https://www.#########/rest/api/2/component/26357, id=26357}
The second issue is that only a handful of issues are being rendered. As far as I can see my REST call looks OK, as does the writing to tables:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //select active spreadsheet
sheet.getRange(2, 1, issuessss.length, 7).setValues(issuessss); // write from cell A2
break;
Anyone have any ideas that could help?
The field component is an array so components.name does not exist (i.e components[0].name would work).
Before setting the values, try to execute a flush first.