-1

I need to copy the values of multiple ranges of data from my main spreadsheet into another spreadsheet and then copy a different range of data back to the main spreadsheet.

Here are my example spreadsheets:

The main spreadsheet (two sheets: 1 - A sheet of pasted values alongside columns of user comments. 2 - A sheet with a button that runs the Apps Script)

The live data spreadsheet (pulls and formats the required data from other sheets).

Previously, I’ve used .copyTo() to copy the values of data and paste them elsewhere on the same spreadsheet. However, this method can’t be used to copy data to a different spreadsheet. Copying data from multiple ranges is also causing me issues. Here is my code:

function RefreshSheetData() { 

// 1a. Run the script when a button is pressed (Main Spreadsheet - ‘Update report button!A3’) 
// 1b. Run the script at a certain time (every Monday at 10 AM) 
// 1c. Run the script when data in a sheet is replaced with new data via a formula – NOT POSSIBLE. 
// 2. Copy email address and user comments (Main Spreadsheet - Editable report - J3:J & AM3:AR) 
// 3. Clear the “Updated user comments” sheet below the header row (Live data Spreadsheet - Updated user comments - A2:G) 
// 4. Paste the values (Live data Spreadsheet - Updated user comments - A2:G) 
// 5. Clear the “Editable report” below the header rows (Main Spreadsheet - Editable report – B3:AR) 
// 6. Copy the Live sheet (which should now include the most recent user comments via array vlookup) (Live data Spreadsheet - live data – A3:AQ) 
// 7. Paste the values (Main Spreadsheet - Editable report - B3:AR) 
// 8. Add the (United Kingdom) time and date (Main Spreadsheet - Update report button - A10) 
// 9. Add the time and date (Live data Spreadsheet - Updated user comments - J1) 

ScriptApp.newTrigger('RefreshSheetData') 
.timeBased() 
.onWeekDay(ScriptApp.WeekDay.MONDAY) 
.atHour(10) 
.create(); 

var ss = SpreadsheetApp.getActiveSpreadsheet();
var startSheet = ss.getSheetByName('Editable report');
var sourceRange = startSheet.getRangeList(['J3:J', 'AM3:AR']);
var sourceValues = sourceRange.getValues();

var target = SpreadsheetApp.openById('1OHQHefYvE4vZZPr8jgziy_L3-UBf1WSoKzMWQ8LUz6w');
var targetSheet = target.getSheetByName('Updated user comments');

var clearTargetRange = targetSheet.getRange('A2:G').clearContent();

var targetRange = targetSheet.getRange('A2').setValues(sourceValues);  

var liveTargetSheet = target.getSheetByName('Live data');
var liveSourceRange = liveTargetSheet.getRange('A3:AQ').getValues();

var clearMainRange = startSheet.getRange('B3:AR').clearContent();
var startRange = startSheet.getRange('B3').setValues(liveSourceRange);

SpreadsheetApp.getActive().getRange('A10').setValue(new Date());  
targetSheet.getRange('J1').setValue(new Date()) 

} 

Any tips would be appreciated. Thank you.

Part of my question was how to trigger a script when a formula output changes. That’s not possible. Neither .onEdit or .onChange triggers work as they only respond to user actions. They won't run when the value of an IMPORTRANGE or alternative formula changes.

  • 1
    Welcome to StackOverFlow please take this opportunity to take the [tour] and learn how to [ask] and [mcve]. – Cooper Jul 21 '19 at 16:51
  • @Cooper Done, thanks. I did that before posting too so please let me know if something is unclear in my post. I left my pseudo-code-style instructions and code snippets in the spreadsheet example Script editor as I thought the post was getting long, but I could move it here instead. However, it could be garbage code as it is parts of a basic restart attempt from several hours of research and tweaking which resulted in many script errors or me trying to get code to work that doesn’t work with multiple spreadsheets (.copyTo etc). – Work in Progress Jul 21 '19 at 20:42
  • I'll be glad to help you write it. I suggest that you start. – Cooper Jul 21 '19 at 23:41
  • 1
    Okay, thanks. I appreciate that. I will redo the Apps Script and then edit my post if needed. – Work in Progress Jul 22 '19 at 19:06
  • I have edited my post and included my code. My biggest issue is pasting columns that aren’t directly next to each other into a different spreadsheet – I have tried a few different methods but it’s hard to determine if I’m getting the syntax wrong or the method isn’t suitable for what I want to achieve. Thank you. – Work in Progress Aug 01 '19 at 21:07

1 Answers1

1

Here some suggestions referring to each of the steps mentioned in your Apps Script file

  1. 1b. To run the script at a certain time: please use the installable trigger "Time driven"

    1c. To run the script when data in the sheet is updated: please use the onEdit trigger

    1d. You can combine all triggers by simply adding as many, as required.

  2. To copy and paste data, you just need the methods getValues() and setValues(), which you were using already, the important thing is that you chose the "to copy" range correctly.

  3. You can clear a range with clear()

  4. See 3.

  5. You can copy a sheet with copyTo(), however keep in mind that if using this method, your data in the copied sheet will automatically be updated if there is a change in the original sheet. If you want the values to remain static, you have to copy and paste them with copyValues() and setValues().

  6. See 2. and 5.

  7. See here how to get and format the date in Apps Script

  8. Assign the date to a variable and use setValue()

I encourage you to try and build the script based on those steps yourself, the Apps Script documentation provides you good reference and guidance, how to do so. If you encounter specific problems during one of the steps which you cannot solve with the documentation, feel free to ask!

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • 1
    Thank you very much. I’ll give that a read, redo my Apps Script and then ask if further help is needed. – Work in Progress Jul 22 '19 at 19:06
  • Thanks for linking the documentation. I have edited my code. My main issue is replacing .CopyTo as this can’t be used to copy and paste data to a different spreadsheet. My other issue is copying columns that aren’t directly next to each other. – Work in Progress Aug 01 '19 at 21:09
  • Don't confuse the method copyTo() for ranges and for sheets. The latter one can be used to copy whole sheets to a different spreadsheet. https://developers.google.com/apps-script/reference/spreadsheet/sheet#copyTo(Spreadsheet) If you want to copy only a range to a different spreadsheet however, you need to use `getValues()` and `setValues()`. – ziganotschka Aug 02 '19 at 06:38
  • Ah, I see. That's good to know, thank you. I'm trying `.getValues()` and `.setValues()`. The error I encounter is: "TypeError: Cannot find function getValues in object RangeList." – Work in Progress Aug 05 '19 at 21:54
  • `var sourceValues = sourceRange.getValues();` Line 21 in this post. Line 33 in the Google sheet example (there are a few more notes in the code which I removed for ease of use here). Thanks. – Work in Progress Aug 08 '19 at 07:44
  • The problem is that you are trying to get values from two, non-adjacent ranges contained in the range list. See this: https://stackoverflow.com/questions/36234752/spreadsheet-non-adjacent-column-data/36254935 It's better if you do `var sourceRange1 = startSheet.getRange('J3:J'); var sourceValues1 = sourceRange1.getValues(); var sourceRange2 = startSheet.getRangeList('AM3:AR'); var sourceValues2 = sourceRange2.getValues();` Alternatively, you can install the `RangeListApp` which allows you to get values from rangelists directly: https://github.com/tanaikech/RangeListApp – ziganotschka Aug 08 '19 at 09:03
  • Thank you for offering multiple solutions. I tried your code first and then the code on the linked question. However, I get the error message "The number of rows in the data does not match the number of rows in the range. The data has 7009 but the range has 1" from the line "var targetRange1 = targetSheet.getRange('A2').setValues(sourceValues1);". Is there a way around this or do you suggest installing the RangeListApp instead? – Work in Progress Aug 10 '19 at 22:13
  • You need to know the size of your source range (e.g. with sourceValues1.length ) and assign the matrix sourceValues1 to a range of the same size, rather than a single cell 'A2'. I recommend you to spend some time studying the Apps Script guides, references and examples to get an in-depth understanding of the existing methods and their usage. – ziganotschka Aug 11 '19 at 20:19
  • OK. The size of the source range will change. I'll return to the documentation. Thanks. – Work in Progress Aug 12 '19 at 17:21