Advertisement
IAmMoonie

Compare timestamps and copy data

Sep 16th, 2024
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.32 KB | Source Code | 0 0
  1. /**
  2.  * @fileoverview Google Apps Script to import new rows from a source sheet to a destination sheet based on unique timestamps.
  3.  *
  4.  * Author: u/IAmMoonie
  5.  * @see https://www.reddit.com/r/GoogleAppsScript/comments/1fi5vw5/compare_timestamps_on_both_sheets_only_copy/
  6.  * Version: 1.0
  7.  */
  8.  
  9. /**
  10.  * Configuration object for the importNewRequests function.
  11.  *
  12.  * @typedef {Object} Config
  13.  * @property {string} sourceID - The ID of the source Google Sheets spreadsheet.
  14.  * @property {string} formRange - The range in the source sheet to check for new rows, formatted as 'SheetName!A1:R'.
  15.  * @property {string} workingRangeStart - The starting cell in the destination sheet where new rows will be appended.
  16.  * @property {string} timestampColumn - The letter of the column in the source sheet that contains the timestamps.
  17.  */
  18. const config = {
  19.   sourceID: "1MTvMNwNYlKqfgaU_lvv-RqW4Jofs2Z1rrlLRAj4yFzM",
  20.   formRange: "Master!A1:R",
  21.   workingRangeStart: "Working!A1",
  22.   timestampColumn: "A"
  23. };
  24.  
  25. /**
  26.  * WARNING: Do not edit anything below this point unless you are familiar with Google Apps Script and the purpose of the code.
  27.  */
  28.  
  29. /**
  30.  * Imports new requests from the source sheet to the destination sheet if they have unique timestamps.
  31.  */
  32. const importNewRequests = () => {
  33.   const sourceSpreadsheet = SpreadsheetApp.openById(config.sourceID);
  34.   const sourceSheet = sourceSpreadsheet.getSheetByName(
  35.     config.formRange.split("!")[0]
  36.   );
  37.   const destSheet = sourceSpreadsheet.getSheetByName(
  38.     config.workingRangeStart.split("!")[0]
  39.   );
  40.   const timestampColIndex = getColumnIndex_(config.timestampColumn);
  41.   const sourceValues = sourceSheet.getRange(config.formRange).getValues();
  42.   const sourceRowCount = sourceValues.length;
  43.   console.info(`Source sheet contains ${sourceRowCount} row(s).`);
  44.   const lastDestRow = getLastNonEmptyRow_(destSheet, timestampColIndex + 1);
  45.   const destRowCount = lastDestRow;
  46.   console.info(`Destination sheet currently has ${destRowCount} row(s).`);
  47.   const destTimestamps = new Set(
  48.     destSheet
  49.       .getRange(1, timestampColIndex + 1, lastDestRow, 1)
  50.       .getValues()
  51.       .flat()
  52.       .map((ts) => new Date(ts).getTime())
  53.   );
  54.   const newRows = [];
  55.   console.info(
  56.     "Checking rows in the source sheet that have a different timestamp compared to the destination sheet"
  57.   );
  58.   sourceValues.forEach((row, index) => {
  59.     const timestamp = new Date(row[timestampColIndex]).getTime();
  60.     console.info(`Checking row ${index + 1}: Timestamp: ${timestamp}`);
  61.     if (timestamp && !destTimestamps.has(timestamp) && !isRowEmpty_(row)) {
  62.       console.info(
  63.         `New row detected with timestamp ${new Date(
  64.           timestamp
  65.         )}, adding to newRows...`
  66.       );
  67.       newRows.push(row);
  68.     } else {
  69.       console.info(
  70.         `Row ${
  71.           index + 1
  72.         } already exists in Working sheet or missing timestamp, skipping.`
  73.       );
  74.     }
  75.   });
  76.   const newRowCount = newRows.length;
  77.   console.info(`${newRowCount} new row(s) meet the requirements.`);
  78.   if (newRowCount > 0) {
  79.     const destRange = destSheet.getRange(
  80.       lastDestRow + 1,
  81.       1,
  82.       newRowCount,
  83.       newRows[0].length
  84.     );
  85.     console.info(`Copying ${newRowCount} new row(s) to the destination sheet.`);
  86.     destRange.setValues(newRows);
  87.   } else {
  88.     console.info("No new rows to copy.");
  89.   }
  90. };
  91.  
  92. /**
  93.  * Gets the last non-empty row in a specific column of a sheet.
  94.  *
  95.  * @param {Sheet} sheet - The sheet to check.
  96.  * @param {number} column - The column number to check for non-empty rows.
  97.  * @return {number} The index of the last non-empty row.
  98.  */
  99. const getLastNonEmptyRow_ = (sheet, column) => {
  100.   const data = sheet.getRange(1, column, sheet.getLastRow()).getValues();
  101.   for (let i = data.length - 1; i >= 0; i--) {
  102.     if (data[i][0] !== "") {
  103.       return i + 1;
  104.     }
  105.   }
  106.   return 0;
  107. };
  108.  
  109. /**
  110.  * Checks if a row is empty.
  111.  *
  112.  * @param {Array} row - The row to check.
  113.  * @return {boolean} True if the row is empty, false otherwise.
  114.  */
  115. const isRowEmpty_ = (row) => row.every((cell) => cell === "");
  116.  
  117. /**
  118.  * Gets the column index from a letter.
  119.  *
  120.  * @param {string} columnLetter - The column letter (e.g., 'A').
  121.  * @return {number} The index of the column (0-based).
  122.  */
  123. const getColumnIndex_ = (columnLetter) =>
  124.   columnLetter.toUpperCase().charCodeAt(0) - 65;
  125.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement