Google sheets 如何获取与Google工作表上2列中的值匹配的最后一行

Google sheets 如何获取与Google工作表上2列中的值匹配的最后一行,google-sheets,google-sheets-formula,Google Sheets,Google Sheets Formula,我有一个交易表,其中包含每次购买物品的交易。最新交易将包含购买该商品后在该商品上花费的总金额 我想创建一个基于(每天)项目的时间花费金额图表。我使用以下公式来获取项目最新事务的行号 ARRAYFORMULA(最大值(如果(事务!$B:$B=“Apple”,行(事务!$B:$B),-1))-->返回6 但我似乎无法添加到这个公式中,以获取基于项目的最新行,以及日期是否小于或等于图表日期 交易表 1. 日期 项目 数量 上。花费 咖喱。花费 2. 2020年1月1日 苹果 $10 $0 $10 3.

我有一个交易表,其中包含每次购买物品的交易。最新交易将包含购买该商品后在该商品上花费的总金额

我想创建一个基于(每天)项目的时间花费金额图表。我使用以下公式来获取项目最新事务的行号

ARRAYFORMULA(最大值(如果(事务!$B:$B=“Apple”,行(事务!$B:$B),-1))-->返回6

但我似乎无法添加到这个公式中,以获取基于项目的最新行,以及日期是否小于或等于图表日期

交易表

1. 日期 项目 数量 上。花费 咖喱。花费 2. 2020年1月1日 苹果 $10 $0 $10 3. 2020年1月1日 香蕉 $12 $0 $12 4. 2020年1月2日 玉米 $3 $0 $3 5. 2020年1月2日 香蕉 $5 $12 $17 6. 2020年1月3日 苹果 $50 $10 $60 7. 2020年1月5日 香蕉 $23 $17 $40
我可以提供两个阶段的公式

  • 交易
    选项卡:
  • Pivot
    选项卡,单元格
    A1
  • =query({Transactions!A:F},“选择Col2,max(Col4),其中Col1不是null,按Col2 pivot Col3分组”,1)

  • ChartData
    选项卡,单元格
    A1
  • =数组公式(
    数组约束(
    {Pivot!A1:D1;
    (顺序(最大(行(Pivot!A:A))-1,1,最小(事务!$B:$B)),
    
    sumif(row(Pivot!B2:B),“为了用简单的公式解决您的问题,我将使用
    sumifs
    函数:

    =sumifs($D:$D,$C:$C,I$15,$B:$B,$H17)+I16
    
    以下是Gsheet数据的外观:


    您可以通过在Google Apps中创建的脚本来实现这一点。要实现这一点,请执行以下步骤:

    • 在电子表格中,选择工具>脚本编辑器打开绑定到文件的脚本
    • 在脚本编辑器中复制此函数,并保存项目(有关函数正在执行的操作的更多信息,请查看内联注释):
    函数可获取(值){
    让times=values.map(row=>row[0].getTime());
    const minTime=Math.min(…次);//获取系列的第一天
    const maxTime=Math.max(…次);//获取序列中的最后一天
    times=getTimes(minTime,maxTime);//获取最小值和最大值之间的所有天数
    const items=[…新集合(values.map(row=>row[1]))];//获取项目的唯一列表
    让targetValues=[[“日期”,…项]];//标题行
    for(让i=0;irow[0].getTime()==time);//获取当天的行
    如果(天行){
    const rowValues=items.map((item,j)=>{//循环遍历日行中的所有项目
    const foundRow=dayRows.find(row=>row[1]==item);//查找与日期和项目对应的行
    const previous=i==0?0:targetValues[targetValues.length-1][j+1];//上一行中的值
    如果(foundRow)返回foundRow[2]+上一个;
    否则返回0+previous;
    });
    push([新日期(时间),…行值]);
    }else{//如果源数据中没有日期,则值与前一行相同
    push([new Date(time),…targetValues[targetValues.length-1].slice(1)];
    }
    }
    返回目标值;
    }
    函数getTimes(minTime、maxTime){
    让allTimes=[minTime];
    让currentTime=minTime;
    while(当前时间<最大时间){
    let date=新日期(当前时间);
    date.setDate(date.getDate()+1);
    currentTime=date.getTime();
    allTimes.push(当前时间);
    }
    随时返回;
    }
    
    • 现在,如果返回到电子表格,您可以使用函数
      getTable
      ,就像使用常规表格公式一样。您只需提供适当的范围作为参数(在本例中为
      A2:E7
      ),如下所示:

    参考:

    你愿意使用应用程序脚本吗?是的,我不介意。谢谢!我没有想到这一点!这非常有效欢迎,只要你觉得它简单易懂:)
    =sumifs($D:$D,$C:$C,I$15,$B:$B,$H17)+I16
    
    function getTable(values) {
      let times = values.map(row => row[0].getTime());
      const minTime = Math.min(...times); // Get first day in series
      const maxTime = Math.max(...times); // Get last day in series
      times = getTimes(minTime, maxTime); // Get all days between minimum and maximum
      const items = [...new Set(values.map(row => row[1]))]; // Get unique list of items
      let targetValues = [["Date", ...items]]; // Header row
      for (let i = 0; i < times.length; i++) { // Loop through all days
        const time = times[i];
        const dayRows = values.filter(row => row[0].getTime() === time); // Get rows with this day
        if (dayRows) {
          const rowValues = items.map((item, j) => { // Loop through all items in day rows
            const foundRow = dayRows.find(row => row[1] === item); // Find row corresponding to day and item
            const previous = i === 0 ? 0 : targetValues[targetValues.length - 1][j + 1]; // Value in previous row
            if (foundRow) return foundRow[2] + previous;
            else return 0 + previous;
          });
          targetValues.push([new Date(time), ...rowValues]);
        } else { // If day is not in source data, values are the same than previous row
          targetValues.push([new Date(time), ...targetValues[targetValues.length - 1].slice(1)]);
        }
      }
      return targetValues;
    }
    
    function getTimes(minTime, maxTime) {
      let allTimes = [minTime];
      let currentTime = minTime;
      while (currentTime < maxTime) {
        let date = new Date(currentTime);
        date.setDate(date.getDate() + 1);
        currentTime = date.getTime();
        allTimes.push(currentTime);
      }
      return allTimes;
    }