Synchronize independent spreadsheet rows, filled by IMPORTRANGE()

后端 未结 2 1227
春和景丽
春和景丽 2020-12-01 15:43

I need to synchronize the contents of 2 spreadsheets that reference each other, keeping their rows in sync if a new row is added in one of the sheets.

I\'ve got 2 sp

2条回答
  •  甜味超标
    2020-12-01 16:10

    This is a classic problem in database design; how to associate information in two tables. The usual solution is to use key data; one or more columns that exist in both tables and provide a unique identifier, or key, to associate rows.

    We can adapt that idea to your situation, with a script that will adjust the location of rows in Spreadsheet 2 to synchronize with Spreadsheet 1. To do that, we need to identify a key - say the Name column - which must exist in both spreadsheets.

    This entails a small change in spreadsheet 2, where a Name column will now appear in column G, following the imported range in columns A-F.

        A      B             C            D       E         F        G         H           I           J
    | Name | Price | est delivery time | qty | etc. of | an item | Name  | order date | delivered | blah blah |
     < - - - - - - - - - - - -  Imported  - - - - - - - - - - - >  *KEY*  < - - - - - -  sheet 2  - - - - - >
    

    Demo

    Here's how that would look in action! This example is using two sheets in the same spreadsheet, just for convenience. In the demo, a new "Item" row is added in the middle of sheet 1, which automatically appears on sheet 2 thanks to the =IMPORTRANGE() function. The synchronizing function is running on a 1-minute timed Trigger, and you'll see it move things around about 20 seconds in.

    You can grab a copy of the spreadsheet + embedded script here.

    Code

    /**
     * Call syncTables() with the name of a key column.
     */
    function doSyncTables() {
      syncTables( "Name" );
    }
    
    /*
     * Sync "Orders" spreadsheet with imported rows from "Items" spreadsheet.
     *
     * From: http://stackoverflow.com/a/33172975/1677912
     *
     * @param {String}  keyName    Column header used as key colum, appears
     *                             at start of "Orders" data, following
     *                             "Items" data.
     */
    function syncTables( keyName ) {
      var sheet2 = SpreadsheetApp.openById( sheetId2 ).getSheetByName('Orders');
    
      // Get data
      var lastCol = sheet2.getLastColumn();
      var lastRow = sheet2.getLastRow();      // Includes all rows, even blank, because of =importRange()
      var headers = sheet2.getRange(1, 1, 1, lastCol).getValues()[0];
      var keyCol = headers.lastIndexOf( keyName ) + 1;
      var itemKeys = sheet2.getSheetValues(1, 1, lastRow, 1).map(function(row) {return row[0]});
      var itemData = sheet2.getSheetValues(1, 1, lastRow, keyCol-1);
      var orderData = sheet2.getSheetValues(1, keyCol, lastRow, lastCol-keyCol+1);
    
      var ordersByKey = [];  // To keep track of orders by key
    
      // Scan keys in orderData
      for (var row=1; row

提交回复
热议问题