Conditional MOVE data from one sheet to another in google spreasheet - google-apps-script

I got the code online and added in the if statement myself and it did not work.
What i would like to achieve:
One column to indicate 'ok' . If 'ok' is present, that row of data will be moved to the other spreadsheet.
function moveData(){
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var originalSheet = app.getActiveSpreadsheet().getSheetByName("Form Responses 4");
var copySheet = app.getActiveSpreadsheet().getSheetByName("RECORDS");
var lc = originalSheet.getLastColumn();
var lr = originalSheet.getLastRow();
var originalData = originalSheet.getDataRange().getValues();
for (var i=originalData.length-1; i>=1 ; --i){
var crange = originalSheet.getRange(i, 37).getValue();
if ( crange == 'ok' ){
copySheet.getRange(copySheet.getLastRow()+1, 1, 1,
originalData[i].length).setValues([ originalData[i] ]);
}
}
}

Related

Copy Row from one Sheet to another sheet which is linked in the row

I have previously been able to copy rows from one Spreadsheet to another, however what I am trying to do now is copy a row to a specific spreadsheet that is linked on the same row and I can't seem to work it out.
I have around 500 rows of names with data (I cannot share a sheet as my firms Google does not allow for sharing externally but I have a screenshot of dummy data below). I used a formula to find the Unique names and then created a Google Sheet for each person and linked the Sheet back to the master data.
Master Data Sheet (tab is called Sheet1)
I am looking for a script that will work through the sheet, copying the rows to the link that is on the same row but I just can't figure it out - the following script does not work but I am at a loss so any help would be appreciated.
Apologies if I haven't explained myself very well!!
function copyTo(){
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Sheet1");
var data = srcSheet.getDataRange().getValues();
for(var i = 1; i < data.length; i++) {
var row = data[i];
var link = row[3];
var id = row[4];
var complete = row[5];
var COMPLETE = "Complete"
if(link !== "" && complete !== "Complete"){
var srcRange = srcSheet.getRange("A" + i + ":C" + i);
var linkID = id.toString()
var tarSS = DriveApp.getFileById(linkID);
var tarSheet = tarSS.getSheetbyName("Sheet1");
var tarRow = tarSheet.getLastRow();
//tarSheet.insertRowAfter(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":C" + (tarRow+1));
srcRange.copyTo(tarRange);
srcSheet.getRange(i+1,6).setValue(COMPLETE)
}
}};
Try this:
function copyTo() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName("Sheet1");
var vs = sh.getDataRange().getValues();
for (var i = 1; i < vs.length; i++) {
var row = vs[i];
var link = row[3];
var id = row[4];
var complete = row[5];
var COMPLETE = "Complete"
if (link !== "" && complete !== "Complete") {
var rg = sh.getRange("A" + i + ":C" + i);
var linkID = id.toString()
var tarSS = SpreadsheetApp.openById(linkID);
var tarSheet = tarSS.getSheetbyName("Sheet1");
var tarRow = tarSheet.getLastRow();
var tarRange = tarSheet.getRange("A" + (tarRow + 1) + ":C" + (tarRow + 1));
rg.copyTo(tarRange);
sh.getRange(i + 1, 6).setValue(COMPLETE)
}
}
};
As much as I understand you question here is the script which will work for you exactly you want .
This will copy data from sheet you want and then create a new spreadsheet and paste into that sheet then link will show of this in same sheet from data copied
Let me know how this worked .
Code.gs
const sendDataToSheet = () => {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName(''paste here your sheet name'')
const newSheet = SpreadsheetApp.create("give new sheet name here")
ws.copyTo(newSheet).setName("Copied Data")
const sheetURL = newSheet.getUrl()
ws.insertRowBefore(1)
ws.getRange(1,1).setValue(sheetURL)
}

Data validation Script loop

I have a code to create a data validation on a cell from a range next to it.
example:
var cellC4 = cell.getRange('F11');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG11:AG11');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC4.setDataValidation(rule);
var cellC5 = cell.getRange('F12');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG12:AG12');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC5.setDataValidation(rule);
var cellC6 = cell.getRange('F13');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG13:AG13');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC6.setDataValidation(rule);
var cellC7 = cell.getRange('F14');
var range = SpreadsheetApp.getActive().getRange('MAIN!AG14:AG14');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cellC7.setDataValidation(rule);
can someone help me do it correctly
Im stuck here:
function onOpen(){
var ss0 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MAIN');
var EndRow = ss0.getLastRow();
for ( var c = 16;c <= 25; c) {
for ( var i = 11;i <= EndRow; i++ ) {
//►PO# VALIDATION►
var range1 = ss0.getRange(i, c);
var rule1 = SpreadsheetApp.newDataValidation().requireValueInRange(range1).build();
ss0.getRange(i, 5).setDataValidation(rule1);
}}}
Findings:
Your looping for this part for ( var c = 16;c <= 25; c) { has a
wrong iteration with c instead of using c++. Thus, this looping
will never finish running.
SUGGESTION:
==UPDATE===
You can try this sample script below:
function onOpen(){
var ss0 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MAIN');
var EndRow = ss0.getLastRow();
for(row=11; row<=EndRow; row++){
var data = ss0.getRange("P"+row+":Y"+row).getDisplayValues();
var rule = SpreadsheetApp.newDataValidation().requireValueInList(data[0]).build();
ss0.getRange(row,5).setDataValidation(rule);
}
}
Sample:
Result on column 5 or column E after the onOpen() function finishes running

Add the time when one google sheets document is modified to another sheets document

I have one sheet for a group of people. I'm trying to make a script so that whenever they edit the sheet, the time that they last edited will show up in a sheet in another document.
A sample row from the group sheet looks like this:
col1|...|col10|person name|...|col17
and the sheet that the time should be going to looks like this:
person name|col2|...|col10|date last edited.
this is the code that I've been trying and it is not working so far:
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
var time = new Date().toLocaleString("en-US", {timeZone: "America/Toronto"})
var ID = "sheet ID"; //The ID for the second sheet goes here
var sheet = SpreadsheetApp.OpenById(ID);
var target = sheet.getSheetByName("Sheet2");
var lastColumn = target.getLastColumn();
var lastRow = target.getLastRow();
var range = target.getRange(1,1,lastRow, lastColumn);
var data = range.getValues();
var userEmail = e.user.getEmail();
var array = userEmail.split(".");
var firstName = array[0];
var secondSheet = e.source.getActiveSheet();
var lastRowSecond = secondSheet.getLastRow();
var lastColumnSecond = secondSheet.getLastColumn();
var secondRange = secondSheet.getRange(1,1,lastRowSecond, lastColumnSecond);
var secondData = secondRange.getValues();
var nameRow = secondData[row-1];
var nameColumn = nameRow[10];
var secondPersonarray = nameColumn.split(" ");
var secondPersonFirstName = secondPersonarray[0];
for (var i=1; i<lastRow; i++) {
var sheetRow = data[i];
var name = sheetRow[0].split(" ");
var firstNameSheet = name[0];
if ((firstName == firstNameSheet) && (firstName == secondPersonFirstName)) {
target.getRange(sheetRow, 10).setValue(time);
}
}
}
I've done something similar, only with one document, so I know the problem isn't with the time.

Matching values between 2 ranges continuously and pasting value in different col, if true

I have a google sheet with 2 tabs, BOMSheet & POProcess. I want to copy the PO Number from PO Process sheet by looking up the column B values of POProcess sheet (one by one continuously) in column D values of BOM Sheet and if matches then pasting the PO number in column M of the BOM sheet (for all values that are matched). here is the link of the sheet.
https://docs.google.com/spreadsheets/d/1MqYn2AjPncx-RvvyTS8Nj0ujpm9Lcd_ORJF9Wqbw6y0/edit?usp=sharing
I tried the code below but it's not working as its checking up the only one value from the PO Process sheet. Please help how to iterate the values from PO process sheet
function UpdateStatus() {
var sss = SpreadsheetApp.getActiveSpreadsheet();
var ss = sss.getSheetByName('POProcess'); //replace with source Sheet tab name
var range = ss.getRange('C4'); //assign the range you want to copy
var data = range.getValues();
var range2 = ss.getRange('B8'); //value to look for to be replaced
var data2 = range2.getValues();
var sheet = sss.getSheetByName('BOMSheet');
var range3 = sheet.getRange('A:L');
var values = range3.getValues();
for (var i = 0; i < values.length; i++) {
if (values[i][3] == data2) {
values[i][12] = data;
}
}
range3.setValues(values);
}
You can use this function for only PO number.
function UpdateStatus() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pSheet = ss.getSheetByName('POProcess'); //replace with source Sheet tab name
var pNumber = pSheet.getRange('C4').getValue(); //assign the range you want to copy
var pRange = pSheet.getRange(8, 2, pSheet.getLastRow()-7, 1); //value to look for to be replaced
var pData = pRange.getValues().map(function(el) {
return el[0];
});
var sheet = ss.getSheetByName('BOMSheet');
var range3 = sheet.getDataRange();
var values = range3.getValues();
values.forEach(function(row) {
if (row[3] == '') return;
if (pData.indexOf(row[3]) > -1) {
row[12] = pNumber;
}
});
range3.setValues(values);
}
For mapping 'Qty Received' column also, try this.
function UpdateStatus() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pSheet = ss.getSheetByName('POProcess'); //replace with source Sheet tab name
var pNumber = pSheet.getRange('C4').getValue(); //assign the range you want to copy
var pRange = pSheet.getRange(8, 2, pSheet.getLastRow() - 7, pSheet.getLastColumn()-1); //values to map
var pData = {};
pRange.getValues().forEach(function(row) {
pData[row[0]] = row[6];
});
var sheet = ss.getSheetByName('BOMSheet');
var range3 = sheet.getDataRange();
var values = range3.getValues();
values.forEach(function(row) {
if (row[3] == '') return;
if (typeof pData[row[3]] != 'undefined') {
row[12] = pNumber;
row[13] = pData[row[3]];
}
});
range3.setValues(values);
}

Google Script: When cell is filled, have prompt ask if user wants to run script

I have written a script to clean up and move data between 3 different sheets. A user first paste a data extract on to the "Extract" page, and then runs the script.
When a user paste the data into cell A1 on the "Extract" page, I would like a prompt box to ask the user if they would like to run the script; if Yes, run script, if No, don't run script and show message. How would I go about doing this?
This is what I have so far...everything after the first function works.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Extract");
if(ss.s().getRange("A1").getValue() != ""){
var ui = SpreadsheetApp.getUi()
var response = ui.alert('Would you jbot to find new claims for you?', ui.ButtonSet.OK_CANCEL);
if (response == ui.Button.OK) {
jbot();
} else {
Logger.log('The user clicked "No" or the close button in the dialog\'s title bar.');
}
}
}
function jbot(){
movetobot();
deleteRows();
removeDupesInOtherSheets();
deleteCol();
cleanup();
movetoqueue();
message();
};
function movetobot() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Extract");
var ts = ss.getSheetByName("bot");
s.getRange("A1:BW").moveTo(ts.getRange("A1"));
}
function deleteRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("bot");
var r = s.getRange("BO:BO");
var v = r.getValues();
for(var i=v.length-1;i>=0;i--)
if(v[0,i]=='#POSTLESSEE' || v[0,i]=='#TDI CRC_OANKURA' || v[0,i]=='#Partpaymentoffer' || v[0,i]=='#TDI_CRC_DVANKURA' || v[0,i]=='#partpaymentdupe' )
s.deleteRow(i+1);
}
function removeDupesInOtherSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1 = ss.getSheetByName("bot").getDataRange().getValues();
var s2 = ss.getSheetByName("Queue").getDataRange().getValues();
// iterate 'Queue' and check in 'bot' if duplicate values exist
var nS1 = [];
var s2Col1 = [];// data in column1 of Queue
for(var n in s2){
s2Col1.push(s2[n][0]);
}
for(var n in s1){ // iterate '180418970' and test col 1 vs col 1 in 'Queue'
var noDup1 = checkForDup(s1[n],s2Col1)
if(noDup1){nS1.push(noDup1)};// if not present in 'Queue' then keep
}
Logger.log(nS1);// view result
ss.getSheetByName("bot").getDataRange().clear();// clear and update sheets
ss.getSheetByName("bot").getRange(1,1,nS1.length,nS1[0].length).setValues(nS1);
}
function checkForDup(item,s){
Logger.log(s+' = '+item[0]+' ?')
if(s.indexOf(item[0])>-1){
return null;
}
return item;
}
function deleteCol() {
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
var lastCol = sheet.getLastColumn();
var keep = [1,2,3,4,45,53,74, 75]; // array of column numbers to keep
for (var col=lastCol; col > 0; col--) {
if (keep.indexOf(col) == -1) {
// This isn't a keeper, delete it
sheet.deleteColumn(col);
}
}
}
function cleanup() {
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
sheet.getRange("B1:B").moveTo(sheet.getRange("H1"));
sheet.deleteColumn(2)
sheet.deleteRow(1)
var cell = sheet.getRange("D:D");
cell.setNumberFormat("m/d/yy");
var cell = sheet.getRange("F:F");
cell.setNumberFormat("m/d/yy");
var cell = sheet.getRange("A:A");
cell.setHorizontalAlignment("center");
var cell = sheet.getRange("C:D");
cell.setHorizontalAlignment("center");
var cell = sheet.getRange("F:G");
cell.setHorizontalAlignment("center");
sheet.autoResizeColumn(2)
sheet.autoResizeColumn(5)
sheet.autoResizeColumn(7)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
var cell = sheet.getRange("BW1");
cell.setFormula("=COUNT(A:A)");
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
var range = sheet.getRange("A1:G");
range.sort({column: 4, ascending: true})
}
function movetoqueue() {
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
// skip row 1 (header) and beyond column G
var range = sheet.getRange(1,1,sheet.getLastRow()-1,7);
sheet = spread.getSheetByName("Queue");
var rows = sheet.getRange(1,1,sheet.getLastRow(),1).getValues();
// search for first blank row column 1
for( var i=0; i<rows.length; i++ ) {
if( rows[i][0] === "" ) {
var offset = sheet.getRange(1,1).offset(i,0);
range.copyTo(offset);
break;
}
}
}
function message() {
SpreadsheetApp.getActive().getSheetByName("Queue").activate();
var spread = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spread.getSheetByName("bot");
var range = sheet.getRange("bot!BW1:BW1");
var data = range.getValue();
Browser.msgBox(data + " new claims have been added to the queue. Thank you for using jBot!");
}
Your onEdit(e) will trigger the alert regardless of which cell is edited. You need to check the event range to limit it to cell A1 of Extract like this.
function onEdit(e) {
if( e.range.getSheet().getName() === "Extract" ) {
if( e.range.getA1Notation() === "A1" ) {
if( e.value !== "" ) {
var ui = SpreadsheetApp.getUi();
// Do the rest of your stuff here
}
}
}
}