Checks a source sheet hourly and appends any rows it has not copied yet into a second sheet. One-way only - nothing is overwritten.

UsesGoogle Sheets

Copy new rows to a second spreadsheet

ScheduleRun every hour.Run every hour.
ValuesSet sourceSpreadsheetLink to blank.Set sourceSpreadsheetLink to blank.
ValuesSet sourceTabName to blank.Set sourceTabName to blank.
ValuesSet destinationSpreadsheetLink to blank.Set destinationSpreadsheetLink to blank.
ValuesSet destinationTabName to blank.Set destinationTabName to blank.
ValuesSet keyColumnNumber to 1.Set keyColumnNumber to 1.
ValuesSet maxNewRowsPerRun to 200.Set maxNewRowsPerRun to 200.
ListsGet the first item of the last item of 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.
ListsGet the first item of the last item of 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.
Decisions & LoopsIf sourceFileId is destinationFileId and sourceTabName is destinationTabNameIf sourceFileId is destinationFileId and sourceTabName is destinationTabName
Yes
Decisions & LoopsStop and report a problem: The source and the destination are the same tab, so every run would copy the sheet into itself. Point 'destinationTabName' at a different tab.Stop and report a problem: The source and the destination are the same tab, so every run would copy the sheet into itself. Point 'destinationTabName' at a different tab.
No
No steps
Google SheetsGoogle SheetsRead column keyColumnNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceKeyColumn.Read column keyColumnNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceKeyColumn.
ValuesSet sourceKeys to sourceKeyColumn.values.Set sourceKeys to sourceKeyColumn.values.
Google SheetsGoogle SheetsRead column keyColumnNumber of destinationTabName in destinationSpreadsheetLink. Save it as destinationKeyColumn.Read column keyColumnNumber of destinationTabName in destinationSpreadsheetLink. Save it as destinationKeyColumn.
ValuesSet copiedKeys to destinationKeyColumn.values.Set copiedKeys to destinationKeyColumn.values.
Decisions & LoopsIf sourceKeys is emptyIf sourceKeys is empty
Yes
Decisions & LoopsFinish the run: The source tab has nothing in its key column, so there was nothing to copy.Finish the run: The source tab has nothing in its key column, so there was nothing to copy.
No
No steps
Decisions & LoopsIf copiedKeys is emptyIf copiedKeys is empty
Yes
Google SheetsGoogle SheetsRead row 1 of sourceTabName in sourceSpreadsheetLink. Save it as sourceHeaderRow.Read row 1 of sourceTabName in sourceSpreadsheetLink. Save it as sourceHeaderRow.
ValuesSet headerValues to sourceHeaderRow.values.Set headerValues to sourceHeaderRow.values.
Decisions & LoopsIf headerValues isn't emptyIf headerValues isn't empty
Yes
Google SheetsGoogle SheetsAdd a row to destinationTabName in destinationSpreadsheetLink.Add a row to destinationTabName in destinationSpreadsheetLink.
No
No steps
No
No steps
ValuesSet copiedCount to 0.Set copiedCount to 0.
ValuesSet blankKeyCount to 0.Set blankKeyCount to 0.
ValuesSet failedCount to 0.Set failedCount to 0.
ValuesSet rowNumber to 0.Set rowNumber to 0.
Decisions & LoopsFor each sourceKey in sourceKeys:For each sourceKey in sourceKeys:
ValuesAdd 1 to rowNumber.Add 1 to rowNumber.
Decisions & LoopsIf rowNumber is 1If rowNumber is 1
Yes
Decisions & LoopsSkip to the next item.Skip to the next item.
No
No steps
Decisions & LoopsIf copiedCount is greater than or equal to maxNewRowsPerRunIf copiedCount is greater than or equal to maxNewRowsPerRun
Yes
Decisions & LoopsStop repeating.Stop repeating.
No
No steps
Decisions & LoopsIf a step below fails, save the error as rowErrorIf a step below fails, save the error as rowError
Try
TextTrim sourceKey and save it as rowKey.Trim sourceKey and save it as rowKey.
Decisions & LoopsIf rowKey is emptyIf rowKey is empty
Yes
ValuesAdd 1 to blankKeyCount.Add 1 to blankKeyCount.
Else if @copiedKeys doesn't contain @rowKey
Google SheetsGoogle SheetsRead row rowNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceRow.Read row rowNumber of sourceTabName in sourceSpreadsheetLink. Save it as sourceRow.
ValuesSet rowValues to sourceRow.values.Set rowValues to sourceRow.values.
Decisions & LoopsIf rowValues isn't emptyIf rowValues isn't empty
Yes
Google SheetsGoogle SheetsAdd a row to destinationTabName in destinationSpreadsheetLink.Add a row to destinationTabName in destinationSpreadsheetLink.
ListsAdd rowKey to the end of copiedKeys and save it as copiedKeys.Add rowKey to the end of copiedKeys and save it as copiedKeys.
ValuesAdd 1 to copiedCount.Add 1 to copiedCount.
No
No steps
Otherwise
No steps
On error
ValuesAdd 1 to failedCount.Add 1 to failedCount.
ValuesShow in the output: Could not copy row rowNumber of the source tab: rowError.message.Show in the output: Could not copy row rowNumber of the source tab: rowError.message.
ValuesSet runSummary to Copied copiedCount new row(s) into '@destinationTabName'.Set runSummary to Copied copiedCount new row(s) into '@destinationTabName'.
Decisions & LoopsIf blankKeyCount is greater than 0If blankKeyCount is greater than 0
Yes
ValuesChange runSummary 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.
No
No steps
Decisions & LoopsIf failedCount is greater than 0If failedCount is greater than 0
Yes
ValuesChange runSummary 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.
No
No steps
Decisions & LoopsIf copiedCount is greater than or equal to maxNewRowsPerRunIf copiedCount is greater than or equal to maxNewRowsPerRun
Yes
ValuesChange runSummary 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.
No
No steps
ValuesShow in the output: runSummary.Show in the output: runSummary.