transferring data from one sheet to another one with script [duplicate] - google-apps-script

sure I had this down but just can't get it right. Had a script set up to get data from one sheet and put it into another one, which I have done but it leaves gaps when copying and I can't figure out how to solve it. I'm sure in the code, its where I have put a question mark, is where the problem lies.
I have tried put i, last, last+1, 10, 12 but none of these work, feel like i'm missing something small to get this right. Below is the code a link to view the sheet if needed (the sheet is just for me to learn from, a basic example if you will).
Thanks in advance and also if the code could be better written, please just let me know as still learning this :)
function copyInfo() {
var app = SpreadsheetApp;
var copySheet = app.getActiveSpreadsheet().getSheetByName("Copy");
for (var i = 2; i <12; i++) {
var getInfo = copySheet.getRange(2,2,i,2).getValues();
// get the info from range above - start at row 2 on column 2 (b), get number of rows i , number of columns = 2, b,c
var last = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Paste").getLastRow();
var pasteSheet = app.getActiveSpreadsheet().getSheetByName("Paste");
// Tell it where you want the info to go to
pasteSheet.getRange(last+1,1,?,2).setValues(getInfo);
var clearIt = copySheet.getRange(2,2,i,2).clearContent();
// this clears the copy range aka getInfo
}}
link to sheet

You can copy whole range at once using copyTo, so your function could be rewritten as:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
// get source range
var source = copySheet.getRange(2,2,12,2);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,2,12,2);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}

Related

Google App Script to paste cell value to another spreadsheet based on column A and column header [duplicate]

sure I had this down but just can't get it right. Had a script set up to get data from one sheet and put it into another one, which I have done but it leaves gaps when copying and I can't figure out how to solve it. I'm sure in the code, its where I have put a question mark, is where the problem lies.
I have tried put i, last, last+1, 10, 12 but none of these work, feel like i'm missing something small to get this right. Below is the code a link to view the sheet if needed (the sheet is just for me to learn from, a basic example if you will).
Thanks in advance and also if the code could be better written, please just let me know as still learning this :)
function copyInfo() {
var app = SpreadsheetApp;
var copySheet = app.getActiveSpreadsheet().getSheetByName("Copy");
for (var i = 2; i <12; i++) {
var getInfo = copySheet.getRange(2,2,i,2).getValues();
// get the info from range above - start at row 2 on column 2 (b), get number of rows i , number of columns = 2, b,c
var last = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Paste").getLastRow();
var pasteSheet = app.getActiveSpreadsheet().getSheetByName("Paste");
// Tell it where you want the info to go to
pasteSheet.getRange(last+1,1,?,2).setValues(getInfo);
var clearIt = copySheet.getRange(2,2,i,2).clearContent();
// this clears the copy range aka getInfo
}}
link to sheet
You can copy whole range at once using copyTo, so your function could be rewritten as:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
// get source range
var source = copySheet.getRange(2,2,12,2);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,2,12,2);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}

How to copy cell value to another sheet base on criteria (Apps Script)

I'm trying to write some Apps Script to pull only the email addresses which match from an array of companies into another sheet for processing. This should also remove the #company.com extension and leave me with just the username.
So on Sheet 1:
In Column E, we have the Company names under Header: "Company"
In Column D, we have the Email Addresses under Header: "Emails"
On Sheet 2:
In Column A, we need the Username result under Header: "Username"
Currently the below script which should have 2 results, comes back with:
this
Any help with this would be immensely appreciated as I'm losing my mind.
Thank you!
function pullUsernames() {
//Get Sheet1
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
//Set Values for Search
var valuesToWatch = ['Company1','Company2'];
var range = sheet.getRange(2,5,sheet.getLastRow()-1).getValues();
var emails = sheet.getRange(2,4,lr-1).getValues();
//For Loop to match values, etc.
for(var i=0; i < range.length; i++){
if(valuesToWatch.indexOf(range[i][0])){;
var targetSS = SpreadsheetApp.openById("1hpIIgkXMgrlOfYqfS4A3ro8BFQB02dAy5G40Y7vUI2c").getSheetByName("Sheet2");
var targetRange = targetSS.getRange(i+1,1,targetSS.getLastRow(),1);
var usernames = String(emails[i][0]).replace("#company.com", "")
targetRange.setValue(usernames[i][0]);
} //if
} //for
} //Function
There were a bunch of issues in your code and I decided to optimize them. Feel free to modify the code if needed.
Issues:
Both range and emails can be fetched together instead of separate
Brought targetSS outside the loop since it is only static based on your issue
I don't quite get your getRange, I assume you want to append the usernames on the last row? If so, then use appendRow instead.
Since I didn't use the array index now, I used includes instead to check if the data is in valuesToWatch.
Your email string manipulation is quite hard coded so I replaced it with a better solution, removing anything but the characters before #.
Code:
function pullUsernames() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
// update your targetSS, made it under same ss for easier testing
var targetSS = ss.getSheetByName("Sheet2");
// set values for search
var valuesToWatch = ['Company1', 'Company2'];
// get email and company columns in one go
var data = sheet.getRange(2, 4, sheet.getLastRow() - 1, 2).getValues();
// each row of data contains email and company formatted as [email, company].
data.forEach(function ([email, company]){
if(valuesToWatch.includes(company))
// remove anything from # onwards from email and append at last row
targetSS.appendRow([email.substring(0, email.lastIndexOf("#"))]);
});
}
Sample Data:
Sample Output:

Google Script how to back up new rows to a master spreadsheet

So the gist of my project is to copy new data added to spreadsheet A to spreadsheet B. The intention is to use spreadsheet A as an input method and spreadsheet B as a log of all data input into A from all of time. A master sheet so to speak. Note that this will be run on a time-based trigger and all data from sheet a will be deleted.
I've taken some code from Stackoverflow (thank you to who made it) and made some changes. I'm able to copy over the first set of data from A to B but when I delete the data from A, add new data and run the code I lose all I've input in B. I may as well have use =importrange.
My solution was logical and to take the getLastRow of B and put this before setting setValues. Theoretically, this should get the last row of B and input the new data from A into the last row of B. Easy right, NO, I've been trying to figure this out for days and many hours reading similar cases but I'm not able to get past this hurdle.
I'm speculating that I've misunderstood something in my variable SRange, A1Range or SData.
Any help would be super helpful.
function CopyDataToNewSheet() {
var sss = SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXXXX');
var ss = sss.getSheetByName('Sheet1');
var lr = ss.getLastRow();
var lc = ss.getLastColumn();
var SRange = ss.getRange(2,1,lr,lc);
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var tss = SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXXXX');
var ts = tss.getSheetByName('Sheet1');
var tlr = ts.getLastRow()+1;
Logger.log(tlr);
tlr.getRange(A1Range).setValues(SData);
}
function CopyDataToNewSheet() {
var ss=SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXXXX');
var sh=ss.getSheetByName('Sheet1');
var srg=sh.getRange(2,1,sh.getLastRow()-1,sh.getLastColumn());
var dA=srg.getValues();
var tss=SpreadsheetApp.openById('XXXXXXXXXXXXXXXXXXXXX');
var tsh=tss.getSheetByName('Sheet1');
tsh.getRange(tsh.getLastRow()+1,1,dA.length,dA[0].length).setValues(dA);
}

Improving Apps Script flexibility by using a column of sheet data instead of hard-coded IDs

Background: My coworkers originally each had a worksheet within the same Google Sheets file that makes a lot of calculations (and was getting unusable). Now, everyone has their own (known) Google Sheets file. To run the same calculations, we need to consolidate all that data into a master sheet (image ref below). We tried =importrange(...), but it's too heavy and breaks often (i.e., Loading... and other unfilled cells).
I've written some code to do this import, but right now its only manual: manually repeating the code and manually add the sheet IDs and changing the destrange.getRange(Cell range) each time. We have 80+ analysts, and fairly high turnover rates, so this would take an absurd amount of time. I'm new to Sheets and Apps Script, and know how to make the script use a cell as reference for a valid range or a valid ID, but I need something that can move a cell down and reference the new info.
Example:
Sheet 1 has a column of everyone Sheet ID
Script Pseudocode
get first row's id(Row 1), get sheet tab, get range, copies to active sheet's corresponding row(Row 1).
gets second row's id(Row 2), get sheet tab, get range, copies to active sheet's corresponding row (Row 2)
etc.
My script understanding is way to low to know how to process this. I have no idea what to read and learn to make it work properly.
function getdata() {
var confirm = Browser.msgBox('Preparing to draw data','Draw the data like your french girls?', Browser.Buttons.YES_NO);
if(confirm == 'yes'){
// I eventually want this to draw the ID from Column A:A, not hard-coded
var sourcess = SpreadsheetApp.openById('1B9sA5J-Jx0kBLuzP5vZ3LZcSw4CN9sS6A_mSbR9b26g');
var sourcesheet = sourcess.getSheetByName('Data Draw'); // source sheet name
var sourcerange = sourcesheet.getRange('E4:DU4'); // range
var sourcevalues = sourcerange.getValues();
var ss = SpreadsheetApp.getActiveSpreadsheet(); //
var destsheet = ss.getSheetByName('Master Totals'); //
// This range needs to somehow move one down after each time it pastes a row in.
var destrange = destsheet.getRange('E4:DU4');
destrange.setValues(sourcevalues); // Data into destsheet
}
}
Any suggestions are greatly appreciated!
Thanks to tehhowch for pointing me in the right direction!
function getdata() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var destsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Master Totals');
var confirm = Browser.msgBox('Drawing Data','Would you like to update the sheet? It may take 2 to 5 minutes.', Browser.Buttons.YES_NO);
if(confirm =='yes'){
var lr = ss.getLastRow();
for (var i = 4; i<=lr; i++) {
var currentID = ss.getRange(i, 1).getValue();
var sourcess = SpreadsheetApp.openByUrl(currentID);
var sourcesheet = sourcess.getSheetByName('Data Draw');
var sourcerange = sourcesheet.getRange('E4:DU4');
var sourcevalues = sourcerange.getValues();
var destrange = destsheet.getRange('E' +i+':'+ 'DU'+ i);
destrange.setValues(sourcevalues);
I just had to learn how to use a variable loop.
Edit: thanks also to Phil for making my question more presentable!
Now that you've figured out one way to do it, I'll offer an alternative that uses batch methods (i.e. is much more time- and resource-efficient):
function getData() {
var wb = SpreadsheetApp.getActive();
var ss = wb.getActiveSheet();
var dest = wb.getSheetByName('Master Totals');
if (!dest || "yes" !== Browser.msgBox('Drawing Data', 'Would you like to update the sheet? It may take 2 to 5 minutes.', Browser.Buttons.YES_NO))
return;
// Batch-read the first column into an array of arrays of values.
var ssids = ss.getSheetValues(4, 1, ss.getLastRow() - 4, 1);
var output = [];
for (var row = 0; row < ssids.length; ++row) {
var targetID = ssids[row][0];
// Open the remote sheet (consider using try-catch
// and adding error handling).
var remote = SpreadsheetApp.openById(targetID);
var source = remote.getSheetByName("Data Draw");
var toImport = source.getRange("E4:DU4").getValues();
// Add this 2D array to the end of our 2D output.
output = [].concat(output, toImport);
}
// Write collected data, if any, anchored from E4.
if(output.length > 0 && output[0].length > 0)
dest.getRange(4, 5, output.length, output[0].length).setValues(output);
}
Each call to getRange and setValues adds measurable time to the execution time - i.e. on the order of hundreds of milliseconds. Minimizing use of the Google interface classes and sticking to JavaScript wherever possible will dramatically improve your scripts' responsiveness.

Copy a row with specific cells to another spreadsheet

I have been searching for a way to copy certain cells from a row and paste them into another spreadsheet, but all I can seem to find are ways to do that just from sheet to sheet within one spreadsheet or questions that deal with code way above my head. I'm just now learning to code in Google Spreadsheets and I can't seem to get it right. Here is my code for now, I'm working on just copying one cell first and after I can do that I'll get a loop to iterate through the row and pick the cells I want to copy.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var master = SpreadsheetApp.openById('0AgcCWQn-aoI1dFpLVE4tSENwcThrYnlMUzhuRmdWU2c');
var target = SpreadsheetApp.openById('0AgcCWQn-aoI1dF96X2dBT2dVVFZ2SU1NRWdYTDJhT2c');
var master_sheet = master.getSheetByName("Steve2");
var target_sheet = target.getSheetByName("Corbin1");
var master_range = master_sheet.getRange("A1");
var target_range = target_sheet.getRange("A1");
master_range.copyTo(target_range);
Right now it is giving me an error saying that it cannot call the getRange method of null. I'm not sure if I'm using OpenById correctly or if I can even use that in this situation.
OK I've got it working now. It copies the row perfectly and it copies only the cells I want. Now I need help with the pasting part. It copies everything fine and puts it into the other sheet great, but I need it to copy into the next available row and into the first available columns. So if row 5 is the last column of data, I need it to paste into row 6 and take up the first 6 or so columns.
This is what I have so far.
function menuItem1() {
var sss = SpreadsheetApp.openById('0AgcCWQn-aoI1dFpLVE4tSENwcThrYnlMUzhuRmdWU2c'); // sss = source spreadsheet Steve2
var ss = sss.getSheetByName('Sheet1'); // ss = source sheet
//Message box asking user to specify the row to be copied
var answer = Browser.inputBox('What row would you like to copy?');
var range = parseInt(answer);
var array = [1,2,3,9,12,30];
//Runs a loop to iterate through array, using array elements as column numbers
for(var i = 0; i < array.length; i++){
var SRange = ss.getRange(answer,1,1,array[i]);
//get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
//get the data values in range
var SData = SRange.getValues();
}
var tss = SpreadsheetApp.openById('0AgcCWQn-aoI1dF96X2dBT2dVVFZ2SU1NRWdYTDJhT2c'); // tss = target spreadsheet Corbin1
var ts = tss.getSheetByName('Sheet1'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
//Confirmation message that the row was copied
Browser.msgBox('You have successfully copied Row: ' + answer);
}
You are getting this error maybe because your spreadsheet does not have a sheet called Steve2 or Cobin1. Try using the method master.getSheets()[0], this way you will get the first sheet without using their name.
You can algo use this piece of code to check the sheets names:
for(var x in master.getSheets()) {
Logger.log(master.getSheets()[x].getSheetName());
}
best,