Excel 2016 VBA - сравнить 2 поля сводных таблиц для сопоставления значений - PullRequest
0 голосов
/ 02 сентября 2018

Привет, пожалуйста, может кто-нибудь помочь, Excel 2016 VBA Сводная таблица объектов. Я редко разрабатываю в Excel VBA.

Общая цель: Сравните список значений [P_ID] одного столбца из PivotTable2 с PivotTable1, если они существуют или нет, чтобы включить фильтрацию по этим действительным значениям в PivotTable1.

У меня есть код VBA для Excel 2016, который я адаптировал из предыдущего ответа из другого интернет-источника.

Логика: сбор данных из PivotTable2 из набора данных ComparisonTable (в модели PowerPivot), поле [P_ID] списка значений. Сгенерируйте тестовую строку в качестве входных данных для функции, чтобы проверить наличие поля и значения в PivotTable1 для набора данных Mastertable, если true, добавьте строку как допустимую, если не пропустите строку. Наконец, отфильтруйте PivotTable1 со значениями VALID P_ID.

Работает до точки, пока не доберется до функции bFieldItemExists, которая генерирует ошибку:

Ошибка времени выполнения '1004' Не удалось получить свойство PivotItems класса PivotField

Может кто-нибудь, пожалуйста, исправьте способ, которым это не работает?

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)

Dim MyArray As Variant, _
    ar As Variant, _
    x As String, _
    y As String, _
    str As Variant

MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("[ComparisonTable].[P_ID].[P_ID]").DataRange

For Each ar In MyArray
    x = "[MasterTable].[P_ID].&[" & ar & "]"

    If ar <> "" And bFieldItemExists(x) = True Then
        If str = "" Then
            str = "[MasterTable].[P_ID].&[" & ar & "]"
        Else
            str = str & "," & "[MasterTable].[P_ID].&[" & ar & "]"
        End If
    End If
Next ar


Dim str2() As String

    str2 = Split(str, ",")

    Application.EnableEvents = False
    Application.ScreenUpdating = False

        ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").VisibleItemsList = Array(str2)

    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub


Function bFieldItemExists(strName As String) As Boolean
    Dim strTemp As Variant

    ' This line does not work!?
  strTemp = ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").PivotItems(strName)

If Err = 0 Then bFieldItemExists = True Else bFieldItemExists = False

End Function

1 Ответ

0 голосов
/ 03 сентября 2018

Ошибка 1004 произошла из-за использования квадратных скобок []. Удалить те.

Вам также необходимо использовать ключевое слово Set, когда вы устанавливаете объект, равный чему-либо. Например Set MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("ComparisonTable.P_ID.[P_ID").DataRange.

Если вы не используете Set, вы получите диалоговое окно с ошибкой во время выполнения VBA, которое сообщает Ошибка во время выполнения '91': переменная объекта или переменная блока не установлена ​​

Я не могу гарантировать, что мои изменения полностью решат вашу проблему, поскольку у меня нет ваших данных и я не могу полностью протестировать ваш код. Вам нужно будет использовать режим отладки в редакторе VBA и один шаг по коду. Для этого установите точку останова на Set mDataRange = Active.... Чтобы установить точку останова, перейдите в меню «Отладка» и выберите пункт подменю «Переключить точку останова», или вы можете нажать F9, чтобы установить точку останова.

Теперь, когда вы вносите изменения в сводную таблицу, событие Worksheet_PivotTableUpdate сработает, и в этот момент код превысит выполнение.

После того, как код перестает выполняться из-за точки останова, вы можете нажать клавишу F8, чтобы выполнить пошаговый просмотр кода. Если вы хотите возобновить выполнение до следующей точки останова, вы можете нажать F5. Также, когда вы получаете диалоговое окно с ошибкой VBA, вы можете нажать Отладка, а затем использовать клавишу F8 для одного шага или использовать окна отладки, чтобы увидеть, что содержат ваши переменные и объекты. Я уверен, что есть несколько хороших видео на YouTube по отладке VBA.

По мере того, как вы шагаете по коду, вы можете наблюдать за тем, что содержит каждая переменная / объект, используя окно Immediate, окно Watches и окно Locals. Чтобы открыть эти окна, перейдите в пункт меню «Вид» и щелкните каждый из этих пунктов подменю.

Вот как вам нужно отредактировать код перед отладкой.

Option Explicit

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)

    'Better practice is to not use the underscore character to
    'continue a Dim declaration line
    Dim mDataRange As Range
    Dim ar As Range
    Dim x As String
    Dim y As String
    Dim str As Variant

    'Use Set to assign the object mDataRange a reference to the the right
    'hand side of the equation.  Remove the square brackets
    'MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("[ComparisonTable].[P_ID].[P_ID]").DataRange
    Set mDataRange = ActiveSheet.PivotTables("PivotTable2").PivotFields("ComparisonTable.P_ID.P_ID").DataRange

    For Each ar In mDataRange
        'You need to specify what proprerty from ar you
        'want to assign to x.  Assuming the value stored in
        'ar.Value2 is a string, this should work.
        'We use value2 because it is the unformmated value
        'and is slightly quicker to access than the Text or Value
        'properties
        'x = "[MasterTable].[P_ID].&[" & ar & "]"
        x = "MasterTable.P_ID." & ar.Value2

        'Once again specify the Value2 property as containing
        'what value you want to test
        If ar.Value2 <> "" And bFieldItemExists(x) = True Then
            If str = "" Then
                'Remove the square brackets and use the specific property
                'str = "[MasterTable].[P_ID].&[" & ar & "]"
                str = "MasterTable.P_ID." & ar.Value2
            Else
                'Remove the square brackets and use the specific property
                'str = str & "," & "[MasterTable].[P_ID].&[" & ar & "]"
                str = str & "," & "MasterTable.P_ID." & ar.Value2
            End If
        End If
    Next ar


Dim str2() As String

    str2 = Split(str, ",")

    Application.EnableEvents = False
    Application.ScreenUpdating = False
        'Remove square brackets
        'ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").VisibleItemsList = Array(str2)
        ActiveSheet.PivotTables("PivotTable1").PivotFields("MasterTable.P_ID.P_ID").VisibleItemsList = Array(str2)

    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub


Function bFieldItemExists(strName As String) As Boolean

    'Declare a PivotItem to accept the return value
    Dim pvItem As PivotItem
    'Since you want to trap for an error, you'll need to let the VBA runtime know
    'The following code is a pseudo Try/Catch.  This tells the VBA runtime to skip
    'the fact an error occured and continue on to the next statement.
    'Your next statement should deal with the error condition
    On Error Resume Next

    'Use Set whenever assigning an object it's "value" or reference in reality
    Set pvItem = ActiveSheet.PivotTables("PivotTable1").PivotFields("MasterTable.P_ID.P_ID").PivotItems(strName)

    'Assuming that an error gets thrown when strName is not found in the pivot
    'Err is the error object.  You should access the property you wish to test
    If Err.Number = 0 Then
        bFieldItemExists = True
    Else
        bFieldItemExists = False
    End If

    'Return to normal error functioning
    On Error GoTo 0
End Function

Наконец, я понимаю, что кое-что из этого должно быть в разделе комментариев, но мне нужно было объяснить слишком много, чтобы помочь Learner74. Но самое главное, я надеюсь, что помог ему. Я использовал так много предложений, рекомендаций и объяснений от обмена переполнения стека VBA в течение многих лет, я просто хочу вернуть его, заплатив вперед.

Дополнительные полезные ссылки:

Чип Пирсон - это сайт и человек для всех вещей VBA

Paul Kelly's Excel Macro Mastery - еще один переход на сайт по вопросам Excel и VBA.

Объектная модель Microsoft Excel , которая иногда полезна, но нуждается в улучшении. Слишком многим объектам не хватает примеров, но они могут, по крайней мере, указать вам правильное направление.

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