I'm new to Google App Scripts and JavaScript as I work on the marketing side. I'm currently trying to create a database in Google Sheets to use in DataStudio as I want to blend data from various sources.
I have Google Sheets with a sheet to feed the data (through add-ons) and another sheet which I intend to use as the database. What I'm trying to do is to save data in the database, new data being saved at the end of the spreadsheet each time (I will set a time-based trigger when my script works). I've written a script using Google's documentation but it's only copying the first line of my Data sheet to the database. I would need it to copy all the content from the data sheet to the database sheet.
Here is the script I have for now :
// function to save data
function saveData() {
// starts with active sheet for data entry
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Data");
// collects values in data entry row
var url = sheet.getRange("Data!A1:A").getValues();
var follower_count = sheet.getRange("Data!B1:B").getValues();
var date = sheet.getRange("Data!C1:C").getValues();
// identifies and adds data to Database
var data1 = ss.getSheetByName("Database");
var aVals = data1.getRange("A1:A").getValues();
var aLastRow = aVals.filter(String).length;
Logger.log(aLastRow);
var newAttData = [[url,follower_count,date]];
Logger.log(newAttData);
data1.getRange(aLastRow +1,1,1,3).setValues(newAttData);
}
I've tried to change the range width and length in the last line but I always get an error:
Incorrect range height, was 1 but should be 3 (line 31, file "Code")
I've spent a lot of time on this but I can't get it to work. Any help would be great !
As Described in the documentation:
setValues(values)
Sets a rectangular grid of values (must match dimensions of this range).
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// The size of the two-dimensional array must match the size of the range.
var values = [
[ "2.000", "1,000,000", "$2.99" ]
];
var range = sheet.getRange("B2:D2");
range.setValues(values);
Reference
Related
I am trying to import the User Report in a Google Admin account into Google Sheets. It is straightforward to export to a Google Sheet, but I would like to run a Google script that will pull in the User Report into an existing Google Sheet.
Try this.
function cloneGoogleSheet(existingSheet, userReportSheet){
//get source google sheet document
var source = SpreadsheetApp.openById(userReportSheet);
//get the source sheet on document
var sourceSheet = source.getSheetByName('NameOfSheet');
//get data range
var dataRange = sourceSheet.getDataRange();
// get A1 notation for the range identification
var A1Range = dataRange.getA1Notation();
//get data within the specified range
var data = dataRange.getValues();
//specify the existing spreadsheet you want to pull data to
var target = SpreadsheetApp.openById(existingSheet);
//target sheet on your existing document
var targetSheet = target.getSheetByName('NameOfTargetSheet');
//if there is already data on the target sheet, you may want to remove it
targetSheet.clear({contentsOnly: true});
//now you set the target range of the values you get from your user report
targetSheet.getRange(A1Range).setValues(data);
};
I receive Google Form data from various users on a daily basis, and the data are stored in a Google Spreadsheet. I'm trying to copy the collected data (except the header row) to my target sheet, but more specifically:
Copy and paste the data from Sheet1 to the next row of the data in Sheet2.
Delete the copied data in Sheet1 when copying is completed, so I can make sure I don't overwrite data and keep the sheet clean.
I'm not familiar with coding at all, and this is what I came up with:
function Copy() {
var sss = SpreadsheetApp.openById('sourceid');
var ss = sss.getSheetByName('Sheet1');
var range = ss.getRange('A:H');
var data = range.getValues();
var tss = SpreadsheetApp.openById('sourceid');
var ts = tss.getSheetByName('Sheet2');
ts.getRange(ts.getLastRow()+1, data.length, data[0].length).setValues(data);
}
It gives me an error stating that the number of data row is 1000 whereas the number of the range is 8. I think it's the last line that's causing the problem.
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.
I'm using ImportXML on Google Spreadsheets to scrape YouTube search results and capture the rankings of a video I'm tracking.
=IMPORTXML("https://www.youtube.com/results?search_query=control+theory&page=1"),"//div[#class='yt-lockup-byline']//a")
The scraping works well (and I get all the results for the first page). I then lookup the position of the YouTube results and save that in a cell.
However, the issue I'm having is when I'm trying to track that ranking over-time. Not sure how to do this but I'm looking for a way to run the =ImportXML function every day (is there a refresh command?) and save the result from that cell in a new row each time the function is run.
Any ideas?
importXML output is automatically updated (about every two hours), but you still need a script to save the past values somewhere: usually, on another sheet. Enter the following using Tools > Script Editor, adjusting the sheet names and the cell with the value of interest. Set it to run daily or weekly using Resources > Current project's triggers.
function storeValue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); // where importXML is
var value = sheet.getRange("B3").getValue(); // where the cell of interest is
var sheet2 = ss.getSheetByName('Sheet2'); // where to store the data
var height = sheet2.getLastRow();
sheet2.insertRowAfter(height);
sheet2.getRange(height+1, 1, 1, 2).setValues([[new Date(), value]]);
}
At each run, the script appends two cells at the bottom of Sheet2: one with the timestamp (should be formatted as such), one with the value corresponding to that timestamp.
A version for storing a range of values such as B3:B7:
function storeValue() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var values = sheet.getRange("B3:B7").getValues()[0];
var sheet2 = ss.getSheetByName('Sheet2'); // where to store the data
var height = sheet2.getLastRow();
sheet2.insertRowAfter(height);
sheet2.getRange(height+1, 1, 1, 6).setValues([[new Date()].concat(values)]);
// setting 6 cells instead of 2 on the previous line
}
In Google Spreadsheet I would like to take only the values from a complete list on one spreadsheet and append it to the bottom of a list on another spreadsheet. My trouble is that using the the copyValuesToRange() function errors the following:
Target sheet and source range must be on the same spreadsheet.
Here's my current code:
function transferList() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var target = SpreadsheetApp.openById("0ABCD");
var target_sheet = target.getSheetByName("RFPData");
var sheet = source.getSheetByName("RFP List");
var sheet_last_row = sheet.getLastRow() + 1;
var source_range = sheet.getRange("A2:I"+sheet_last_row);
var sWidth=source_range.getWidth() + 1;
var sHeight=source_range.getHeight() + 1;
var last_row=target_sheet.getLastRow();
source_range.copyValuesToRange(target_sheet , 1, sWidth,
last_row + 1, last_row + sHeight );
}
Any idea how I can get this to work?
As you've found, copyValuesToRange() is a Range method that affects a Sheet Object that is in the same Spreadsheet Object as the Range. There isn't an atomic method that will copy a range of values to another Spreadsheet, but there are a number of ways you could do it.
Here's one way.
From the source sheet, get all the data in one operation, by selecting the complete range of data using getDataRange() and then grabbing all values into a javascript array with getValues().
To ignore the first row of headers, use the javascript array method splice().
Locate your destination, which is on the target sheet, starting after the last row of data that's currently there, using getLastRow().
Write the source data (without the headers) to the destination sheet starting at the next row, using setValues().
Script:
function transferList() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("RFP List");
var sourceData = sourceSheet.getDataRange().getValues();
sourceData.splice(0,1); // Remove header
var targetSS = SpreadsheetApp.openById("0ABCD").getSheetByName("RFPData");
var targetRangeTop = targetSS.getLastRow(); // Get # rows currently in target
targetSS.getRange(targetRangeTop+1,1,sourceData.length,sourceData[0].length).setValues(sourceData);
}
For some historic dashboard I created by importing and appending data, I use an add-on called Sheetgo. Save me programing time and help me with traceability issues.