I'm using Google app script for sheets and I'm new to it.
I have a column with number and a hyperlink in each cell (each link and number is different).
I want to get the link then make an API request which will return a number which will replace that original number for each cell.
At the moment here is my function:
function getLinkUrls() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("B2:B");
var values = range.getRichTextValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j].getLinkUrl() !== null) {
const val = values[i][j],
url = val.getLinkUrl(),
path = url.split('/')[3];
var response = UrlFetchApp.fetch(`https://decapi.me/twitch/followcount/${path}`),
f = response.getContentText();
}
}
}
}
I want to replace each cell now with f but I'm unsure how.
Table:
Column B should always have hyperlink
I have successful replace the hyperlink with the follower count, you may try if working on your side also, since I did not use getrichtext but getvalue directly:
function getLinkUrls1() {
var sheet = SpreadsheetApp.getActiveSheet();
for (var i = 2; i <= sheet.getLastRow(); i++) {
var url = sheet.getRange(i,2).getRichTextValue().getLinkUrl();
if (url){
var path = url.split('/')[3];
var response = UrlFetchApp.fetch(`https://decapi.me/twitch/followcount/${path}`),
f = response.getContentText();
sheet.getRange(i,2).setRichTextValue(SpreadsheetApp.newRichTextValue()
.setText(f).build());
}
}
}
This is my sample data:
Related
You will need this link to solve this: - https://docs.google.com/spreadsheets/d/11PjVSWPfqOBPSej3AlQ-_T8Bws66kevR08Q2NRTmVcE/edit?usp=sharing
So this is a tricky one. I am looking to loop through the name in Sheet1 Column A, and also loop through the type in Column C. Then if Column A in Sheet1 matches the name of column A in Sheet2, AND the type is "pickup" I want to log the other information that is in Sheet 1 inside of Column C on Sheet 2. Log the things like "State", "Location", "City" next to the identical name in Sheet 2. I hope that makes sense.
I know I probably need to use a loop within a loop to do all this, but this is as far as I can get as I cannot figure out how to write the loop and then log the rows where the 2 names match.
function myFunction() {
function pullDeliveryNotes()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var dataRange = sheet.getDataRange();
var dataRange2 = sheet2.getDataRange();
var rng = sheet.getRange(2,1, dataRange.getLastRow()-1,dataRange.getLastColumn());
var rng2 = sheet.getRange(2,3, dataRange.getLastRow()-1,dataRange.getLastColumn());
var rng3 = sheet2.getRange(2,1, dataRange2.getLastRow()-1,dataRange2.getLastColumn());
var rngA = rng.getValues().toString()
var rngB = rng2.getValues().toString()
var rngC = rng3.getValues().toString()
for(var i = 0; i < rng.length; i++) {
for (var x = 0; x < rng2.length; x++) {
for (var y = 0; y < rng3.length; y++) {
if (rng[i][x][y].includes(rng3[i][x][y]) && rng2[i][x][y] === "pickUp") {
Logger.log("We got it")
}
}
}
}
}
}
Based on your problem statement.
Try this sample script:-
function checkValues() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ssSource = ss.getSheetByName('Sheet1')
const ssTarget = ss.getSheetByName('Sheet2')
const sourceRange = ssSource.getDataRange().getValues().filter(r=> r[2] === 'Pickup'); // Filtering only pickup values
const targetRange = ssTarget.getDataRange().getValues();
for(var i = 0 ; i < sourceRange.length ; i++)
{
for(var j = 1 ; j < targetRange.length ; j++)
{
if(sourceRange[i][0] === targetRange[j][0]) // if name matches
{
ssTarget.getRange(`C${j+1}`).setValue(`${sourceRange[i][3]},${sourceRange[i][4]},${sourceRange[i][5]}`) // set values in column C
}
}
}
}
I have "script A" that can list of any file in "source folder" with url
Then i write "script B" to scan all ID of them and get every email user of file's permission, but when i set "email" value to [i] rows, it will overwrite till the last user of that permission.
Examples: if file "A" has 3 users of view, a#gmail, b#gmail, c#gmail, then "script B" will overwrite till c#gmail at file "A" row. (then we dont know about a#gmail, b#gmail have viewer permission.)
function Listpermission() {
var ss = SpreadsheetApp.getActiveSheet();
var dataLength = getDataLength(); var data = getSheetValues();
for(var i = 0; i < dataLength; i++) {
if(data[i]["Condition"] != "1") continue
var thisid = SpreadsheetApp.getActiveSheet().getRange(i+1, 12).getValue()
Logger.log(thisid)
var editors = DriveApp.getFileById(thisid).getEditors()
for (var x = 0; x < editors.length;x++){
var edit = editors[x].getEmail() }
SpreadsheetApp.getActiveSheet().getRange(i+1, 14).setValue(edit)
var viewers = DriveApp.getFileById(thisid).getViewers()
for (var x = 0; x < viewers.length;x++) {
var view = viewers[x].getEmail()
Logger.log(view)
SpreadsheetApp.getActiveSheet().getRange(i+1, 13).setValue(view)
}}}
This is log of runing script, in the red box, there are 2 user of view but it overwrite at: Range(i+1,13)
Any idea to solve this isue, thank you very much.
You want to retrieve emails of editors and viewers from the file ID.
File IDs are in the column "L".
You want to put the retrieved values to the cells.
From your script, I thought that you might want to put the values of editors and viewers to a cell, respectively.
You want to put the viewers and editors to the column "M" and "N", respectively.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about creating a value using join() and putting the value to the cells? For this situation, how about the following modifications? Please think of this as just one of several answers.
Modified script 1:
Please modify your script as follows. In this modification, the for loop is modified.
function Listpermission() {
var ss = SpreadsheetApp.getActiveSheet();
var dataLength = getDataLength();
var data = getSheetValues();
for(var i = 0; i < dataLength; i++) {
if (data[i]["Condition"] != "1") continue
var thisid = ss.getRange(i+1, 12).getValue()
var editors = DriveApp.getFileById(thisid).getEditors()
var edit = [];
for (var x = 0; x < editors.length;x++) {
edit.push(editors[x].getEmail());
}
ss.getRange(i+1, 14).setValue(edit.join(","));
var viewers = DriveApp.getFileById(thisid).getViewers();
var view = [];
for (var x = 0; x < viewers.length;x++) {
view.push(viewers[x].getEmail());
}
ss.getRange(i+1, 13).setValue(view.join(","));
}
}
Modified script 2:
Please modify your script as follows. In this modification, the values are retrieved by getValues() and are created in the for loop and the created values are put to the Spreadsheet using setValues(). I think that this becomes lower cost of the process than that of getValue() and setValue().
function Listpermission() {
var ss = SpreadsheetApp.getActiveSheet();
var dataLength = getDataLength();
var data = getSheetValues();
var thisids = ss.getRange(1, 12, dataLength, 1).getValues();
var values = [];
for (var i = 0; i < thisids.length; i++) {
if (data[i]["Condition"] != "1") {
values.push(["", ""]);
continue;
}
var thisid = thisids[i][0];
var view = [];
var viewers = DriveApp.getFileById(thisid).getViewers();
for (var x = 0; x < viewers.length;x++) {
view.push(viewers[x].getEmail());
}
var edit = [];
var editors = DriveApp.getFileById(thisid).getEditors();
for (var x = 0; x < editors.length;x++) {
edit.push(editors[x].getEmail());
}
values.push([view.join(","), edit.join(",")]);
}
ss.getRange(1, 13, values.length, 2).setValues(values);
}
References:
join()
getValue()
setValue(value)
getValues()
setValues(values)
Benchmark: Reading and Writing Spreadsheet using Google Apps Script
If I misunderstood your question and this was not the result you want, I apologize.
Fill array with all values to Array and then join all values to one column.
var viewers = DriveApp.getFileById(thisid).getViewers();
var viewerEmails = [];
for (var x = 0; x < viewers.length;x++) {
var view = viewers[x].getEmail();
Logger.log(view);
viewerEmails.push(view);
}
SpreadsheetApp.getActiveSheet().getRange(i+1, 13).setValue(viewerEmails.join());
I need to fix a Google Script I've been working on. Basically, I have a json https://www.instagram.com/nike/?__a=1 that returns basic info about Nike's account on instagram. I have no problem retrieving data from objects such as "biography". But, when I try to retrieve nested objects (arrays) I'm doing something wrong because the results arrive duplicated (see attachment). Can anyone help me figure out what I'm doing wrong?
// the name of the sheet within your document
var sheetName = "Sheet1";
// the name of the Instagram account you want the follower count for
var instagramAccountName = "nike";
function insert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(this.sheetName);
var followers = [];
var followers = captionArray(this.instagramAccountName);
for(var i = 0 ; i < 3; i++) {
sheet.appendRow([Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd"), followers]);
};
}
function captionArray(username) {
var i = 0;
for(var i = 0; i < 3; i++) {
var url = "https://www.instagram.com/" + username + "/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var caption = [];
var caption = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges[i].node.edge_media_to_caption.edges[i].node.text;
return caption;
};
}
I think this is causing problems:
You're using the same index (i) for both arrays, but the second have only one element.
You just need to do one request.
This code works for me:
function captionArray(username) {
var captions = [];
var url = "https://www.instagram.com/nike/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var edges = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges;
for(var i = 0, limit = edges.length; i < limit; i++) {
captions.push(edges[i].node.edge_media_to_caption.edges[0].node.text);
}
return captions;
}
I have a google spreadsheet with two columns corresponding to lessons: the first with names of the porfessors (occasionally repeating themselves) and the second with numbers (number of hours). I would like to have as output two columns, the first with the names of the porfessors and the second with the sum of all the hours
I tried with the following code, but it seems to give me back two arrays with the initial colums, as if the condition if (names[names.length-1] == namesColumn[i]) is never met.
What am I doing wrong?
function resumeProfessors() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
var namesColumn = sheet.getRange("C4:C31").getValues();
var lessonsColumn = sheet.getRange("G4:G31").getValues();
var names = [];
names.length = 0;
var lessons = [];
lessons.length = 0;
namesColumn.sort();
for (var i = 0; i < namesColumn.length; i++) {
if (names[names.length-1] == namesColumn[i]){
lessons[lessons.length-1] = lessons[lessons.length-1] + lessonsColumn[i];}
else{
sheet.getRange(i+4, 9).setValue(names[names.length-1] + namesColumn[i]);
names[names.length] = namesColumn[i];
lessons[lessons.length] = lessonsColumn[i];
};}
writeResume(names, lessons);
}
Ty
Given your use-case, I'd recommend using a Pivot table or the =QUERY formula.
However, assuming your input sheet looks something like this -
And the expected output is something like this -
You can try the below code -
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var input = ss.getSheetByName('Sheet1');
var output = ss.getSheetByName('Sheet2');
var inputValues = input.getDataRange().getValues();
Logger.log(inputValues)
for (var i = 1; i < inputValues.length; i++) {
var name = inputValues[i][0];
var totalHours = [];
for (var j = 0; j < inputValues.length; j++) {
var hours = inputValues[j][1];
if (name == inputValues[j][0]) {
totalHours.push(inputValues[j][1]);
}
}
var outputValues = output.getDataRange().getValues();
var newEntry = true;
for (var k = 0; k < outputValues.length; k++) {
if (name == outputValues[k][0]) {
newEntry = false;
}
}
if (newEntry) {
output.appendRow([name,totalHours.reduce(function(a, b) {return a + b})]);
}
}
}
Hope this helps.
I need this script to delete the row (within the Registration sheet) with the matching Registration Code to the Cancel Registration sheet's Registration code. As of now, this script only deletes a row if "sheetR.deleteRow(i);" is not inside "if (regCodeR === regCodeCR) {}". It doesn't delete the correct row either.
function rD() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetR = ss.getSheetByName("Registration");
var sheetCR = ss.getSheetByName("Cancel Registration")
var dataR = sheetR.getDataRange().getValues();
var dataCR = sheetCR.getDataRange().getValues();
var headerRow = 1;
for (var i = 1; i in dataR && i in dataCR; ++i) {
var rowR = dataR[i];
var rowCR = dataCR[i];
var duplicate = false;
var regCodeR = sheetR.getRange(headerRow + i, 10).getValues();
var regCodeCR = sheetCR.getRange(headerRow + i, 9).getValues();
if (rowR[9] === rowCR[8]) {
duplicate = true;
}
}
if (regCodeR === regCodeCR) {
sheetR.deleteRow(i);
}
}
I tried this code with simple data having one column with registration numbers. You can modify the main sheet range according to your data. Also make sure to change the sheet names.
Tried and tested the code below :
function deleteDup(){
var mainSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('regis');
var cancelSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('cancel');
var mainSheetValues = mainSheet.getRange(2, 1, mainSheet.getLastRow(),1).getValues();
var cancelSheetValues = cancelSheet.getRange(2, 1, cancelSheet.getLastRow(),1).getValues();
var k = 0;
var del = [];
// Getting the row index of matching values
for (i = 0; i < cancelSheetValues.length; i++)
{
var cancelValue = cancelSheetValues[i][0];
Logger.log(cancelValue);
for (j = 0; j < mainSheetValues.length; j++)
{
if(mainSheetValues[j][0] == cancelValue){
del[k] = j;
k++;
}
}
}
del.sort();
var count =0;
// deleting the values from the main sheet values array
for (i = 0; i < k; i++ )
{
mainSheetValues.splice((del[i] - count), 1);
count++;
}
var len = mainSheetValues.length;
// Update the sheet with new values
mainSheet.getRange(2, 1, mainSheet.getLastRow(),1).clearContent();
mainSheet.getRange(2, 1, len,1).setValues(mainSheetValues);
}
But instead you can also do this way:
Set a flag value in the registration sheet if it matches with the cancellation sheet.
Then loop through the registration sheet data and delete the matching flag row.
Hope that helps!