Sumproduct в VBA с использованием таблиц - PullRequest
0 голосов
/ 10 марта 2019

enter image description here

Я определил таблицу с именем 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")

Ответы [ 3 ]

1 голос
/ 10 марта 2019
  • Используйте Range("name of range here") при доступе к диапазонам (пока игнорируете [] синтаксический сахар) - и лучше всего включать родительскую рабочую книгу и имя рабочей таблицы (которые содержат диапазон).
  • Я думаю, что в вашей формуле есть ошибка. Вы не включили третий аргумент для SUMIF, поэтому возвращаемое значение будет равно нулю (то есть вы получите ошибку деления на 0, даже если ваш код синтаксически допустим).
  • Я не думаю, что вы можете использовать SUMPRODUCT в VBA, как в клетке. В частности, в VBA вы не можете дважды отрицать массив (--), чтобы превратить его в массив 1 s и 0 s. Вместо этого вам нужно вручную зациклить массив и преобразовать его в нужный массив (насколько я знаю).

Вам нужно исправить свой делитель / знаменатель в вашем подразделении (я изменил его, чтобы мой пример работал).

Предполагается, что ваша таблица 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])")

Вышесказанное сработало для меня.

1 голос
/ 10 марта 2019

Я предполагаю, что вы используете "subtable" в формулах (например: Range("subtable[Tye]")...) для ссылки на таблицу, указанную вашей subTable переменной объекта, которую вы установили в 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 обрежет любое rate ниже 1 до нуля

0 голосов
/ 10 марта 2019

Две проблемы:

1) [ ] - это не способ доступа к элементам в массиве в VBA. Вместо этого [x] примерно такой же, как Evaluate("x"), следовательно, что-то вроде subtable[Amount] похоже на subtable Evaluate("Amount"), что явно не имеет смысла.

2) Type - зарезервированное слово

Вы не предоставили достаточно контекста, чтобы сказать гораздо больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...