openByURL opens first value and arrays down selected column - google-apps-script

This will only open F2 and will array that value down column G...help?
function CountData() {
var sheet = SpreadsheetApp;
var urlsheet = sheet.getActiveSpreadsheet().getSheetByName('Sheet1');
var url = urlsheet.getRange('F2:F100').getValues();
for(var i=0;i<url.length;++i){
var formsheet = sheet.openByUrl(url);
var CountRows = formsheet.getActiveSheet().getLastRow();
urlsheet.getRange('G2:G').setValue(CountRows);
}
};

You're looping through the array, but you're not using the actual value. Keep in mind that .getValues() returns a 2-dimensional array, so you need to access the value using [i][0].
function CountData() {
var sheet = SpreadsheetApp;
var urlsheet = sheet.getActiveSpreadsheet().getSheetByName('Sheet1');
var urls = urlsheet.getRange('F2:F100').getValues(); // Renamed to be plural, indicating some kind of list
for(var i=0;i<urls.length;++i){
var formsheet = sheet.openByUrl(urls[i][0]); // Select the URL
// ... the rest of your code
}
};
I think the rest of the code in your for-loop will have issues because
The script is not container-bound to formsheet, so you can't access .getActiveSheet(). Try something like .getSheetByName() instead.
You're not updating the range urlsheet.getRange('G2:G'), so you're going to be replacing the values in that column for every url.

function CountData() {
var ush=SpreadsheetApp.getActive().getSheetByName('Sheet1');
var uv=ush.getRange(2,6,99,1).getValues().map(function(r){return r[0];});
var rA=[];
uv.forEach(function(url){rA.push([SpreadsheetApp.openByUrl(url).getActiveSheet().getLastRow()])});
ush.getRange(2,7,rA.length,rA[0].length).setValues(rA);
}

Related

How to remove part of a sentence based on the frequency of a particular letter in using apps script?

There is a URL I scraped to google Sheets from the internet. I want to delete an original part of it. There I found a pattern like this. The symbol "/" is used several times in every URL. I want to remove the characters up to the fourth occurrence of "/".
The URL inside the cell is like this https://www.wensite.com/username/how-to-remove-part-of
The result should be like this. how-to-remove-part-of
Since the URL is wrapped, remove it and copy the link using the code below.
function urlText(){
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet().getActiveSheet();
var lC = ss.getLastColumn();
for(i=2; i<lC; i++){
var cellVal = ss.getRange(2,i).getRichTextValue().getLinkUrl();
var count = cellVal.length;
var find =cellVal.lastIndexOf("/");
var remove =cellVal.replace().endsWith(find);
//ss.getRange(9,i).setValue(cellVal);
}
}
From your answer of I solved the problem using this code, when I saw it, I'm worried that getRange, getRichTextValue() and setValue are used in a loop, the process cost becomes high. So, as another approach, I would like to propose the following modification by reducing the process cost.
Modified script:
function urlText() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(2, 2, 1, sheet.getLastColumn() - 1);
var values = range.getRichTextValues()[0].map(c => {
var url = c.getLinkUrl();
return url ? (url.split("/")[4] || null) : null; // or return url ? url.split("/").pop() : null;
});
range.offset(7, 0).setValues([values]);
}
I think that when this script is run, the same result as the script in your answer is obtained.
References:
getRichTextValues()
map()
I solved the problem using this code
function urlText(){
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet().getActiveSheet();
var lC = ss.getLastColumn();
for(i=2; i<lC+1; i++){
var cellVal = ss.getRange(2,i).getRichTextValue().getLinkUrl();
var count = cellVal.length;
var find =cellVal.lastIndexOf("/");
var remove =cellVal.slice(find+1,count);
ss.getRange(9,i).setValue(remove);
Logger.log(remove);
}
}

How do I store a JSON loop value and send it to an empty sheet?

I'm pulling data from an API.
I parsed the JSON file and ran it through a loop to grab each index present within the file(14 indexes).
I believe my code stores the values in i?
So when I use log, it returns json[i][2], which logs 14 different values.(perfect)
But when I use return, it only returns 1 value into my google sheet.
What am I doing wrong?
Thanks!
function myKlines(){
var url='https://api1.binance.com/api/v3/klines?symbol=ADAUSDT&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
for(var i=0; i<json.length; i++){
var loop = json[i][2];
Logger.log(loop);
}
By function =myKlines(A1)
function myKlines(code){
var url='https://api1.binance.com/api/v3/klines?symbol='+code+'&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
for (var i=0;i<json.length;i++){json[i][0] = new Date(json[i][0])}
return json
}
for date/high/low/close
function myKlinesExtract(code){
var url='https://api1.binance.com/api/v3/klines?symbol='+code+'&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
var result = []
result.push(['Date','High','Low','Close'])
for (var i=0;i<json.length;i++){
result.push([new Date(json[i][0]),json[i][2],json[i][3],json[i][4]])
}
return result
}
https://docs.google.com/spreadsheets/d/1JDT1TSwbAVcMrhWEHGH8jprt0u_gAnRqjY_W7W7SaQ4/copy
As you have it now, you are iterating through the variable json, but you aren't doing anything with the data.
To save the data from the loop, you need to put each iteration into an array or an object.
To make it easy, here it is with an array:
function myKlines(){
var url='https://api1.binance.com/api/v3/klines?symbol=ADAUSDT&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
var output = []; //declaring an empty array
for (var i=0; i<json.length; i++){
var loop = json[i][2];
Logger.log(loop);
// add the contents of this iteration to the output array
output.push(loop);
}
Logger.log(output);
// send the output to a function to paste the data into your sheet.
// you could also just replace below with the paste code
pasteOutput(output);
}
Next, to paste it into a sheet, you need to build the range it will go into. I am guessing you want to paste the 14 indexes into different cells. Here is the 14 cells in a single column:
function pasteOutput(output){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('your sheet name');
// get how many items there are in your array
var outputLength = output.length;
// this gets a range that starts at row 1, col 1, and has as many rows
//as your array has items, and is 1 column wide
var pasteRange = sheet.getRange(1,1,outputLength,1);
/*
Sheets takes values as a 2 dimensional array with
the inner array being a row, and the items inside the inner array the columns like this:
[[row1col1, row1col2, row1col3],[row2col1, row2col2, row2col3],[row3col1, row3col2, row3col3],...]
*/
// this statement will take each item in the output array,
//make it an array of one thing, and add that to the pasteArray
var pasteArray = output.forEach(item => pasteArray.push([item]));
pasteRange.setValues(pasteArray);
}
To put the cells in a single row, omit the pasteArray line, and change your pasteRange to (1,1,1 outputLength)
By this way, you will get all datas at once in sheet ADAUSDT
function myKlinesAll(){
var url='https://api1.binance.com/api/v3/klines?symbol=ADAUSDT&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ADAUSDT')
var headers = ["Open time","Open","High","Low","Close","Volume","Close time","Quote asset volume","Number of trades","Taker buy base asset volume","Taker buy quote asset volume","Ignore"]
for (var i=0;i<json.length;i++){json[i][0] = new Date(json[i][0])}
sheet.getRange(1,1,1,headers.length).setValues([headers])
sheet.getRange(2,1,json.length,json[0].length).setValues(json)
}
By this way, you will retrieve only column#2 (High)
function myKlines(){
var url='https://api1.binance.com/api/v3/klines?symbol=ADAUSDT&interval=1d&limit=14'
var source = UrlFetchApp.fetch(url).getContentText()
var json = JSON.parse(source)
var result = []
result.push(['Date','High'])
for (var i=0;i<json.length;i++){
result.push([new Date(json[i][0]),json[i][2]])
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ADAUSDT')
sheet.getRange(1,18,result.length,result[0].length).setValues(result)
}

How to apply filters of spreadsheet using google apps scripts?

I need to apply a filter on a spreadsheet and then apply the filter on the active spreadsheet.
Tried using the Filter Class but not sure what is incorrect
'''
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("main sheet");
var dataMatrix1 = activeSheet.getRange(1, 1, activeSheet.getLastRow(), activeSheet.getLastColumn());
function applyFilter(){
Logger.log("mark1");
var filteredData = dataMatrix1.createFilter(); //filter created
var a = 'a';
filteredData.sort(1, false);
filteredData.setColumnFilterCriteria(1 , a);
Logger.log("Mark2");
}
'''
The spreadsheet has 2 rows with value = 'a' in the first column. Need to apply a filter to the sheet and filter out rows with value = 'a'.
You are very close to accomplish your request; you only need to create a filter criteria instead of using the a variable. You can see exactly which methods to use on the following code. Also, the filtered string must be inside of an array, so I sightly modified your a variable.
function applyFilter() {
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
"main sheet");
var dataMatrix1 = activeSheet.getRange(1, 1, activeSheet.getLastRow(),
activeSheet.getLastColumn());
var filteredData = dataMatrix1.createFilter(); //filter created
var a = ['a'];
filteredData.sort(1, false);
var filterCriteria = SpreadsheetApp.newFilterCriteria().setHiddenValues(a)
.build();
filteredData.setColumnFilterCriteria(1, filterCriteria);
}
Please, do not hesitate to ask for more help if you keep having problems.

Google App Scripts - Copy file into folder with names from ranges

I'm working in Google Sheets and I'm trying to create a script that will make a set number of copies of the current file, giving each copy the next name from a list of names in a range, and place those files in folders that were created by a previous script. I was able to get it all working, but only for the first file (out of 6, and possible far more) and can't figure out what I'm doing wrong.
Here's a copy of the sheet. I also have another version of this that works to just create copies of the document, but I'm trying to streamline the process for my end users who may be creating dozens of copies and was hoping that doing the organization for them would help.
Thanks for your help!
Here's the script:
function createcopies2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store necessary data.
var CoachNames = ss.getRangeByName("CoachNames");
var CoachObjects = CoachNames.getValues();
var schoolNames = ss.getRangeByName("SchoolNames");
var SchoolObjects = schoolNames.getValues();
var id = ss.getId();
// The next variable gets a value that counts how many CoachNames there are in the spreadsheet
var coaches = ss.getRangeByName("Coaches");
var numcoaches = coaches.getValue();
//here's the function
for(i=0; i<numcoaches; i++){
var drive=DriveApp.getFileById(id);
var name=CoachObjects[i].toString();
var folder=DriveApp.getFoldersByName(SchoolObjects[i]).next();
var folderid=folder.getId();
var folder2=DriveApp.getFolderById(folderid)
if(folder) {
drive.makeCopy(name, folder2)}
else{
drive.makeCopy(name);
}
return;
}
}
You are on the right track.
I have modified you below, with explanation:
function createcopies2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store necessary data.
var CoachNames = ss.getRangeByName("CoachNames");
//The below statements a 2D dimensional array.
//To access the individual value you will have a statement like this
//CoachObjects[0][0],CoachObject[1][0],[2][0] ..., down the row
var CoachObjects = CoachNames.getValues();
var schoolNames = ss.getRangeByName("SchoolNames");
//The below statements a 2D dimensional array.
var SchoolObjects = schoolNames.getValues();
var id = ss.getId();
// The next variable gets a value that counts how many CoachNames there are in the spreadsheet
var coaches = ss.getRangeByName("Coaches");
var numcoaches = coaches.getValue();
//Moved the below statement out of the loop
// Baceause you are using the same file
var drive=DriveApp.getFileById(id);
//here's the function
for(i=0; i<numcoaches; i++){
var name=CoachObjects[i][0].toString();
var folder=DriveApp.getFoldersByName(SchoolObjects[i][0]).next();
var folderid=folder.getId();
var folder2=DriveApp.getFolderById(folderid)
if(folder) {
drive.makeCopy(name, folder2)}
else{
drive.makeCopy(name);
}
return;
}
}
I modified the code since you get a 2D array from getValues
//The below statements a 2D dimensional array.
var CoachObjects = CoachNames.getValues();
To access the individual value you will use a statement like this
`CoachObjects[0][0]`
CoachObjects[1][0]
....... [2][0] ...
down the row
Also, These are redundant lines of code:
var folder=DriveApp.getFoldersByName(SchoolObjects[i][0]).next();
var folderid=folder.getId();
var folder2=DriveApp.getFolderById(folderid)
you can just replace it with
var folder2=DriveApp.getFoldersByName(SchoolObjects[i][0]).next();

Need help Copying and Editing sheet within the same Spreadsheet in Google Apps Script

I need some help refining this code. It should copy a specific worksheet in this case the sheet Master Copy based on the rows on the sheet Maxes. Then rename the sheet to the name on the given row in the sheet Maxes. When I try to execute the code all it does is insert a blank page and adds it to the end of the Spreadsheet. Please forgive the poorly written code I am really new at this and trying to make something work. Any suggestions that you could give would be gratefully appreciated. I'm not sure if there is an error within the while loops or what exactly.
function createWorkouts(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var nameSource = ss.getSheetByName("Maxes");
var nameColumn = nameSource.getRange("A2:A300");
var nameStartRow = nameSource.getRange("A2");
var trainingSheet = ss.getSheetByName("Master Copy");
var trainingRange = trainingSheet.getRange("a1:m66");
var nameEndRow = nameSource.getLastRow();
var lifterName;
while (nameStartRow <= nameEndRow)
{
lifterName = nameSource.getCell(nameStartRow, nameColumn);
if (lifterName == null)
{
errors.clear();
ss.getSheetsByName(lifterName) = lifterName;
if(errors.number() > 0)
{
errors.clear();
var newSheet = ss.insertSheet();
ss.renameActiveSheet(lifterName);
ss.getSheetByName(lifterName);
trainingRange.copyValuesToRange(lifterName,1,1,16,66);
lifterName.copyValuesToRange(lifterName,4,1,4,1);
}
} nameStartRow = nameStartRow + 1;
}
}
I modifyed your code because I didn't understood what you wanted exactlly, I hope this will do the trick:
function createWorkouts(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var nameSource = ss.getSheetByName("Maxes");
var nameColumn = nameSource.getRange("A2:A").getValues(); // it's a table of table [][]
var trainingSheet = ss.getSheetByName("Master Copy");
var trainingRange = trainingSheet.getRange("A1:M66").getValues(); // get values give a table of table
for(var i in nameColumn){
if(nameColumn[i][0]!=""){ // if blank we skip
try{ // try to see if already exist who know...
var lifter = ss.getSheetByName(nameColumn[i][0]).activate();
Logger.log("getting lifter sheet "+nameColumn[i][0]);
}
catch(err){ // well it didn't exist so lets create it :D
var lifter = ss.insertSheet(nameColumn[i][0]);
Logger.log("creating lifter sheet "+nameColumn[i][0]);
}
SpreadsheetApp.flush();
lifter.getRange("A1:M66").setValues(trainingRange); // passing the value to the created sheet
}
}
}
I also have a demo sheet here.
Please tell me if this is what you wanted (if not can you give a demo sheet of what you want and what you should get at the end)
EDIT
here the script with formulas copy (it's not nice because you are forced to define in the script where your formulas are, we could have the script to analyse the spreadsheet to search the formulas, but, has it's a copy from template, it's less ressource consuming not to do so.)
function createWorkouts(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var nameSource = ss.getSheetByName("Maxes");
var nameColumn = nameSource.getRange("A2:A").getValues(); // it's a table of table [][]
var trainingSheet = ss.getSheetByName("Master Copy");
var trainingRange = trainingSheet.getRange("A1:H21").getValues(); // get values give a table of table
var trainingFormulasD = trainingSheet.getRange("D2:D21").getFormulas(); // get the formulas to copy
var trainingFormulasH = trainingSheet.getRange("H2:H21").getFormulas(); // get others formulas to copy
for(var i in nameColumn){
if(nameColumn[i][0]!=""){ // if blank we skip
try{ // try to see if already exist who know...
var lifter = ss.getSheetByName(nameColumn[i][0]).activate();
Logger.log("getting lifter sheet "+nameColumn[i][0]);
}
catch(err){ // well it didn't exist so lets create it :D
var lifter = ss.insertSheet(nameColumn[i][0]);
Logger.log("creating lifter sheet "+nameColumn[i][0]);
}
SpreadsheetApp.flush();
lifter.getRange("A1:H21").setValues(trainingRange); // passing the value to the created sheet
lifter.getRange("D2:D21").setFormulas(trainingFormulasD); //passing formulas
lifter.getRange("H2:H21").setFormulas(trainingFormulasH); //passing formulas
}
}
}