0

I have a sheet where users download the latest version (make a copy of) from a blank master. I want them to be able to import their 'logs' (2 sheets with ranges) from whatever version they last had by copying the spreadsheet id from their original sheet and pasting it into a box and pressing a button that executes the installable trigger script.

In this instance, both sheets would be in the users drive. I know there are some limitations with openByID.

I found a few things on here, but I'm unsure of how to call or parse the pasted id from the cell, as the example below (which I found here) seems wrong since it just defines a variable twice.

function setTrigger() {
  var ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger("importlogs").forSpreadsheet(ss).onEdit().create();
}

//variables
var id = "123456789abcdefg";
var sheet = "LOG WIZARD";
var cells = "M11:AB13";
var range = SpreadsheetApp.openById(id).getSheetByName(sheet).getRange(cells);
var id = range.getSheet().getParent().getId();

//custom function to import logs
function importlogs() {

//Source sheet from which to import from
var is = SpreadsheetApp.openById(id)
var sheet1i = is.getSheetByName("BUDGET LOG");
var sheet2i = is.getSheetByName("LOG");

//Current sheet from which to export to
var xs = SpreadsheetApp.getActiveSpreadsheet();
var sheet1x = xs.getSheetByName("BUDGET LOG");
var sheet2x = xs.getSheetByName("LOG");

//Copy and paste contents of import Budget Log sheet to export Budget Log sheet
sheet1i.getRange("A3:AO").copyTo(sheet1x.getRange(sheet1x.getLastRow()+1,1,1,7), {contentsOnly:true});

//Copy and paste contents of import Log sheet to export Log sheet
sheet2i.getRange("A3:O").copyTo(sheet2x.getRange(sheet2x.getLastRow()+1,1,1,7), {contentsOnly:true});

}

1 Answers1

0

When the trigger fires, you can examine the event object e to find which cell was edited. If it is the cell you are interested in, you can call the import function with the value that was entered, like this:

/**
* Installable trigger that runs each time the user hand edits the spreadsheet.
*
* @param {Object} e The installable "on edit" event object.
*/
function runImportLogs(e) {
  if (!e) {
    throw new Error(
      'Please do not run the runImportLogs(e) function in the script editor window. '
      + 'It runs automatically when you hand edit the spreadsheet.'
    );
  }
  if (!e.value
    || e.range.getA1Notation() !== 'M11'
    || e.range.getSheet().getName() !== 'LOG WIZARD') {
    return;
  }
  importLogs_(e.value);
}

To use the passed value in the import function, declare it as an argument, like this:

/**
* Imports logs.
*
* @param {Object} sourceSsId The ID of the spreadsheet where to read data from.
*/
function importLogs_(sourceSsId) {
  try {
    const sheetNames = ['BUDGET LOG', 'LOG',];
    const sourceSs = SpreadsheetApp.openById(sourceSsId);
    const sourceSheets = sheetNames.map(sheetName => sourceSs.getSheetByName(sheetName));
    const targetSs = SpreadsheetApp.getActive();
    const targetSheets = sheetNames.map(sheetName => targetSs.getSheetByName(sheetName));
    sourceSheets.forEach((sheet, index) => {
      const data = sheet.getRange('A3:AO').getValues();
      appendRows_(targetSheets[index], data);
    });
  } catch (error) {
    SpreadsheetApp.getActive().toast(error.message);
    throw error;
  }
}

For this to work, you will need to paste the appendRows_() utility function in the script project.

Finally, when you are setting up the trigger, it usually makes sense to first delete any duplicate triggers that may still be hanging around:

function setTrigger() {
  const ss = SpreadsheetApp.getActive();
  const triggers = ScriptApp.getUserTriggers(ss);
  triggers.forEach(trigger => {
    if (trigger.getEventType() === ScriptApp.EventType.ON_EDIT) {
      ScriptApp.deleteTrigger(trigger);
    }
  });
  ScriptApp.newTrigger('runImportLogs').forSpreadsheet(ss).onEdit().create();
}
doubleunary
  • 13,842
  • 3
  • 18
  • 51
  • I get no errors, but no data is copied. https://docs.google.com/spreadsheets/d/1833-5CnOurssETuZFtohiHRRBx1V3_95_L0S-f9vPLk/edit?usp=sharing – Dapperstache Theatres Oct 02 '22 at 09:51
  • Your script project's [execution log](https://script.google.com/home/projects/1AUJun5iAVKd5htS8TggcbCCcCpfqHZkz-Fs0XKg1__oHu-273JElWSKW/executions) shows that the `runImportLogs(e)` has not run. That indicates that you have not set up a trigger. You should run `setTrigger()` once to create a trigger. See [installable triggers](https://developers.google.com/apps-script/guides/triggers/installable). – doubleunary Oct 02 '22 at 10:34
  • When you get `runImportLogs(e)` to run, you will note that it is not doing anything. The reason is that it only watches cell `'LOG WIZARD'!M11` that does not exist in your sample spreadsheet. An additional issue is that you have not pasted the code for the [appendRows_()](https://webapps.stackexchange.com/a/159426/269219) utility function in the script project. – doubleunary Oct 02 '22 at 10:37
  • See [Apps Script at Stack Overflow](https://stackoverflow.com/tags/google-apps-script/info). – doubleunary Oct 02 '22 at 10:37
  • I would like to keep the button functionality. Unfortunately, though I tried using your solutions, I have thus far been unable to make them work. – Dapperstache Theatres Oct 03 '22 at 20:55
  • If you want to use a button, use a [button](https://developers.google.com/apps-script/guides/menus#clickable_images_and_drawings_in_google_sheets) instead of a [trigger](https://developers.google.com/apps-script/guides/triggers). That is a different question though. Please ask only [one question per post](https://meta.stackexchange.com/a/222741). Do not post code that is unrelated to what you are trying to do. Always indicate where you got the code from. – doubleunary Oct 04 '22 at 05:22
  • My apologies if my question was unclear, however, I did mention the use of a button and explained as best I could what I was trying to do in my post. The code was cobbled together based on what I had learned before, which admittedly isn't much. My specific issue was not knowing how to call the value in the cell when the button is clicked. Beyond that are the apparent issues with openById to call a sheet in a different workbook. – Dapperstache Theatres Oct 04 '22 at 06:20
  • A button always runs a script function directly. You do not need any triggers. Please post a [new question](https://stackoverflow.com/questions/ask). – doubleunary Oct 04 '22 at 06:36