Joe Joe - 2 months ago 14
Javascript Question

Script for Google Sheets to Move Row to New Sheet

I am having some issues with a shop schedule I am trying to set up. I would like to have en entire row be moved the corresponding new tab when certain data is entered into column "J". I have included an editable link for a sample sheet I created that also helps explain what I am trying to do.

If possible, it would also be helpful to be able to make the backgrounds change to the colors on the sample sheet as well.

Thank you!

Editable Link: https://docs.google.com/spreadsheets/d/1D0iptPchrrLuq75ysvXwisBa_Xr0fuNabAdTb3sm-yA/edit?usp=sharing

Answer

This is a crude code that will work, however if you change the value to the same that it is on (so if it's in complete, and you edit it to change to 20) it will just delete the row. It would be easy to fix, but I just don't have the time right now :)

EDIT: just remembered to note, that it will use the last row, so for moving stuff back to appointments you should move the legend to the top of the sheet :) Or you should just get rid of the move back to appointments bit altogether. You can also play around with how the variables are worked with, I just don't like grabbing the sheets again so I send a lot of them to the move function.

function onEdit(e) {
  var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();  //get active spreadsheet
  var srcSheet = spreadSheet.getActiveSheet();  //get active sheet

  var editCol = e.range.getColumn(); //check the edited column
  if (editCol!==10) {return}  //if the edited column is not J then we don't need to do anything else
  var srcLastCol = srcSheet.getLastColumn(); //check how large is our data range
  var srcRow = srcSheet.getRange(e.range.getRow(), 1, 1, srcLastCol); //get the source row range
  var srcVals = srcRow.getValues(); //get the values from the source fow
  var destSheet, destRow, destRange; //destination variables
  Logger.log(e.value)

  if (e.value>=1 && e.value<=14) {  //for 1-14 we use we assign 1 sheet, the same function for everything
    moveRow('In Shop', srcRow, srcVals, srcLastCol, spreadSheet);
  }  
  else {  //for everything else we use a switch
    switch(e.value) {
      case '15':
        moveRow('Arrive / In Lot', srcRow, srcVals, srcLastCol, spreadSheet);
        break;
      case '17':
        moveRow('Waiting on Parts, Truck, Etc.', srcRow, srcVals, srcLastCol, spreadSheet);     
        break;
      case '20':
        moveRow('Completed', srcRow, srcVals, srcLastCol, spreadSheet);
        break;
      default :
        moveRow('Appointments', srcRow, srcVals, srcLastCol, spreadSheet);
      }
  }  
}

function moveRow(destName, srcRow, srcVals, srcLastCol, spreadSheet) {
  var destRow
  var destSheet = spreadSheet.getSheetByName(destName)
  destRow = destSheet.getLastRow() + 1;
  destSheet.getRange(destRow, 1, 1, srcLastCol).setValues(srcVals)
  srcRow.clear()
}

EDIT2 Answering comments

function moveRow(destName, srcRow, srcVals, srcLastCol) {
  var spreadSheet = SpreadsheetApp.getActiveSpreadsheet()
  var destRow
  var destSheet = spreadSheet.getSheetByName(destName)
    destRow = destSheet.getLastRow() + 1;
    destSheet.getRange(destRow, 1, 1, srcLastCol).setValues(srcVals)
    srcRow.clear()
}

However, that would be bad practice for any larger script that has a long runtime. You would then waste time accessing the SpreadsheetApp every time.

As for the colours, it's a fairly simple adjustment in the moveRow():

function moveRow(destName, srcRow, srcVals, srcLastCol, spreadSheet) {
  var destRow
  var destSheet = spreadSheet.getSheetByName(destName);
  destRow = destSheet.getLastRow() + 1;

  var destRange = destSheet.getRange(destRow, 1, 1, srcLastCol);
  destRange.setValues(srcVals);
  destRange.setBackground(destSheet.getTabColor())
  srcRow.clear()
}

As for sorting, this is where you need to have destSheet = spreadSheet.getSheetByName(destName); before calling the moveRow(). So bellow, let's assume that you retrieve the destSheet somewhere before the if or in the if itself. This sample will sort it by column A in ascending order (so adjust the 1 to what you need, let's say you want J, then it would be 10)

  if (e.value>=1 && e.value<=14) {
    moveRow('In Shop', srcRow, srcVals, srcLastCol, spreadSheet);
    destSheet.sort(1)acceding order
  }