Copy Entire Row To Another Sheet Except Column C - google-apps-script

I'm using Google Sheets and I have this code below to copy the last row (via Form On Submit trigger) onto another sheet (not tab). I'm not sure how to copy over the last row and skip the data in Column C. It's currently copying the entire row to another sheet successfully, fyi. Any help would be appreciated, thank you!
function CopyToAnotherSheet() {
// Delaying this script so that there is enough time to get the Google Doc URL before it starts to fill out the template file
Utilities.sleep(10000); // 10 second delay
// Get Source Spreadsheet
var source = SpreadsheetApp.getActiveSpreadsheet();
// Get Source Sheet from Spreadsheet
var source_sheet = source.getActiveSheet();
// Get Last Row
var lastRow = source_sheet.getLastRow();
// Get Last Column
var lastColumn = source_sheet.getLastColumn();
// Get Last Row of Data
var lastRowOfData = source_sheet.getRange(lastRow, 1, 1, lastColumn).getValues();
// Creates a one dimensional array
var oneD_array = lastRowOfData.join().split(",");
// Get the Value of the Manufacturer Cell
var cellValue = source_sheet.getRange(lastRow,3).getValues();
// Copy Last Row to First Sheet
if ( cellValue == "First" ) {
var target = SpreadsheetApp.openById("xxxyyyzzz");
var target_sheet = target.getSheetByName("First");
target_sheet.appendRow(oneD_array);
}
// Copy Last Row to Second Sheet
if ( cellValue == "Second" ) {
var target = SpreadsheetApp.openById("aabbcc");
var target_sheet = target.getSheetByName("Second");
target_sheet.appendRow(oneD_array);
}
}

One option you can do is to remove column C value in your 1-d array. Instead of skipping it.
Sample code:
var lastRowOfData = source_sheet.getRange(lastRow, 1, 1, lastColumn).getValues().flat();
Logger.log("Before removal: "+lastRowOfData)
// Remove index 2 (Column C value) in the array
lastRowOfData.splice(2,1)
Logger.log("After removal: "+lastRowOfData)
What it does?
Using array.flat(), change 2-d array to 1-d array
Using array.splice(), remove an element in the array
Output:
Execution log
5:10:50 AM Notice Execution started
5:10:51 AM Info Before removal: a,b,c,d,e
5:10:51 AM Info After removal: a,b,d,e
5:10:52 AM Notice Execution completed
Note:
I removed the oneD_array variable in the sample code. If you really want a separate variable for your 1-d array you can use this one:
var oneD_array = lastRowOfData.flat();
oneD_array.splice(2,1);

Related

How to separate column into two separate columns by condition App Script

I am trying to take the Data in the scan it columns and conditionally filter it into the commercial or manufacturing sheet.
I tried writing a formula as an if function basically saying if it equals "Company" put it in manufacturing column, if not(if the rest) then put into commercial column.
I tried coding it backend in app script, but had an issue grabbing the last row from scan it and correctly adding the item #, vendor, and quantity into the last row of either Commercial or Manufactured.
The scan it section is an importrange function so more data will be entered into it once the code is working correctly.
I ran into dead ends with both. This is obviously an advanced code and I only did a little bit of coding in college. Below is a script that I had been messing with trying to get it to filter the data properly, but I couldn't get it to run. Any help would be appreciated!
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1')
//Get last rows for MFG
var mfgvalues = sheet.getRange(3, 5, sheet.getLastRow()).getValues();
//var mfglast = mfgvalues.filter(String).length;
//Get last rows for Comm
var commvalues = sheet.getRange(3, 1, sheet.getLastRow()).getValues();
//var commlast = commvalues.filter(String).length;
//Get last rows for Scann
var scanvalues = sheet.getRange(2, 12, sheet.getLastRow()).getValues();
//var scanlast = scanvalues.filter(String).length;
//Filter Accordingly
if (scanvalues == "IMMCO") {
var scanrange = sheet.getRange("L2:N").getLastRow().getValues();
//var scanlastrow = scanrange.getLastRow().getValues();
var mfgrow = sheet.getRange("E3:G").getLastRow();
scanlastrow.copyTo(mfgrow)
} else {
var scanrange = sheet.getRange("L:N").getLastRow.getValues();
//var scanlastrow = scanrange.getLastRow().getValues();
var commrow = sheets.getRange("A3:C").getLastrow()
scanlastrow.copyTo(commrow)
}
}
https://docs.google.com/spreadsheets/d/1D0FvVoTADi3t3ENPceB14QYYI4lNI6C3xj2OF-St7Is/edit?usp=sharing
GOOGLE SHEET OUTPUT WANTED
Option1:
Using FILTER() to filter your data set if vendor name is equal to "COMPANY" as mentioned in your description
Formula in Cell A3:
=filter(L3:N,LEN(L3:L)>0,UPPER(M3:M)<>"COMPANY")
Formula in Cell E3:
=filter(L3:N,LEN(L3:L)>0,UPPER(M3:M)="COMPANY")
Output:
Option2:
Using apps script to filter your data set.
Sample Code:
function filter(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
//Get item count for Scann
var scanCnt = sheet.getRange('L3:L').getValues().flat().filter(String).length;
Logger.log(scanCnt);
//Get last rows for Comm
var commLastRow = sheet.getRange('A1:A').getValues().flat().filter(String).length;
Logger.log(commLastRow);
//Get last rows for MFG
var mfgLastRow = sheet.getRange('E1:E').getValues().flat().filter(String).length;
Logger.log(mfgLastRow);
//Get Scann data if item count is not zero
if(scanCnt){
var commItem = [];
var mfgItem = [];
var dataRange = sheet.getRange(3,12,scanCnt,3);
var data = dataRange.getDisplayValues();
//Loop all scann data and separate mfg with comm
Logger.log(data.length)
data.forEach(item => {
Logger.log(item);
if(item[1].toUpperCase() == "COMPANY"){
mfgItem.push(item);
}else{
commItem.push(item);
}
});
Logger.log(mfgItem);
Logger.log(commItem);
//Append comm items
sheet.getRange(commLastRow+1,1,commItem.length,commItem[0].length).setValues(commItem);
//Append mfg items
sheet.getRange(mfgLastRow+1,5,mfgItem.length,mfgItem[0].length).setValues(mfgItem);
//Optional: Clear content of scann column
dataRange.clearContent();
}
}
What it does?
Get the item count to filter in Scan it column by selecting the range L3:L. Get its value. Change 2-d array to 1-d array using array.flat(). Use array.filter() to remove empty values. Then get its length
Get the last row of Commercial(ColumnA) and Manufactured(ColumnE) column.
If item count obtained in step1 is not zero. Then get the data range and its value
Loop all data value (by row) one-by-one. Check if vendor index is equal to "COMPANY" then add it to mfgItem array. Else, add it to commItem array
Append mfgItem and commItem under Manufactured Column and Commercial Column
(Optional) Clear the data under Scan-it Column
Note:
You can check the execution log to further understand the procedure done. I included some debug logs in the sample code.
Output:

Script to copy from one sheet to another, needs edit

I have this script which is working well, but i need to edit it to
a) only return new rows since last run
b) only return certain cells instead of whole row
any guidance would be greatly appreciated
function Copy() {
var sourceSheet = SpreadsheetApp.openById('1WAtRDYhfVXcBKQoUxfTJORXwAqYvVG2Khl4GuJEYSIs')
.getSheetByName('Jobs Log');
var range = sourceSheet.getRange(1, 1, sourceSheet.getLastRow(), sourceSheet.getLastColumn());
var arr = [];
var rangeval = range.getValues()
.forEach(function (r, i, v) {
if (r[1] == 'Amber') arr.push(v[i]);
});
var destinationSheet = SpreadsheetApp.openById('137xdyV8LEh6GAhAwSx4GmRGusnjsHQ0VGlWbsDLXf2c')
.getSheetByName('Sheet1');
destinationSheet.getRange(destinationSheet.getLastRow() + 1, 1, arr.length, arr[0].length)
.setValues(arr);
}
In order to only check new data added after last runtime we have to store .getLastRow() value in properties and retrieve it every runtime. We would also have to work under a few assumptions:
In the input data new values are only appended at the bottom and never inserted between other data
Data is never deleted from the input sheet (if you ignore this, then you must also have an update script for the last row that runs after deleting data)
The sheet is not sorted after new data is added but before this script is run.
So you would need something along the lines of
var sourceSheet = SpreadsheetApp.openById('1WAtRDYhfVXcBKQoUxfTJORXwAqYvVG2Khl4GuJEYSIs')
.getSheetByName('Jobs Log');
var lastRow = sourceSheet.getLastRow();
// note that you need to hav the script property initialized and stored
// or adjust the if to also check if prevLastRow gets a value
var prevLastRow = PropertiesService.getScriptProperties().getProperty('lastRow')
if (lastRow <= prevLastRow) {
return; // we simply stop the execution right here if we don't have more data
}
// then we simply start the range from the previous last row
// and take the amount of rows added afterwards
var range = sourceSheet.getRange(prevLastRow,
1,
lastRow - prevLastRow,
sourceSheet.getLastColumn()
);
As for the second question, inside the forEach you need to simply push an array into arr that will contain only the columns you want. So for example
if (r[1] == 'Amber') arr.push(v[i]);
changes into
if (r[1] == 'Amber') arr.push([v[i][0], v[i][3], v[i][2]]);
which will output A D C columns (in that order) for each row.
Finally, the last thing you need to run before the script ends is
PropertiesService.getScriptProperties().setProperty('lastRow', lastRow)
which will let us know where we stopped the next time we run the script. Again, keep in mind that this works only if new data will always be in new rows. Otherwise, you need to do a different method and retrieve 2 arrays of data. 1 for the entire input sheet and 1 for the output sheet. Then you would have to perform 2 if checks. First one to see if your criteria are met and a second one to see if it already exists in the output data.

Copy a row to new sheet based on value in a cell

I'm trying to create a Google Script that copies rows from one Google Sheet into different sheets based on the value of a cell.
The cell value are states in the United States. The master spreadsheet has data from a registration form that is being imported into it all the time. When a new registration happens (and the data is imported into the master sheet), I'd like the script to run and copy that row of data into the appropriate state sheet.
Here's where I'm at:
Get master sheet
Find the last row
Get the value of the cell in the column "state"
Copy that row into one of 50 different sheets depending on what state it is.
Run the script every time the master sheet is updated (via an API).
Any help would be appreciated. I'm definitely a newbie when it comes to scripting and this is just hurting my head.
Here's the code I have so far:
function myFunction() {
// Get Source Spreadsheet
var source = SpreadsheetApp.getActiveSpreadsheet();
// Get Source Sheet from Spreadsheet
var source_sheet = source.getActiveSheet();
// Get Active Range from Sheet
var lastRow = sheet.getLastRow();
// Get the Value of the State Cell
var cellValue = Range.getCell(lastrow,3);
// Copy Last Row to Appropriate State Sheet
if ( cellValue == 'Alaska') {
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
target_sheet.appendRow(lastRow);
}
}
With this code:
// Get Active Range from Sheet
var lastRow = sheet.getLastRow();
The getLastRow() method returns an integer. Then further down in your code, you are using the lastRow variable as the data for appendrow() which won't work;
target_sheet.appendRow(lastRow);
The code should probably be something like this:
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
var lastRowOfData = source_sheet
.getRange(source_sheet.getLastRow(), 1, 1, source_sheet.getLastColumn())
.getValues(); //Returns a two dimensional array
var oneD_Array = lastRowOfData.join().split(","); //Creates a one D array
target_sheet.appendRow(oneD_Array);
The appendRow() method takes a one dimensional array. The getValues() method returns a 2 Dimensional array, so it must be converted. Because you are only getting one row of data, it's easy to convert. The outer array only has one inner array. The one inner array has all the cell values of the row.
Here's the answer for what I came up with for the code:
function myFunction() {
// Get Source Spreadsheet
var source = SpreadsheetApp.getActiveSpreadsheet();
// Get Source Sheet from Spreadsheet
var source_sheet = source.getActiveSheet();
// Get Last Row
var lastRow = source_sheet.getLastRow();
// Get Last Column
var lastColumn = source_sheet.getLastColumn();
// Get Last Row of Data
var lastRowOfData = source_sheet.getRange(lastRow, 1, 1, lastColumn).getValues();
// Creates a one dimensional array
var oneD_array = lastRowOfData.join().split(",");
// Get the Value of the State Cell
var cellValue = source_sheet.getRange(2,7).getValue();
// Copy Last Row to Appropriate State Sheet
if ( cellValue == "New York" ) {
var target = SpreadsheetApp.openById("");
var target_sheet = target.getSheetByName("Sheet1");
target_sheet.appendRow(oneD_array);
}
}

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,

I need to copy data from 3 sheets to another master sheet in same spreadsheet

I have written a code for this but getting an error
The coordinates or dimensions of the range are invalid. (line 44)
Code:
function updateMaster() {
var repArray = new Array();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var allSheets = ss.getSheets();
// build array of all sheets
for (i in allSheets) {
if ((allSheets[i].getName()).match(/.*?\-Rep$/))
{repArray.push(allSheets[i].getName());}
}
// store all sheets in array
var sheetArray = [];
// loop through all rep sheets
for (var j in repArray) {
// get each sheet
var tempSheet = ss.getSheetByName(repArray[j]);
// get sheet data
var dataRange = tempSheet.getDataRange().getValues();
// remove the first header row
dataRange.splice(parseInt(0), 1);
// append sheet data to array
var sheetArray = sheetArray.concat(dataRange);
}
// Time to update the master sheet
var mSheet = ss.getSheetByName("summary");
// save top header row
var headerRow = mSheet.getRange(1,1,1,12).getValues();
// clear the whole sheet
mSheet.clear({contentsOnly:true});
// put back the header row
mSheet.getRange(1, 1, 1, 12).setValues(headerRow);
This is where i am getting error while writing to master sheet:
// write to the Master sheet via the array
mSheet.getRange(2, 1, sheetArray.length, 12).setValues(sheetArray);
// force spreadsheet updates
SpreadsheetApp.flush();
// pause (1,000 milliseconds = 1 second)
Utilities.sleep("200");
// delete empty rows at bottom
var last = mSheet.getLastRow();
var max = mSheet.getMaxRows();
if (last !== max) {mSheet.deleteRows(last+1,max-last);}
}
I am not able to figure out the error.
You need a sheet with "Rep" inside the name.
"The first array stores all the Sales Rep sheets. Since some sheets could be something other than Sales Rep sheets, the script stores sheets only if the sheet name has a “-Rep” suffix (e.g. “JohnDoe-Rep”)"
code source: http://blog.ditoweb.com/2012/01/consolidate-spreadsheet-sheets-with.html
That's why it's not working.
mSheet.getRange(2, 1, sheetArray.length, 12).setValues(sheetArray)
I faced the same issue and solved it by following the "Rep" solution. Then I ran into another problem and realized that my number of columns was different... so just go back in and change the no 12 to the number of rows you have in your sheet.
Also try to keep the format of the all sheets the same.
Rename the sheet where you would like the data to combine