Google Spreadsheet Script - How to split an Object[][] from .getValues? - google-apps-script

I want to importxml from more than 50 sites in Google Documents and fill that information into another sheet and preferably overwrite the data already there preventing a clear function. The problem I'm running into however is I'm getting
={229999999.99;0;0;183000000;169999999.99;209999999.99}
in one cell. How do I split this to be six numbers in different columns but the same row?
This is my code:
function Xml() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var s = sheet.getSheetByName('Script');
var ss = sheet.getSheetByName('TradeIBuy');
var Num = Browser.inputBox("How many URLs to scrape");
for (y=0;y<2;y++) {
for (x=2;x-2 < Num;x++) {
//ss.getRange("b4:n400").setValue(""); //Too slow for spreadsheet
var url = s.getRange(x,1).getValue(); //Grab URL
s.getRange(2,6).setValue(url); //Move URL into position
var xpathResult = s.getRange("F3:F8").getValues(); //Grab results from first sheet
if (y===1){
var export = ss.getRange(x+2,2); //Export position
export.setValue(xpathResult); //Export data to second sheet
SpreadsheetApp.flush();
}
}
}
}
function clear() {
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("a2:b1000").setValue("");
}
Thanks ~ Chandler

If I understand your question properly, I think there's a solution without scripting.
=SPLIT(SUBSTITUTE(SUBSTITUTE(ImportXML(blah,blah),"}",""),"{",""),";")
...will change {229999999.99;0;0;183000000;169999999.99;209999999.99} to:
229999999.99 0 0 183000000 169999999.99 209999999.99
... with each number in its own cell.
SPLIT breaks a string at the given delimiter character, which is ; in this case.
SUBSTITUTE is being used to strip the braces.

Related

Google App Script Function: Return Drive Filename from File URL

I've searched extensively for an answer to this, but have not had much luck. I think it should be a fairly simple answer. Here's what I'm trying to do:
I have a list of (other) Google Sheets document URLs in a Google Sheet.
I'd like to have a simple function that loads the URL in each line and returns the file name.
To illustrate, if the URLs are in A2:A10, a user could input a custom function like =GetFileName(A2) and it would return the file name corresponding to the Google Sheet URL that is in A2.
Here's the code that I have thus far, but it's returning an error, " TypeError: SpreadsheetApp.openByURL is not a function (line 3)."
function getFileName(fileURL) {
var GetFile = SpreadsheetApp.openByURL(fileURL);
var GetName = GetFile.getName();
return GetName;
}
UPDATE *************
Here's the code that worked for me. Basically, it loops through the sheet with IDs to pull file names. Not the most efficient, but works for relatively short lists just fine.
function getFileName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// DocumentIDs are listed in the 'tool' sheet
var targetSheet = ss.getSheetByName("tool");
// Find the last row
var LastRow = targetSheet.getLastRow();
//Loop Begins
//Initializing variable assumes that the first valid Drive ID is in the 3rd row.
for(var i = 3; i < LastRow; i++) {
// Get the Document ID. This gets the Document ID
var LookupID = targetSheet.getRange(i,1).getValue();
// Get the Filename
var FileOpen = SpreadsheetApp.open(DriveApp.getFileById(LookupID));
var FileName = FileOpen.getName();
// Write the FileName in the second column
targetSheet.getRange(i,2).setValue(FileName);
Logger.log(i);
Logger.log(LookupID);
Logger.log(FileName);
}
}
Suggestion:
You can try this script together with using clickable image to act as a button for the function to run the script below:
function convertURLtoSheetName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cell = ss.getActiveCell().getValue();
var getSheetName = SpreadsheetApp.openByUrl(cell).getName();
var seturl = SpreadsheetApp.newRichTextValue().setText(getSheetName).setLinkUrl(cell).build();
ss.getActiveCell().setRichTextValue(seturl);
}
Here is how you assign a script function to an image:
Custom Functions Cannot open other spreadsheets (SpreadsheetApp.openById() or SpreadsheetApp.openByUrl()).
reference

Apps script copy multiple range from 1 sheet to another spreadsheet

I am trying to copy data from 1 spreadsheet to another, I have successfully implemented something i found online that works with a specific range
function cloneGoogleSheet() {
// source doc
var sss = SpreadsheetApp.openById("spreadsheetkey1");
// source sheet
var ss = sss.getSheetByName('_tab_name_source');
// Get full range of data
var SRange = ss.getRange(7,3,5,1);
// get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
// get the data values in range
var SData = SRange.getValues();
// target spreadsheet
var tss = SpreadsheetApp.openById("spreadsheetkey2");
// target sheet
var ts = tss.getSheetByName('tab_name_destination');
// Clear the Google Sheet before copy
//ts.clear({contentsOnly: true});
// set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
};
The above piece coding work perfectly however I need to copy 18 different ranges that i cant just merge into 1 range. I considered the option of using the above however "multiplying" it 18 times for each range that however seems like a very inelegant solution.
I found a working solution that works if it stays within the same spreadsheet since it uses copyto instead of get/set values. The values part works perfectly since it doesnt mess with merge cells formatting. I have been struggling past 2-3 hours in merging the below-working code with elements from the first code to make a working script.
function test () {
try {
var spread = SpreadsheetApp.openById("spreadsheetkey");
var sheet = spread.getSheetByName("tab_name_source");
var rlist = sheet.getRangeList(["c7:c11", "g7:g11", "k7:k11"]);
sheet = spread.getSheetByName("tab_name_destination");
for( var i=0; i<rlist.getRanges().length; i++ ) {
var r1 = rlist.getRanges()[i];
var r2 = sheet.getRange(r1.getA1Notation());
r1.copyto(r2);
}
}
catch(err) {
Logger.log(err);
}
}
I tried initially to adapt the 2nd piece of coding to using setvalues however i had not been able to succesfully implement the part of getvalues within the scope of this code. I figured once I got this piece of code working with get and set values instead of Copyto i would only need to add the spreadsheetid of the other spreadsheet to get the final result
Try this:
function myFunction() {
var sourceSS = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = sourceSS.getSheetByName("sheetname");
var targetSS = SpreadsheetApp.openById("spreadsheet id here");
var targetSheet = targetSS.getSheetByName("Sheet1");
var ranges = ["C7:C11", "G7:G11", "K7:K11"];
ranges.forEach(range => {
var data = sourceSheet.getRange(range).getValues();
targetSheet.getRange(range).setValues(data);
})
}
Source sheet:
Destination sheet:
References:
setValues()
getValues()

Can you find and replace URL's in a formula with Google Apps Script?

I am creating a summary sheet for teachers to pull in all their student's data. Each column is a different student and has a different URL for the student's file. I have over 50 teachers and 850+ students. I am trying to find a way using google apps script to find and replace the URLs in a column. I have this code so far, and I can see the 'baseLink' and the 'replaceLink' in the log, but I cannot figure out what to do to get them to replace. I'm attaching a snapshot of the spreadsheet I'm using in case that helps explain my issue better. You can see I use the importrange formula to pull in the URLs and those are what need to be changed. I do need to read through all the columns, but I'm happy just learning how to do one column first. Thanks for any help!
This is the code I have, with a line of pseudo code where I need help:
function UpdateColumnLinks() {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getRange('G1:G76');
var baseLink = ss.getRange('R2').getValue(); //This is the URL of a spreadsheet I want to replace that is in the formula
var replaceLink = ss.getRange('S10').getValue(); //This is the URL of a spreadsheet I want to see in the formula
Logger.log(baseLink)
Logger.log(replaceLink)
for i = 0; i<range.length; i++ {
pseudo code: find baseLink in range and replace with replaceLink
}
}
Replacing Links in a Spreadsheet
Rich Text Links:
function UpdateColumnLinks() {
var sh=SpreadsheetApp.getActiveSheet();
var rg=sh.getRange(1,3,sh.getLastRow(),1);
var dvs=rg.getRichTextValues();
var rl=sh.getRange(1,1).getRichTextValue().getLinkUrl();replacement link
var ls=SpreadsheetApp.newRichTextValue().setText(rl).build();
for(var i=0;i<dvs.length;i++) {
var link=dvs[i][0]=ls;
}
rg.setRichTextValues(dvs);
}
RichTextValueBuilder
Class RichTextValue
Formula Links:
function UpdateColumnLinks1() {
const sh=SpreadsheetApp.getActiveSheet();
const rl=sh.getRange(1,1).getFormula();
const rg=sh.getRange(1,3,sh.getLastRow(),1);
var vs=rg.getFormulas();
vs.forEach(function(r,i){
r[0]=rl;
});
rg.setFormulas(vs);
}
Your specific case:
function UpdateColumnLinks() {
var ss=SpreadsheetApp.getActiveSheet();
var rg=ss.getRange('G1:G76);
var fA=rg.getFormulas();
var rl=ss.getRange('S10').getFormula();
fA.forEach(function(r){r[0]=rl;});
rg.setFormulas(fA);
}

Script to copy data between sheets

I'm trying to create a script to copy data from sheet 1 to sheet 2 and at the same time reorder it. I get my data from a Google form, so data is constantly updating.
Here are two images as examples. N°1 is how I have my data, N°2 is how I want it to be in sheet 2.
The idea is to have the script copying the data every time a new row appears.
Data from Forms.
This is how I would like it to be.
This is my initial code:
function copyrange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Ingreso'); //source sheet
var testrange = sheet.getRange('J:J');
var testvalue = (testrange.getValues());
var csh = ss.getSheetByName('Auxiliar Ingreso'); //destination sheet
var data = [];
var columnasfijas = [];
var cadena = [];
//Condition check in G:G; If true copy the same row to data array
for (i=1; i<testvalue.length;i++) {
data.push.apply(data,sheet.getRange(i+1,1,1,9).getValues());
if ( testvalue[i] == 'Si') {
data = (sheet.getRange(i+1,1,1,9).getValues()).concat (sheet.getRange(i+1,11,1,9).getValues()); // this beaks up into 2 rows Idon't know why
/*cadena = (columnasfijas);
data.push.apply(data, columnasfijas);*/
}
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
//Copy data array to destination sheet
//csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
}
In this line, I'm also having trouble concatenating different lengths of data. It should be: (i+1,1,1,6). concat.....(i+1,11,1,3)
data = (sheet.getRange(i+1,1,1,9).getValues()).concat (sheet.getRange(i+1,11,1,9).getValues()); // this beaks up into 2 rows Idon't know why
When I run it as it should by I receive an error that the length should be 9 instead of 3.
This can be accomplished more simply using formulas instead of app scripts:
=sort(importrange("spreadsheetURL", "Sheet1!A2:AA10000"),sort_col#,TRUE/FALSE,[sort_col2#],[TRUE/FALSE]...)
Documentation on importrange function: https://support.google.com/docs/answer/3093340
Documentation on sort function: https://support.google.com/docs/answer/3093150
Once you input the formula, there will likely red triangle on the cell, be sure to click on the cell and click the Allow Access button to give one spreadsheet access to the other.

Unmerge in Google Apps Script

I'd like to unmerge all the cells of my google spreadsheet using script. I believe that VBA has this option (cells.unmerge) but I can't find a similar operation in GAS. I've tried this script but it didn't seem to work.
function MyFunction() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var Range = Sheet.getDataRange().activate();
Range.clearFormat();
}
The correct word is "Range.breakApart" not "unmerge". Note that this only works when the range it is called on encompasses all merged cells.
Try this code:
function unmerge() {
var app = SpreadsheetApp;
// get current active sheet use single line coding
var activeSheet =app.getActiveSpreadsheet().getActiveSheet();
// get last row
var lstrow= activeSheet.getLastRow();
// see below description **
var mergerange = activeSheet.getRange(13,4,lstrow).getMergedRanges();
for (var i = 0; i < mergerange.length; i++) {
Logger.log(mergerange[i].getA1Notation());
Logger.log(mergerange[i].getDisplayValue());
mergerange[i].breakApart();
}
}
** 13= start row number. 4 = column number of merge cells.