我为我们的小型企业创建了一个Google电子表格,其中列出了所有发票。我已经上传了一个简化的格式 https://docs.google.com/spreadsheets/d/1zYrRxDm0ahsjWE8aNquz-shHuNY_Eifl3lXLhIBUeTE/edit?usp=sharing
1.每张发票可以有1-5种产品。
2. 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。请不要将此标记为基于意见的问题。这纯粹是一个解决问题的问题。
答案 0 :(得分:0)
如果您能够使用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列,您的Party名称位于B列,您的金额位于D列。我也为您实施了一些选项:
=InvoiceDetail(A3,1)
返回发票上的项目数(以整数形式)
=InvoiceDetail(A3,2)
返回发票上的项目总和(为双倍)
=InvoiceDetail(A3,3)
返回sum和[count](作为字符串)
答案 1 :(得分:0)
由于您可以选择将辅助列放在一边或隐藏,我们可以执行以下操作。
在第3行开始的第K列中,我放置了这个公式:
=IF(A3<>"",A3,K2)
您实际上可以使用您记得的任何列来更新后续公式中的列引用。它生成一列没有空格的发票号,这使得其他一些公式对我们来说更容易。
在第3行的第一列中,我放置了这个公式:
IF(COUNTIF($K$3:K3,K3)=1,COUNTIF(K:K,K3),0)
这给出了与G列相同的结果.IFC声明的第一部分是检查发票号是否是发票号的第一次出现。如果计算发票编号发生的次数,则显示0。
现在,如果您想跳过发票中有多少项目,可以使用sumproduct公式,如下所示:
=IF(A3<>"",SUMPRODUCT(($K$3:$K$12=A3)*$D$3:$D$12),"")
现在考虑到可变大小的发票清单,我们将计算发票数量并使用偏移量调整我们的公式以返回适当的范围,如下所示:
=IF(A3<>"",SUMPRODUCT((OFFSET($K$3,0,0,COUNT(K:K),1)=A3)*OFFSET($D$3,0,0,COUNT(K:K),1)),"")
由于我们使用COUNT(K:K),因此除了我们的公式生成的数字之外,不必在此列中输入任何数字。
这会将括号内的项目视为数组,而公式本身不是数组。整个事情放在一个IF语句中,以便在与A列中的发票编号不对应的行中显示空单元格而不是零。
现在如果你想了解sumproduct在这种情况下是如何工作的,它基本上生成一个填充1或0表示true或false的数组,然后将它乘以一个填充了所有金额的相同大小的数组。所以乘以0的任何东西都是0,任何乘以1的东西都是数量。 sumproduct的最后一步是将所有值相加。因此,您只能得到真实的总和或1.
答案 2 :(得分:0)
我能用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))