【问题标题】:Google Sheets App Script Add Value Cell Based on Date谷歌表格应用脚本根据日期添加值单元格
【发布时间】:2021-10-20 18:58:10
【问题描述】:

我有以下示例表,它使用了以下公式,有些工作。我说的有点是因为经常打开工作表,在对选项卡进行排序过滤后或有时在添加新行时,过滤器公式会出现错误。设置的值一旦最初设置就不会改变,所以我正在寻找一些帮助,让我开始使用一个应用脚本,如果相应单元格中的值为空白,该脚本将在打开时设置值。

由于上述错误,我想使用应用脚本之一,并且也有兴趣学习一下。我已经在其他平台上做了一些 js 工作,并且相信我可以在以下一项或一项的帮助下拨通这个

交易标签

    FILTER(text(B2:B,"MMMM"),Not(ISBLANK(B2:B)))
    FILTER(text(B2:B,"YYYY"),Not(ISBLANK(B2:B)))
    filter(if(E2:E < 0,"debit","credit"),not(ISBLANK(E2:E)))
    filter(VLOOKUP(D2:D,Lists!A:B,2,false),not(ISBLANK(B2:B)))

余额历史

   FILTER(text(B2:B,"MMMM"),Not(ISBLANK(B2:B)))
   FILTER(text(B2:B,"YYYY"),Not(ISBLANK(B2:B)))
   ARRAYFORMULA({"Date/Time"; B2:B+C2:C})

https://docs.google.com/spreadsheets/d/17SId7mIzO3hVOC36Nq40O0bjPS5YfGOX4wsMU1NlbCU/edit?usp=sharing

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    你可以参考这个示例代码:

    function onOpen() {
      updateTransactionsSheet();
      updateBalanceHistorySheet();
    }
    
    function updateTransactionsSheet() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var transactionSheet = ss.getSheetByName("Transactions");
      var transactionData = transactionSheet.getDataRange().getValues();
    
      var listsSheet = ss.getSheetByName("Lists");
      var listsData = listsSheet.getDataRange().getValues();
      var listsMap = {};
      for (var i = 1; i<listsData.length; i++) {
        var category = listsData[i][0];
        var group = listsData[i][1];
        if (!(category in listsMap)) {
          // Add category in the dictionary/javascript object
          listsMap[category] = group;
        }
      }
      Logger.log("Lists Map: "+JSON.stringify(listsMap));
    
      // Check each row data in the transaction sheet. Ignore header row
      var transactionResult = [];
      for (var i = 1; i < transactionData.length; i++) {
        var row = transactionData[i];
        var date = row[1]; // Get date value in column B (zero-based)
        var category = row[3] // Get category value in column D (zero-based)
        var amount = row[4] // Get amount value in column E (zero-based)
    
        var dateObj = new Date(date);
        var month = dateObj.toLocaleString('default', { month: 'long' });
        var year = dateObj.getFullYear().toString();
        var amountStr = amount < 0 ? "Debit" : "Credit";
        
        transactionResult.push([month, year, listsMap[category], amountStr])
      }
      Logger.log(transactionResult)
      // Write result in transaction sheet to column P (index 16 one-based) starting from row 2
      transactionSheet.getRange(2,16,transactionResult.length,transactionResult[0].length).setValues(transactionResult);
    }
    
    function updateBalanceHistorySheet() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var balanceSheet = ss.getSheetByName("BalanceHistory");
      var balanceData = balanceSheet.getDataRange().getValues();
      // Check each row data in the balance sheet. Ignore header row
      var balanceResult = [];
      for (var i = 1; i < balanceData.length; i++) {
        var row = balanceData[i];
        var date = row[1]; // Get date value in column B (zero-based)
        var time = row[2]; // Get date value in column C (zero-based)
        
        var dateObj = new Date(date);
        dateObj.setHours(time.getHours(),time.getMinutes(),0);
        var dateTimeStr = Utilities.formatDate(dateObj, Session.getScriptTimeZone(), "MM/dd/yyyy' 'HH:mm:ss");
        var month = dateObj.toLocaleString('default', { month: 'long' });
        var year = dateObj.getFullYear().toString();
    
        
        balanceResult.push([month, year, dateTimeStr])
      }
      Logger.log(balanceResult)
      //Write result in balance sheet to column M (index 13 one-based) starting from row 2
      balanceSheet.getRange(2,13,balanceResult.length,balanceResult[0].length).setValues(balanceResult);
    }
    

    它有什么作用?

    • 创建一个onOpen() simple trigger 并调用updateTransactionsSheet()updateBalanceHistorySheet() 来更新它们各自工作表的值
    • updateTransactionsSheet()。使用getActiveSpreadsheet() 获取当前活动的 srpeadsheet 对象。使用getSheetByName(name) 获取交易表对象。使用getDataRange() 获取事务表中的所有数据范围对象,然后使用getValues() 获取范围的值。它将返回一个二维值数组。
    • 循环每一行(跳过索引为 0 的标题行)并分别在column Bcolumn E 中获取date valueamount value
    • 使用您的date value 创建一个JavaScript date object,使用toLocalString() 获取您的日期对象的月份字符串。并使用 getFullYear() 获取日期对象的年份
    • 在当前行中获得必要的值后,使用array.push() 将数据添加到结果数组中。请注意,推送的值是一个数组[month, year, "", amountStr],这是要为 4 列(列 P 到 S)设置的当前行值。
    • 将值写入工作表。使用getRange(row, column, numRows, numColumns) 获取您要写入数据的范围。由于我们想从 P2:Q 开始对它进行修正,因此行开始将为 2,列开始将为 16,行数和列数将基于结果数组(这是一个二维数组)的大小。使用setValues(values)
    • updateBalanceHistorySheet() 完成了类似的过程

    输出:

    (更新)

    • 我更新了代码以在Transactions 表中包含Group 列值。我刚刚读取了Lists 表中的值并创建了一个JavaScript Object,其中A 列(类别)作为key,B 列(组)作为value。请参阅 listsMap 变量了解它的创建方式。
    • 然后我使用Transactions 工作表中当前行的类别来获取其在 JavaScript 对象中的等效组值。

    【讨论】:

    • 很酷,谢谢。我会在接下来的一两天内测试它!
    • 当然,如果您遇到一些问题,请告诉我。顺便说一句,如果我们回答了您的问题,请点击接受按钮。通过这样做,社区中可能与您有同样担忧的其他人将知道他们的问题可以得到解决。如果您无法使用接受按钮,请随时告诉我。 How to accept answer
    • Ron 这太棒了,感谢您提供如此详细的解释。一个跟进,我现在将其标记为已解决。然而,上面还有一个公式,我希望你能帮我看看它的应用程序脚本。在事务选项卡上有一个组列,它使用过滤器和 vLookup 来匹配来自事务选项卡的类别,并从列表选项卡返回组。如果你能帮助这个惊人的。再次非常感谢。过滤器(VLOOKUP(D2:D,Lists!A:B,2,false),not(ISBLANK(D2:D)))
    • 我更新了答案以包含 Group 列值
    • 好的,很好,从来没有真正使用过应用脚本,所以在那里学习了一下。我要修补一下。感谢您的指导。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    相关资源
    最近更新 更多