Checks a source sheet hourly and appends any rows it has not copied yet into a second sheet. One-way only - nothing is overwritten.
Uses
Google Sheets
Copy new rows to a second spreadsheet
Every hour, the key column of a source tab is compared with the key column of a destination tab in another spreadsheet, and every row whose key does not yet appear in the destination is appended there. One team keeps the list, another gets its own copy, and nobody pastes anything.
The copy is one way and append only. Nothing already in the destination is ever written over, and edits or deletions made in the source are not mirrored. A row counts as copied once its key appears in the destination, so running it twice copies nothing the second time. Rows with an empty key cell are left alone and counted in the run summary, a row that fails to copy is reported and tried again next run, and a large first copy is spread over several runs.
Both tabs need the same layout, with a column that identifies each row uniquely, such as an order number or an email address, in the same position in each. If the destination tab is empty, the source's header row is copied across first.
sourceSpreadsheetLink to blank.Set sourceSpreadsheetLink to blank.sourceTabName to blank.Set sourceTabName to blank.destinationSpreadsheetLink to blank.Set destinationSpreadsheetLink to blank.destinationTabName to blank.Set destinationTabName to blank.keyColumnNumber to 1.Set keyColumnNumber to 1.maxNewRowsPerRun to 200.Set maxNewRowsPerRun to 200.sourceSpreadsheetLink split by /spreadsheets/d/ split by / and save it as sourceFileId.Get the first item of the last item of sourceSpreadsheetLink split by /spreadsheets/d/ split by / and save it as sourceFileId.destinationSpreadsheetLink split by /spreadsheets/d/ split by / and save it as destinationFileId.Get the first item of the last item of destinationSpreadsheetLink split by /spreadsheets/d/ split by / and save it as destinationFileId.sourceFileId is destinationFileId and sourceTabName is destinationTabNameIf sourceFileId is destinationFileId and sourceTabName is destinationTabNamekeyColumnNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceKeyColumn.Read column keyColumnNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceKeyColumn.sourceKeys to sourceKeyColumn.values.Set sourceKeys to sourceKeyColumn.values.keyColumnNumber of destinationTabName in destinationSpreadsheetLink. Save it as destinationKeyColumn.Read column keyColumnNumber of destinationTabName in destinationSpreadsheetLink. Save it as destinationKeyColumn.copiedKeys to destinationKeyColumn.values.Set copiedKeys to destinationKeyColumn.values.sourceKeys is emptyIf sourceKeys is emptycopiedKeys is emptyIf copiedKeys is emptysourceTabName in sourceSpreadsheetLink. Save it as sourceHeaderRow.Read row 1 of sourceTabName in sourceSpreadsheetLink. Save it as sourceHeaderRow.headerValues to sourceHeaderRow.values.Set headerValues to sourceHeaderRow.values.headerValues isn't emptyIf headerValues isn't emptydestinationTabName in destinationSpreadsheetLink.Add a row to destinationTabName in destinationSpreadsheetLink.copiedCount to 0.Set copiedCount to 0.blankKeyCount to 0.Set blankKeyCount to 0.failedCount to 0.Set failedCount to 0.rowNumber to 0.Set rowNumber to 0.sourceKey in sourceKeys:For each sourceKey in sourceKeys:rowNumber.Add 1 to rowNumber.rowNumber is 1If rowNumber is 1copiedCount is greater than or equal to maxNewRowsPerRunIf copiedCount is greater than or equal to maxNewRowsPerRunrowErrorIf a step below fails, save the error as rowErrorsourceKey and save it as rowKey.Trim sourceKey and save it as rowKey.rowKey is emptyIf rowKey is emptyblankKeyCount.Add 1 to blankKeyCount.rowNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceRow.Read row rowNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceRow.rowValues to sourceRow.values.Set rowValues to sourceRow.values.rowValues isn't emptyIf rowValues isn't emptydestinationTabName in destinationSpreadsheetLink.Add a row to destinationTabName in destinationSpreadsheetLink.rowKey to the end of copiedKeys and save it as copiedKeys.Add rowKey to the end of copiedKeys and save it as copiedKeys.copiedCount.Add 1 to copiedCount.failedCount.Add 1 to failedCount.rowNumber of the source tab: rowError.message.Show in the output: Could not copy row rowNumber of the source tab: rowError.message.runSummary to Copied copiedCount new row(s) into '@destinationTabName'.Set runSummary to Copied copiedCount new row(s) into '@destinationTabName'.blankKeyCount is greater than 0If blankKeyCount is greater than 0runSummary to runSummary blankKeyCount row(s) had nothing in the key column and were left alone.Change runSummary to runSummary blankKeyCount row(s) had nothing in the key column and were left alone.failedCount is greater than 0If failedCount is greater than 0runSummary to runSummary failedCount row(s) could not be copied and will be tried again next run.Change runSummary to runSummary failedCount row(s) could not be copied and will be tried again next run.copiedCount is greater than or equal to maxNewRowsPerRunIf copiedCount is greater than or equal to maxNewRowsPerRunrunSummary to runSummary This run stopped at its limit of maxNewRowsPerRun rows; the next run carries on from there.Change runSummary to runSummary This run stopped at its limit of maxNewRowsPerRun rows; the next run carries on from there.runSummary.Show in the output: runSummary.