-1

Combine Data from Worksheets Into A Master Orders Sheet

Hi all, We use a Google Sheet to track our online orders, storing the orders from each marketplace in their own sheet within the same workbook. Currently, we have 3 worksheets: ebay, etsy and amazon. There are external scripts that run throughout the day inserting records into each respective worksheet as the orders come in.

We manually transfer the the order records into a single master worksheet called "GI Orders". From there, we have an internal workflow that occurs in which We setup "jobs" for each order, record the job number(s) for a given order in the spreadsheet, and mark it as done, once processed.

These manual inputs are ONY done on the master GI Orders worksheet, per record, and are recorded in columns A:C, everything from Col D is just data.

Copying records easy because all the sheets have identical columns. The difficulty is in figuring out which orders were already copied over to the master vs which ones are new (inserted after the last copy/paste operation). I also do not know how to programmatically store/handle which records were already copied, and thus can be skipped over during the next script execution.

Our Goal

  • Automate the manual transfer of data from the 3 data feed worksheets into the master GI Orders worksheet.
  • Repeat the process automatically whenever new rows are added into any of the feed sheets, or copy over new records (delta) at regular intervals (e.g., hourly), adding them to the bottom of sheet so as to not overwrite any existing records.

Many, many thanks in advance for all your assistance!

Link To Sheet

TD Media
  • 3
  • 3
  • Hi, basically, we have data that comes in to 1 of 3 worksheets. Either "Amazon - DataAutomation Feed", "eBay - Shipstation" or "Etsy - Shipstation". This happens many times per day as new orders come in. We manually copy the new orders data from each sheet and paste it into the GI Orders sheet. We need to automate this -- getting new records from these sheets and inserting them into the GI Orders Sheet, as new rows at bottom of the sheet. – TD Media May 21 '23 at 00:09
  • I am sorry, but can you please clarify which part doesn't make sense? Basically: From 3 Source Sheets, copy records; & paste records into GI Orders sheet. - Repeat. Copy new rows only (no duplicates). – TD Media May 21 '23 at 01:03
  • `There are external scripts that run throughout the day inserting records into each respective worksheet as the orders come in.` Though you want to update your consolidated records _as orders are received_, external scripts don't trigger internal scripts. The best that you could do would be to use a time-driven script. On a tangent, what have you done/tried to resolve this problem yourself? I know you said `I also do not know how to programmatically store/handle which records were already copied`, but what has your research shown? – Tedinoz May 21 '23 at 01:08
  • The external scripts are independent of this request and are already in place. They are neither affected nor influenced by this process. I shared that info in order to provide a more complete picture of the process. They will continue to input data into the 3 respective data sheets. What I found: script to copy like: this:https://stackoverflow.com/questions/44967086/copy-data-from-one-sheet-to-another-in-google-app-script-and-append-a-row-one-s. What I don't know: a) how to copy only new records (not yet in master); b) copy data A:BA from source sheets & paste into cols D:BE in GI Orders. – TD Media May 21 '23 at 01:19
  • @Tedinoz, yes, a time-driven script, such as one that runs every hour would be perfect. The part I am totally lost at is essentially, once the script runs at hour 0, and copies all the records, for example, how to ensure that when it runs again at hour 1, that the script only copies records that were added since its last execution? That is, only copy records added between hour 0 and 1. I hope this makes sense. – TD Media May 21 '23 at 01:23
  • OK. So you want to avoid duplicates. No worries. What data field or fields in an order can be used to identify a duplicate? – Tedinoz May 21 '23 at 01:47
  • @Tedinoz thank you. I think we can key on cols A & X (Order Number & Item Listing SKU), together. – TD Media May 21 '23 at 02:07
  • `Order Number & Item Listing SKU` Please supply some examples of each. – Tedinoz May 21 '23 at 02:14
  • @Tedinoz Sorry, I should've also said that there is sample data in my sheet from each marketplace. And taking a closer look at it, because item listing sku is not present in each sheet, it would be better to use Order Number & Item Master SKU (cols A & Y in each data sheet). Sample order number: "112-1236327-8737026" & Sample Item Master SKU: "Whiskey-Decanter-Two-Glasses"; (ignore quotation marks). – TD Media May 21 '23 at 02:30
  • @Tedinoz several order numbers: 25-10049-85497; 27-10054-45673; 11-10062-29119; 111-3316925-4797052; 112-0395655-2562658; 112-2352509-3811455; several Item Master SKUs: Whiskey-One-Glass; Wine-Glass-Stemless-Custom-Text; Whiskey-Decanter; Whiskey-Decanter-Four-Glasses; Champagne-Flutes-Two-Glasses Shot-Glasses-Custom-Designs-2-Pack; Whiskey-Decanter; – TD Media May 21 '23 at 02:35

1 Answers1

0

You have 3 external sheets containing order information. The data from the external sheets is imported into three separate sheets in a master spreadsheet.

As new orders are imported, you want to copy the data from each of the three "import" sheets and combine it on a fourth sheet "Gi Orders". However, you need to ensure that you don't create duplicate entries on "GI Orders".

A duplicate transaction can be identified if the combination of the "Order Number" and "SKU" are found to be duplicated on "GI Orders".


function updateOrders(){
  var ss = SpreadsheetApp.getActiveSpreadsheet()
  // create an array of the sheet names in this spreadsheet
  var source = ["ebay","etsy","amazon"]

  // get the GI Orders data
  var giOrders = ss.getSheetByName("GI Orders")
  var giOrdersData = giOrders.getDataRange().getValues()
  
  // get a 1D array of the order nuimbers and remove the header row
  var giorders = giOrdersData.map(function(e){return e[1]})
  giorders.splice(0,1);

  // get a 1D array of the SKU and remove the header row
  var gisku = giOrdersData.map(function(e){return e[24]})
  gisku.splice(0,1);

  // create an array to hold the combined order#/SKU
  var giArray = new Array
  for (var i=0;i<giorders.length;i++){
    var gikey =giorders[i]+gisku[i]
    // Logger.log("DDEBUG: source = GI Orders , i="+i+", order = "+orders[i]+", sku = "+sku[i]+", key = "+key)
    giArray.push(gikey)
  }

  // get the transaction data
  // create an array to hold any non-duplicate transactions
  var cleanTrans = new Array

  // loop through the sheets
  for (var s = 0;s<source.length;s++){
    var sourceSheet = ss.getSheetByName(source[s])

    // get transaction data
    var transData = sourceSheet.getDataRange().getValues()

    // get a 1D array of Orders and remove the header row
    var orders = transData.map(function(e){return e[0]})
    orders.splice(0,1);

    // get a 1D array of SKU and remove the header row
    var sku = transData.map(function(e){return e[23]})
    sku.splice(0,1);

    // loop through the order/sku  
    for (var i=0;i<orders.length;i++){
      // combine the order and sku
      var key = orders[i]+sku[i]
      // Logger.log("DEBUG: source = "+source[s]+", i="+i+", order = "+orders[i]+", sku = "+sku[i]+", key = "+key)

      // is the combined order#/sku in GI Orders?
      // indexOf returns -1 if there is no match
      var idx = giArray.indexOf(key);

      if (idx == -1){
        // no match found, so add to gi Orders
        // Logger.log("DEBUG: no match "+key+" result = "+idx)
        // add the source to the array
        transData[(i+1)].unshift(source[s])
        cleanTrans.push(transData[(i+1)])
      }
      else{
        // do nothing
        // Logger.log("DEBUG: match found:  "+key+" result = "+idx)
      }
    }
    // Logger.log(cleanTrans) // DEBUG
    // Logger.log("DEBUG: source = "+source[s]+", numbers of transactions = "+ cleanTrans.length) 
  } // end of transactions loop

  // if any new Trans, then append to giOrders
  if (cleanTrans.length >0){
    var giLR = giOrders.getLastRow()
    giOrders.getRange(giLR+1,1,cleanTrans.length,25).setValues(cleanTrans)
  }
}


Sample GI Orders - BEFORE consolidation before

Sample GI Orders - AFTER consolidation enter image description here

Sample Imported Orders - eBay

ebay

Sample Imported Orders - etsy

etsy

Sample Imported Orders - amazon

amazon

Tedinoz
  • 5,911
  • 3
  • 25
  • 35
  • THANK YOU SO MUCH @tedinoz!! I was able to make the adjustments I needed for my dataset and this worked perfectly – TD Media May 22 '23 at 00:12
  • I am seeing though that we're picking up duplicates. If the script is keying on order number and order sku, shouldn't it be filtering out dupes that exist within the source data? As an example, if you look at the ebay data sheet, the first two rows are dupes (and definitely so by order number and order sku), but the script still pulls it in twice, as 2 records, into GI Orders. – TD Media May 22 '23 at 00:38
  • This is why we ask the OP for an example of the expected outcome. In the absense of this, it appears that I have/may have misunderstood you. You said `we can key on cols A & X (Order Number & Item Listing SKU), together`. I undertood this to mean that the key was the **combination** of Order and SKU. This made sense to me because (_I thought_) a customer might order many things on a single order number. The key for line #1 = "12-345678-01234Whiskey-Glass", line#2 = "12-345678-01234Port-Glass". The two keys are different so one is not a duplicate of the other (or so I understood). – Tedinoz May 22 '23 at 01:23
  • `In order to correctly understand your question, can you provide the sample input and output situations you expect?` Perhaps you are content to modify the code to suit your conditions, otherwise would you please edit your question to provide "the sample input and output situations you expect". – Tedinoz May 22 '23 at 01:24