While loop duplicates lines to new sheet until cell = 0 - google-apps-script

I am trying to copy a row over to a new sheet multiple times (based on user response).
After the row has been copied over x number of times, it should move to another sheet and then be removed from the original sheet.
I have it almost working but the while() loop will only subtract from the active cell once in row z and then just keeps repeating.
I would appreciate any help. Here is what I have:
function dupLines()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
var cell = s.getCurrentCell();
var cellValue = cell.getValue();
function getTimeStamp()
{
var now = new Date();
return ((now.getMonth() + 1) + '/' + (now.getDate()) + '/' + now.getFullYear() );
}
while (cellValue > '0')
{
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cell.setValue(cellValue - 1);
}
awarded.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetAwd = awarded.getRange("A19");
s.getRange(row, 1, 1, numColumns).moveTo(targetAwd);
awarded.getRange("X19").setValue(getTimeStamp());
s.deleteRow(row);
}
******************* UPDATE ********************
This is what I have that is now working. I am sure it can be simplified?
function onOpen(e){
SpreadsheetApp.getUi().createMenu('QUEUE MENU')
.addItem('Create POs', 'CreatePOs')
.addSeparator()
.addItem('Sidebar Queue', 'openSidebar')
.addToUi();
}
function CreatePOs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
if(s.getName() == "QUEUE" && r.getColumn() == 22 && r.getValue() == true) {
userInput();
dupLines();
moveToAwarded();
}
else
{
Browser.msgBox('Please check box in PO Status column.');
};
}
function userInput() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().offset(0, 4).activate();
var prompt = SpreadsheetApp.getUi().prompt('How many lines do you want to send to PO STATUS?', SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(prompt.getSelectedButton() === SpreadsheetApp.getUi().Button.OK){
value = prompt.getResponseText();
}
spreadsheet.getCurrentCell().setValue(value);
}
function dupLines(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
var cell = s.getCurrentCell();
var cellValue = cell.getValue();
function getTimeStamp() {
var now = new Date();
return ((now.getMonth() + 1) + '/' +
(now.getDate()) + '/' +
now.getFullYear() );
}
while (cellValue > 0) {
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cellValue--;
} }
function moveToAwarded() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
function getTimeStamp() {
var now = new Date();
return ((now.getMonth() + 1) + '/' +
(now.getDate()) + '/' +
now.getFullYear() );
}
awarded.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetAwd = awarded.getRange("A19");
s.getRange(row, 1, 1, numColumns).moveTo(targetAwd);
awarded.getRange("X19").setValue(getTimeStamp());
s.deleteRow(row);
}
function openSidebar(){
var html = HtmlService.createHtmlOutputFromFile('Sidebar').setTitle('Queue Quick View');
SpreadsheetApp.getUi().showSidebar(html);
}

One of the problems (and there may be others) that I can spot is in:
cell.setValue(cellValue - 1); // Changes the value in the cell but not in the script
This changes the value in the active cell. But it does not change the value of the variable cellValue.
Try this while-loop instead:
while (cellValue > '0')
{
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cellValue--; // Reduce value by 1
cell.setValue(cellValue); // Set new value in cell
}
A few other suggestions that may help:
1
while (cellValue > '0') is checking for a string value '0'. It works because alphabetically, all positive numbers are greater than 1. But strictly speaking you want while (cellValue > 0)
2
cell.setValue(cellValue); has cosmetic value, i.e. it updates the cell. But the updated value is not used in the script.
Best practices suggest not making unnecessary calls to the sheet. So you could do without that line and have the script run a bit faster.

Related

Iterate through column A and do until empty cell

My script is working but it times out. I am unsure as to what I can do to keep it from doing this.
function archived(e) {
var sheet = SpreadsheetApp.getActive().getSheetByName('IVA');
const targetSheet = e.source.getSheetByName('Archived Videos');
const numColumnsToMove = 20;
var sheetTo = SpreadsheetApp.getActive().getSheetByName('IVA');
var myValues = sheetTo.getRange('A:A').getValues();
var i;
for (i = 0; i < myValues.length; i++) {
if (myValues[i][0] === '')
return i + 1;
const rangeToMove = sheet.getRange(e.range.rowStart, 1, 1, numColumnsToMove);
const values = rangeToMove.getValues();
appendRowsV(targetSheet, values, 1);
sheet.deleteRows(e.range.rowStart, 1);
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn(), range = sheet.getRange(lRow,1,1,lCol);
sheet.insertRowsAfter(lRow, 1);
range.copyTo(sheet.getRange(lRow+1, 1, 1, lCol), {contentsOnly:false});
}
}
As an FYI my sheet has 1500 rows and 15 columns. don't know if that is important or not.
Just in case. As far as I can tell from your code you're trying to append all data from the sheet 'IVA' at the bottom of the sheet 'Archived Videos'. It can be done this way:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var src_range = ss.getSheetByName('IVA').getDataRange();
var dest_sheet = ss.getSheetByName('Archived Videos');
var last_row = dest_sheet.getLastRow() + 1;
var dest_range = dest_sheet.getRange('A' + last_row);
src_range.copyTo(dest_range);
}

Google App Scripts: How do you copy a row to the next available row in a new tab depending on the value in a cell

I am trying to transfer a row (range A:AE) from sheet NSI to the next available row in Sheet1 if cell AE= 1.
My code doesn't seem to work, please could somebody help me?
Thank you!!
function myFunction() {
function copyRows() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("NSI");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var srcRange = srcSheet.getRange("A" + i + ":AE" + i);
var cell = srcSheet.getRange("AE" + i);
var val = cell.getValue();
//sets the target sheet depending on the exam in column AE
if (val == "1") {
var tarSheet = sSheet.getSheetByName("Sheet1");
}
//insets the row in the correct target worksheet
var tarRow = tarSheet.getLastRow()+1;
tarSheet.insertRows(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow) + ":AE" + (tarRow));
srcRange.copyTo(tarRange);
}
};
}
function copyRows() {
var sSheet = SpreadsheetApp.getActive();
var srcSheet = sSheet.getSheetByName("NSI");
const vs = srcSheet.getRange(2, 1, srcSheet.getLastRow() - 1, 31).getDisplayValues();
var tarSheet = sSheet.getSheetByName("Sheet1");
vs.forEach(r => {
if (r[30] == "1") {
tarSheet.appendRow(r);
}
});
}

Check if in cell Today's date then continue

I found a script on the Internet and am trying to alter it a little to fit my needs. But stumbled upon a problem. The script takes a list of bookmarks from the drop down menu and if you write OK in the next cell, then it transfers the line to the selected bookmark. I want to confirm today's date.
Copy of the sheet. Also here some diffeent.
var actionCol = 7;
var nameCol = 6;
https://docs.google.com/spreadsheets/d/1P9avWP8i5Z4KA4zt3EoUZNbgMKeXwnOYKsgCG2_vSLE/edit?usp=sharing
/**
* Moves row of data to another spreadsheet based on criteria in column 6 to sheet with same name as the value in column 4.
*/
function onEdit(e) {
// see Sheet event objects docs
// https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
// to let you modify where the action and move columns are in the form responses sheet
var actionCol = 10;
var nameCol = 9;
// Get the row and column of the active cell.
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
// Get the number of columns in the active sheet.
// -1 to drop our action/status column
var colNumber = s.getLastColumn()-1;
// if our action/status col is changed to ok do stuff
if (e.value == "ok" && colIndex == actionCol) {
// get our target sheet name - in this example we are using the priority column
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
// if the sheet exists do more stuff
if (ss.getSheetByName(targetSheet)) {
// set our target sheet and target range
var targetSheet = ss.getSheetByName(targetSheet);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
// get our source range/row
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
// new sheets says: 'Cannot cut from form data. Use copy instead.'
sourceRange.copyTo(targetRange);
// ..but we can still delete the row after
s.deleteRow(rowIndex);
// or you might want to keep but note move e.g. r.setValue("moved");
}
}
}
If I understand you correctly, you want to cut & paste the edited row if:
The edited column is G, and the value is a Date corresponding to today.
The corresponding name in column F refers to the name of an existing sheet.
In order to check that the two dates correspond to the same day, you can compare the values returned by getDate(), getMonth() and getFullYear(), as in this function (credits to Pointy):
function sameDay(d1, d2) {
return d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate();
}
Then, you can call this in your main function:
function onEdit(e) {
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
var value = r.getValue();
var actionCol = 7;
var nameCol = 6;
var rowIndex = r.getRow();
var colIndex = r.getColumn();
var colNumber = s.getLastColumn();
if (value instanceof Date && colIndex == actionCol) {
var today = new Date();
if (sameDay(value, today)) {
var targetSheetName = s.getRange(rowIndex, nameCol).getValue();
var targetSheet = ss.getSheetByName(targetSheetName);
if (targetSheet) {
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
}
}
Try it this way:
function onEdit(e) {
var ss = e.source;
var s = e.range.getSheet();
var r = e.range;
var actionCol = 10;
var nameCol = 9;
var rowIndex = r.rowStart;
var colIndex = r.columnStart;
var colNumber = s.getLastColumn()-1;
const dt=new Date(e.range.offset(0,n));//you add the column offset
const dtv=new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();
const td=new Date();
const tdv=new Date(td.getFullYear(),td.getMonth(),td.getDate()).valueOf();
if (e.value == "ok" && colIndex == actionCol && dtv==tdv) {
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
var tSh = ss.getSheetByName(targetSheet);
if (tSh) {
var targetRange = tSh.getRange(tSh.getLastRow()+1, 1, 1, colNumber);
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
}

Google script for move rows depending on checkbox - Google sheet

I've got a script that moves a row from one tab "COMMUNICATIONS" to another tab "ARCHIVE" when a cell checkbox (column AE) is true but it's only working well with the row AE2 and it's not working when I check AE3 or AE6.
function onEdit() {
var sheetNameToWatch = "COMMUNICATIONS";
var sheetNameToMoveTheRowTo = "ARCHIVE";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName(sheetNameToWatch);
var sheet2 = ss.getSheetByName(sheetNameToMoveTheRowTo);
var cell1 = sheet1.getRange("AE2:AE1000");
var x= cell1.getValue();
Logger.log("a",x);
if(cell1.getValue()== false) {
Logger.log("box not checked");
sheet1.showSheet();
} else if (cell1.getValue() == true) {
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1,
sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}
you can try this code. I Tested it on one of my sheets and it worked fine.
function onEdit(event) {
// assumes source data in sheet named Active
// target sheet of move to named Found
// test column with yes/no is col 13 or M
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "COMMUNICATIONS" && r.getColumn() == 13 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("ARCHIVE");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}

Changing from getActiveCell(); to getting a range instead

This may be fairly simple for you guys.
How to replace getActiveCell() for something I dont need to be online for the script to run, so I can set it up based on a time-trigger?
Check the code block below.
function MoveRows() {
var sheetNameToWatch = "Requests";
var sheetNameToMoveTo = "Approved";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getActiveCell();
var range = sheet.getActiveCell();
var row = range.getRow();
if (sheet.getName() == sheetNameToWatch &&
sheet.getRange(row, 8).getValue() == "Y" &&
sheet.getRange(row, 12).getValue() == "Approved") {
{
var targetSheet = ss.getSheetByName(sheetNameToMoveTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1,
sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}}
Thank you!
After looking at your code a bit I'm guessing this maybe close to what your looking for.
function MoveRows() {
var sheetNameToWatch = "Requests";
var sheetNameToMoveTo = "Approved";
var ss = SpreadsheetApp.openById(id)
var sheet = ss.getSheetByName('Requests')
var range = sheet.getRange(sheet.getLastRow(),1,1,sheet.getLastColumn());
var values=range.getValues();
var row = range.getRow();
if (values[0][7] == "Y" && values[0][11] == "Approved") {
var targetSheet = ss.getSheetByName(sheetNameToMoveTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
range.moveTo(targetRange);//you could also just do targetSheet.appendRow(values[0]); Your call
sheet.deleteRow(range.getRow());
}
}