制定涉及嵌套 IF 的 GSheets 公式
Formulate GSheets formula involving nested IFs
我为我们的小型企业创建了一个 Google 电子表格,其中列出了所有发票。我上传了一个简化的格式
https://docs.google.com/spreadsheets/d/1zYrRxDm0ahsjWE8aNquz-shHuNY_Eifl3lXLhIBUeTE/edit?usp=sharing.
1.There 每张发票可以是 1-5 个产品。
2.The G 列是该发票中所有产品的总和。我想为此列创建一个公式。
目前,我的公式很长而且效率低下。
列 (G) 使用此公式计算产品数量:
=IF(B3<>"",IF(OFFSET(B3,1,0)="",IF(OFFSET(B3,2,0)="",if(OFFSET(B3,3,0)="",if(OFFSET(B3,4,0)="",if(OFFSET(B3,5,0)="",5,5),4),3),2),1),0)
另一列 (H) 总结了产品价值:=IF(G3>0,SUM(OFFSET(D3,0,0,G3,1)),"")
帮我修改一下计算产品数量的G列公式。如果有任何方法可以合并 G 和 H,那也很棒。
注意:(I) 列只是 (H) 列的替代。
P.S。请不要将此标记为基于意见的问题。这纯粹是一道解题题。
如果您能够使用 VBA,您可以使用用户定义函数。将此代码插入新模块并像调用普通 excel 函数一样调用它:
Public Function InvoiceDetail(Invoice As Range, ReturnType As Integer)
Dim varCount As Long
Dim varSheet As Worksheet
Dim varInvoiceID As String
Dim varPartyName As String
Dim varInvoiceTotal As Double
Dim varInvoiceCount As Integer
Set varSheet = ThisWorkbook.Sheets(Invoice.Parent.Name)
If varSheet.Range("A" & Invoice.Row).Value <> "" Then
varInvoiceID = varSheet.Range("A" & Invoice.Row).Value
varPartyName = varSheet.Range("B" & Invoice.Row).Value
For varCount = Invoice.Row To 1000000
If varSheet.Range("D" & varCount).Value = "" Then
Exit For
End If
If varInvoiceID = varSheet.Range("A" & varCount).Value And varPartyName = varSheet.Range("B" & varCount).Value Then
varInvoiceTotal = varInvoiceTotal + varSheet.Range("D" & varCount).Value
varInvoiceCount = varInvoiceCount + 1
ElseIf varSheet.Range("A" & varCount).Value = "" And varSheet.Range("B" & varCount).Value = "" Then
varInvoiceTotal = varInvoiceTotal + varSheet.Range("D" & varCount).Value
varInvoiceCount = varInvoiceCount + 1
Else
Exit For
End If
Next
End If
Set varSheet = Nothing
Select Case ReturnType
Case 1 '// Count Only
InvoiceDetail = varInvoiceCount
Case 2 '// Total Only
InvoiceDetail = varInvoiceTotal
Case 3 '// Total [Count]
InvoiceDetail = varInvoiceTotal & " [" & varInvoiceCount & "]"
Case Else
InvoiceDetail = "Error"
End Select
End Function
此代码显然假定您的发票 ID 在 A 列中,您的合作伙伴名称在 B 列中,您的金额在 D 列中。我也为您实现了一些选项:
=InvoiceDetail(A3,1)
returns 发票上的项目数(整数)
=InvoiceDetail(A3,2)
returns发票上的项目总和(双倍)
=InvoiceDetail(A3,3)
returns 总和和 [计数](作为字符串)
既然您可以选择将辅助列放在一边或隐藏,我们可以执行以下操作。
在从第 3 行开始的 K 列中,我放置了这个公式:
=IF(A3<>"",A3,K2)
您实际上可以使用您记得的任何适合的列来更新后续公式中的列引用。它生成一列没有空格的发票编号,这使得其他一些公式对我们来说更容易工作。
在第 3 行开始的 L 列中,我放置了这个公式:
IF(COUNTIF($K:K3,K3)=1,COUNTIF(K:K,K3),0)
这给出了与 G 列相同的结果。IF 语句的第一部分是检查发票编号是否是发票编号的第一次出现。如果是统计发票号出现的次数,否则显示0。
现在如果您想跳过计算发票中有多少项目,您可以使用 sumproduct 公式,如下所示:
=IF(A3<>"",SUMPRODUCT(($K:$K=A3)*$D:$D),"")
现在,为了计算可变大小的发票列表,我们将计算发票数量并调整我们的公式,并将偏移量调整到 return 适当的范围,如下所示:
=IF(A3<>"",SUMPRODUCT((OFFSET($K,0,0,COUNT(K:K),1)=A3)*OFFSET($D,0,0,COUNT(K:K),1)),"")
由于我们使用的是 COUNT(K:K),因此除了由我们的公式生成的数字外,不得在此列中输入任何数字。
这会将括号内的项目视为一个数组,而不是公式本身是一个数组。整个内容都放在 IF 语句中,以便在与 A 列中的发票编号不对应的行中显示空单元格而不是零。
现在,如果您想了解 sumproduct 在这种情况下的工作原理,它基本上会生成一个用 1 或 0 表示 true 或 false 的数组,然后将它乘以一个大小相同的数组,该数组包含您所有的金额。所以乘以 0 的任何东西都是 0,乘以 1 的任何东西都是数量。 sumproduct 的最后一步是将所有值相加。所以你只会得到真实或 1 的总和。
我用 2 个数组公式解决了这个问题。
将此公式粘贴到任何相应的单元格中,设为 O3
:
=TRANSPOSE(SPLIT(JOIN("",ArrayFormula(REPT(FILTER(A3:A12,A3:A12>0)&"-",
len(TRANSPOSE(SPLIT(REGEXREPLACE(JOIN(",",A3:A12)&",","\d+","-"),"-")))))),"-"))
单元格 P3
中的这个公式:
=ArrayFormula(if(A3:A>0,SUMIF(O3:O,O3:O,D3:D),""))
我的sample file.
要使第一个公式适用于不同的范围:
- 将
A3:A12
替换为offset(A3,,,counta(C3:C))
我为我们的小型企业创建了一个 Google 电子表格,其中列出了所有发票。我上传了一个简化的格式 https://docs.google.com/spreadsheets/d/1zYrRxDm0ahsjWE8aNquz-shHuNY_Eifl3lXLhIBUeTE/edit?usp=sharing.
1.There 每张发票可以是 1-5 个产品。
2.The G 列是该发票中所有产品的总和。我想为此列创建一个公式。
目前,我的公式很长而且效率低下。 列 (G) 使用此公式计算产品数量:
=IF(B3<>"",IF(OFFSET(B3,1,0)="",IF(OFFSET(B3,2,0)="",if(OFFSET(B3,3,0)="",if(OFFSET(B3,4,0)="",if(OFFSET(B3,5,0)="",5,5),4),3),2),1),0)
另一列 (H) 总结了产品价值:=IF(G3>0,SUM(OFFSET(D3,0,0,G3,1)),"")
帮我修改一下计算产品数量的G列公式。如果有任何方法可以合并 G 和 H,那也很棒。
注意:(I) 列只是 (H) 列的替代。
P.S。请不要将此标记为基于意见的问题。这纯粹是一道解题题。
如果您能够使用 VBA,您可以使用用户定义函数。将此代码插入新模块并像调用普通 excel 函数一样调用它:
Public Function InvoiceDetail(Invoice As Range, ReturnType As Integer)
Dim varCount As Long
Dim varSheet As Worksheet
Dim varInvoiceID As String
Dim varPartyName As String
Dim varInvoiceTotal As Double
Dim varInvoiceCount As Integer
Set varSheet = ThisWorkbook.Sheets(Invoice.Parent.Name)
If varSheet.Range("A" & Invoice.Row).Value <> "" Then
varInvoiceID = varSheet.Range("A" & Invoice.Row).Value
varPartyName = varSheet.Range("B" & Invoice.Row).Value
For varCount = Invoice.Row To 1000000
If varSheet.Range("D" & varCount).Value = "" Then
Exit For
End If
If varInvoiceID = varSheet.Range("A" & varCount).Value And varPartyName = varSheet.Range("B" & varCount).Value Then
varInvoiceTotal = varInvoiceTotal + varSheet.Range("D" & varCount).Value
varInvoiceCount = varInvoiceCount + 1
ElseIf varSheet.Range("A" & varCount).Value = "" And varSheet.Range("B" & varCount).Value = "" Then
varInvoiceTotal = varInvoiceTotal + varSheet.Range("D" & varCount).Value
varInvoiceCount = varInvoiceCount + 1
Else
Exit For
End If
Next
End If
Set varSheet = Nothing
Select Case ReturnType
Case 1 '// Count Only
InvoiceDetail = varInvoiceCount
Case 2 '// Total Only
InvoiceDetail = varInvoiceTotal
Case 3 '// Total [Count]
InvoiceDetail = varInvoiceTotal & " [" & varInvoiceCount & "]"
Case Else
InvoiceDetail = "Error"
End Select
End Function
此代码显然假定您的发票 ID 在 A 列中,您的合作伙伴名称在 B 列中,您的金额在 D 列中。我也为您实现了一些选项:
=InvoiceDetail(A3,1)
returns 发票上的项目数(整数)
=InvoiceDetail(A3,2)
returns发票上的项目总和(双倍)
=InvoiceDetail(A3,3)
returns 总和和 [计数](作为字符串)
既然您可以选择将辅助列放在一边或隐藏,我们可以执行以下操作。
在从第 3 行开始的 K 列中,我放置了这个公式:
=IF(A3<>"",A3,K2)
您实际上可以使用您记得的任何适合的列来更新后续公式中的列引用。它生成一列没有空格的发票编号,这使得其他一些公式对我们来说更容易工作。
在第 3 行开始的 L 列中,我放置了这个公式:
IF(COUNTIF($K:K3,K3)=1,COUNTIF(K:K,K3),0)
这给出了与 G 列相同的结果。IF 语句的第一部分是检查发票编号是否是发票编号的第一次出现。如果是统计发票号出现的次数,否则显示0。
现在如果您想跳过计算发票中有多少项目,您可以使用 sumproduct 公式,如下所示:
=IF(A3<>"",SUMPRODUCT(($K:$K=A3)*$D:$D),"")
现在,为了计算可变大小的发票列表,我们将计算发票数量并调整我们的公式,并将偏移量调整到 return 适当的范围,如下所示:
=IF(A3<>"",SUMPRODUCT((OFFSET($K,0,0,COUNT(K:K),1)=A3)*OFFSET($D,0,0,COUNT(K:K),1)),"")
由于我们使用的是 COUNT(K:K),因此除了由我们的公式生成的数字外,不得在此列中输入任何数字。
这会将括号内的项目视为一个数组,而不是公式本身是一个数组。整个内容都放在 IF 语句中,以便在与 A 列中的发票编号不对应的行中显示空单元格而不是零。
现在,如果您想了解 sumproduct 在这种情况下的工作原理,它基本上会生成一个用 1 或 0 表示 true 或 false 的数组,然后将它乘以一个大小相同的数组,该数组包含您所有的金额。所以乘以 0 的任何东西都是 0,乘以 1 的任何东西都是数量。 sumproduct 的最后一步是将所有值相加。所以你只会得到真实或 1 的总和。
我用 2 个数组公式解决了这个问题。
将此公式粘贴到任何相应的单元格中,设为 O3
:
=TRANSPOSE(SPLIT(JOIN("",ArrayFormula(REPT(FILTER(A3:A12,A3:A12>0)&"-",
len(TRANSPOSE(SPLIT(REGEXREPLACE(JOIN(",",A3:A12)&",","\d+","-"),"-")))))),"-"))
单元格 P3
中的这个公式:
=ArrayFormula(if(A3:A>0,SUMIF(O3:O,O3:O,D3:D),""))
我的sample file.
要使第一个公式适用于不同的范围:
- 将
A3:A12
替换为offset(A3,,,counta(C3:C))