【问题标题】:Sumproduct in VBA using tablesVBA 中的 Sumproduct 使用表
【发布时间】:2019-03-10 14:49:15
【问题描述】:

我定义了一个名为subtable 的表。我试图以比使用适当的单元格定义range 更动态的方式执行计算。 但是,下面的行抛出了compile error。我不确定我哪里出错了。

Set tbl = Sheets("ASF").ListObjects("tblASF")
tbl.Resize Range("A1:C1200")

Set ws = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "Test"
tbl.Range.Copy Destination:=ws.Range("C1")
Set subtable = Sheets("Test").ListObjects(1)

Dim rate As Long

Set ws = ActiveSheet
rate = Application.WorksheetFunction.SumProduct(--(Range("subtable[Tye]") = "Standard"), Range("subtable[Amount]"), Range("subtable[Rate]")) / Application.WorksheetFunction.SumIf(Range("subtable[Amount]"), "Standard")

【问题讨论】:

  • 嘿,我决定将此问题标记为“过于宽泛”。您的问题缺少 1)任何类型的示例,2)上下文的完整代码,3)确切的错误消息。没有它,我们只能猜测如何为您提供帮助
  • @Rawrplus 我同意这个问题缺少上下文,但是除了语法错误之外没有错误消息。整行以红色突出显示,没有说明编译器拒绝它的原因。
  • 我相信这应该是足够的信息了

标签: excel vba excel-formula


【解决方案1】:

我猜您在公式中使用“子表”(例如:Range("subtable[Tye]")...)来引用您在Set subtable = Sheets("Test").ListObjects(1) 中设置的subTable 对象变量指向的表,但它不是这样工作的

->您必须在“子表”之后实际命名

Set subtable = ws.ListObjects(1)
subtable.Name = "subtable" '<- name the table after "subtable"

那么您必须遵循@chillin 关于使用 SUMPRODUCT() 工作表函数的建议

最终的代码可能是:

Dim tbl As ListObject, subtable As ListObject
Dim ws As Worksheet

Set tbl = Sheets("ASF").ListObjects("tblASF")
tbl.Resize Range("A1:C1200")

Set ws = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "Test"
tbl.Range.Copy Destination:=ws.Range("C1")

Set subtable = ws.ListObjects(1)
subtable.Name = "subtable"

Dim rate As Long
rate = Application.Evaluate("SUMPRODUCT(--(subtable[Tye]=""Standard""),subtable[Amount],subtable[Rate])/SUMIF(subtable[Tye],""Standard"",subtable[Amount])")

顺便说一句,请注意 Dim rate As Long 会将任何低于 1 的 rate 削减为零

【讨论】:

  • 由于 vba 无法处理sumproduct(),您是否知道如何更动态地将我的条件引用为“标准”。例如,我创建了一个数组变量arr_type(1) = "Standard",但我不能简单地将这个数组变量替换为上面的 application.evaluate。我是否必须在 sumproduct 语句中评估 arr_type(1) 变量?
【解决方案2】:
  • 访问范围时使用Range("name of range here")(暂时忽略[] 语法糖)- 最好包括父工作簿和工作表名称(包含范围)。
  • 我认为您的公式有误。您没有为SUMIF 包含第三个参数,因此返回值将为零(这意味着即使您的代码在语法上有效,您也会得到除以0 的错误)。
  • 我认为您不能像在单元格中那样在 VBA 中使用SUMPRODUCT。更具体地说,在 VBA 中,您不能对数组 (--) 进行双重否定以将其转换为 1s 和 0s 的数组。相反,您必须手动循环遍历数组并将其转换为所需的数组(据我所知)。

您需要在分区中修正除数/分母(我已对其进行了更改以使我的示例正常工作)。

假设您的subtable 表在工作表"Sheet1" 上:

Option Explicit

Private Sub SumproductInVBA()

    With ThisWorkbook.Worksheets("Sheet1")

        Dim typeColumn As Variant
        typeColumn = .Range("subtable[Type]").Value2

        Dim rowIndex As Long
        For rowIndex = LBound(typeColumn, 1) To UBound(typeColumn, 1)
            If typeColumn(rowIndex, 1) = "Standard" Then
                typeColumn(rowIndex, 1) = 1
            Else
                typeColumn(rowIndex, 1) = 0
            End If
        Next rowIndex

        Dim someVariable As Double
        someVariable = Application.SumProduct(typeColumn, .Range("subtable[Amount]"), .Range("subtable[Rate]")) / Application.SumIf(.Range("subtable[Type]"), "Standard", .Range("subtable[Amount]"))

    End With

End Sub

或者,代替上述方法,一种更短但更慢的方法可能是:

someVariable = Application.Evaluate("SUMPRODUCT(--(subtable[Type]=""Standard""),subtable[Amount],subtable[Rate])/SUMIF(subtable[Type],""Standard"",subtable[Amount])")

以上对我有用。

【讨论】:

    【解决方案3】:

    两个问题:

    1) [ ] 不是在 VBA 中访问数组中元素的方法。相反,[x]Evaluate("x") 大致相同,因此subtable[Amount] 有点像subtable Evaluate("Amount"),这显然没有意义。

    2) Type 是保留字

    您没有提供足够的上下文来说明更多内容。

    【讨论】:

    • 感谢[],我尝试使用range 方法,但还是一样。 SumProduct(--(Range("subtable[Tye]") = "Standard"), Range("subtable[Amount]"), Range("subtable[Rate]"))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    相关资源
    最近更新 更多