0
votes

I'm doing this as part of the internship. I found here most part of what I needed but still can't complete it because I'm lacking in programmation.

I have 3 SpreadSheets with their IDs:

  • SpreadSheet1 has some data stored in it,
  • SpreadSheet2 is the one where the script is running on,
  • SpreadSheet3 is a backup of SpreadSheet2.

In SpreadSheet2 when I imput something in column A or B the script should look for that value on column A of SpreadSheet1, if the value is the same than it has to copy the corresponding row right after the input (from A to Z if or from B to Z, depending on who got the match) and delete that row from SpreadSheet1. If the value isn't there than the imput should just be deleted.

When i type 0 on column B in the Spreadsheet2 the script should copy all the data present there should on SpreadSheet3 (first row available and 0 should not be copied) than it should erase all rows except the first one from SpreadSheet2.

Possibly this script should be available to use on different SpreadSheets simply by copying it, for example 3 computers should use different SpreadSheets with this script working on the same data from SpreadSheet1 and backuping all in SpreadSheet3.

Here is a visual example of what I'm trying to do

Sorry for bad English and thanks in advance

function example1(e) {
      const range = e.range;
      const sheet = range.getSheet();
      if (sheet.getSheetName() != "Sheet1" || range.getColumn() != 1 || range.getRow() == 1) return;
      const value = range.getValue();
      const values = sheet.getRange("A2:A" + sheet.getLastRow()).getValues();
      values.splice(range.getRow() - 2, 1);
      if (values.flat().includes(value)) {
        range.clearContent();
        return;
      }
      const srcSheet = e.source.SpreadsheetApp.openById("SSheetID1");
      const srcSheet3 = e.source.SpreadsheetApp.openById("SSheetID3");
      const range3 = e.range;
      const sheet = range3.srcSheet3;
      const srcRange = srcSheet.getRange("A2:A" + srcSheet.getLastRow()).createTextFinder(value).matchEntireCell(true).findNext();
      if (srcRange) {
        srcRange.offset(0, 1, 1, srcSheet.getLastColumn() - 1).copyTo(range.offset(0, 1));
        srcRange.offset(0, 1, 1, srcSheet.getLastColumn() - 1).copyTo(range3.offset(0,1));
        srcRange.clearContent();
      }
      else {
        range.clearContent();
        return;
      }
    }
1
Welcome to Stack Overflow. What is the question?Rubén
e.source.SpreadsheetApp this is wrong, remove the e.source part. Also range3.srcSheet3 is wrong. Is like you are calling e.range.e.source.SpreadsheetApp.openById("SSheetID3") .soMario
The question is: how can I access to different spreadsheets?. I know I'm missing something basilar. By now it only eliminates duplicates from column A in the SpreadSheet2 but can't read form SpreadSheet1.Prometheus
Can you add in a Sample spreadsheet that is shared with everyone, please include sample data and please provide a sample of the desired output. Can you also confirm that this runs as an onEdit trigger? Finally could you say what this is for? Maybe with some context we would be able to understand your goal better.iansedano
@iansedano you are right, it's hard to understand with what i've said till now...Prometheus

1 Answers

0
votes

Modified Script

This needs to be installed as an onEdit trigger on sheet 2.

  • If user enters number in col 1 or 2 then it gets the row from SS1.
  • It then deletes that row from SS1.
  • If user enters number 0 in col 1 or 2, then all rows are moved to SS3 from SS2.
function updater(e) {
  // Get details about change in sheet
  let range = e.range;
  let sheet = range.getSheet();
  let value = e.value;
  let row = range.getRow()

  // check if it is request for information from SS1
  let wantInfo = (
    sheet.getSheetName() == "Foglio1" &&
    row != 1 &&
    (
      range.getColumn() == 1 ||
      range.getColumn() == 2
    )
  )

  // check if it is a 0, which means they are done
  let done = (value === "0")

  // If request for info
  if (wantInfo & !done) {
    // Get details of SS1
    let s1 = SpreadsheetApp.openById("1OfPEnvfA7PFLgzLTdfPycCPxsvavE93fHxQ1gFHaUt8")
    let s1sheet = s1.getSheetByName("Foglio1")
    let s1range = s1sheet.getDataRange()
    let s1values = s1range.getValues()

    // Prepare variables
    let output = [];
    let rowToDelete;

    // filter values in s1 to check if same as value searching
    newS1values = s1values.filter((row, index) => {
      if (row[0] == value){
        // if found, set row to delete
        rowToDelete = index + 1
        // remove first value from row
        row.shift()
        // add row to output array
        output.push(row)
        // don't include in newS1values
        return false

      } else return true // else do include in newS1values
    })

    // set range for new row in S2
    let outputRange = sheet.getRange(row, 3, 1, 8);
    // set values for range
    outputRange.setValues(output)
    // delete row in S1
    s1sheet.deleteRow(rowToDelete)

  } else if (done) {
    // if value entered is 0
    // get SS3 details
    let s3 = SpreadsheetApp.openById("1rfYBx3WFko3OmzbbtvlOdN1INkF0Uq6v2sM4d_sMejw")
    let s3sheet = s3.getSheetByName("Foglio1")
    
    // get all data from SS2
    let s2range = sheet.getDataRange();
    let s2values = s2range.getValues();
    // remove headers from value array
    let headers = s2values.shift();
    
    // remove last row (with 0)
    s2values.pop();

    // for each row in SS2 value array, add to SS3
    s2values.forEach(row => s3sheet.appendRow(row))

    // Delete all from SS2
    sheet.clearContents()
    sheet.clearFormats()

    // Add the header to SS2 again
    let headerRange = sheet.getRange(1,1,1,headers.length)
    headerRange.setValues([headers])
  }
}

function init(){}

Notes

  • Ensure that the sheet names, i.e. "Folgio1" are correct.
  • You will need to run the function init to grant permissions before it starts working.

Reference