簡體   English   中英

AppScript Google Sheets:將結賬表中的序列號匹配到主表,然后更新主表中的單元格

[英]AppScript Google Sheets: Match Serial #s from checkout sheet to the main sheet then update cells in main sheet

我對腳本編寫相當陌生,而且我已經因為這樣做而耗盡了我的大腦。 我已經嘗試尋找答案數周了,但我的腳本仍然沒有按照我的意圖去做。

為清楚起見,此表將用作簡單的結帳和庫存系統,在結帳時,收銀員將填寫產品的序列號,然后使用 vlookup 功能返回詳細信息,例如價格、項目名稱、類別、可用性. 這已經設置並且正在工作。

我遇到的問題是,在結帳付款時,收銀員需要更新主要的“庫存”表列,其中包含詳細信息,例如客戶名稱、購買日期、收銀員姓名、付款方式,以及將狀態從“可用”更新為“賣。” 目前,這些都是手動完成的,太耗時了。 我認為這可以使用腳本來實現,收銀員只需單擊一個按鈕,然后啟動腳本來更新主庫存表。

我已經閱讀了無數關於如何解決這個問題並啟動了一個腳本 (updateInventory) 但問題在於:

  1. 未能更新適當的單元格
  2. 由於執行時間超過 5-6 分鍾,這是 Google 對腳本的時間限制,所以它花費的時間太長,而且腳本通常會終止。 原始工作表有 > 5000 行,但我相信通過使用數組或對象並應用腳本優化這不會成為問題,但我真的不知道如何正確使用它們。

我在此處提供了一份原始工作表的副本,其中包含已編輯的字段和詳細信息。 https://docs.google.com/spreadsheets/d/16hWouvaOZ6R5pGZCPm6wYyeFHmSljvMr9hG9zhbFrTQ/edit#gid=2121597849請注意,大多數列都被隱藏了,因為它無關緊要,但我沒有盡可能地刪除它們來表示原始列。

這也是我一直在努力並不斷失敗的腳本:

function updateInventory() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh1 = ss.getSheetByName('OUT');
  var sh2 = ss.getSheetByName('INventory');
  var sh1rg = sh1.getRange(7,4,sh1.getLastRow(),1);
  var sh2rg = sh2.getRange(3,11,sh2.getLastRow(),1);
  var sh1sn = sh1rg.getValues();
  var sh2sn = sh2rg.getValues();
  var clientrg = sh1.getRange(1,3); 
  var client = clientrg.getValue();
  var cashierrg = sh1.getRange(38,4);
  var cashier = cashierrg.getValue();
  var daterg = sh1.getRange(2,3)
  var date = daterg.getValue ()
  var paymentrg = sh1.getRange(3,3)
  var payment = daterg.getValue ()
  for(var i=0;i<sh2sn.length-1;i++){
    for(var j=0;j<sh1sn.length;j++) {
      if(sh2sn[i][0] == sh1sn[j][0]) {
      sh2.getRange(i+2,31).setValue(date)
      sh2.getRange(i+2,23).setValue("Sold");
      sh2.getRange(i+2,35).setValue(cashier);
      sh2.getRange(i+2,30).setValue(client);
      sh2.getRange(i+2,33).setValue("YES");
      sh2.getRange(i+2,34).setValue(payment);
        break
      }
    }
  }
}

我真的希望有人能幫助我。

這個改裝怎么樣?

改裝要點:

  • 在您的示例腳本,似乎在片材中的值INventory從3行,但在你的腳本開始, sh2.getRange(i+2,31)被使用。 在您的腳本中,由於數據驗證規則,第 2 行出現錯誤。
  • 在您的問題中,您將update status from "Available" to "Sold." “STATUS”欄是“R”欄。 但是在您的腳本中,“Solid”被放置在“W”列中。
    • 我認為這些可能是你的第一個問題的原因。
  • 並且,循環中的每一行都使用setValue
    • 我認為這可能是您的第二個問題的原因。
  • 在您的目標中, "Sold",client,date,"YES",payment,cashier的值似乎分別放在R,AD,AE,AG,AH,AI的不連續 6 列中。 所以在這種情況下,我想建議使用范圍列表來放置值。

當以上幾點反映到你的腳本中時,它變成如下。

修改后的腳本:

從:
 for(var i=0;i<sh2sn.length-1;i++){ for(var j=0;j<sh1sn.length;j++) { if(sh2sn[i][0] == sh1sn[j][0]) { sh2.getRange(i+2,31).setValue(date) sh2.getRange(i+2,23).setValue("Sold"); sh2.getRange(i+2,35).setValue(cashier); sh2.getRange(i+2,30).setValue(client); sh2.getRange(i+2,33).setValue("YES"); sh2.getRange(i+2,34).setValue(payment); break } } }
到:
 var objFromOUT = sh1sn.reduce((o, [d]) => { if (d.toString() != "") o[d] = true; return o; }, {}); var putValues = { R: {ranges: [], value: "Sold"}, AD: {ranges: [], value: client}, AE: {ranges: [], value: date}, AG: {ranges: [], value: "YES"}, AH: {ranges: [], value: payment}, AI: {ranges: [], value: cashier}, }; sh2sn.forEach(([v], i) => { if (v.toString() != "" && objFromOUT[v]) { Object.keys(putValues).forEach(k => putValues[k].ranges.push(`${k}${i + 3}`)); } }); Object.entries(putValues).forEach(([_,v]) => sh2.getRangeList(v.ranges).setValue(v.value));
  • 在這個修改后的腳本中,您可以調整 put 值和putValues的列。 例如,在當前階段, R: {ranges: [], value: "Sold"}表示將"Solid"值放入“R”列。

參考:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM