获得"类型不匹配"使用VBA数据透视表和过滤日期

时间:2018-04-09 13:44:51

标签: vba excel-vba pivot-table cube excel

我在Excel VBA(MS0 365 - 版本1708)中编写脚本。

该脚本的目标是将不同的日期范围应用于"预先构建的"数据透视表,数据透视表连接到表格多维数据集。

我使用Google搜索并看到了类似的问题,但遗憾的是我找不到任何问题的解决方案

在脚本中,我根据需要循环这些年,然后是季度,月份和最后的日期(日期是通过工作表计算的),这里的想法是模拟用户用鼠标做什么,但我明白可能有更有效的方法? (我尝试过.PivotFilters.Add2,但它看起来并不像是xlPageField字段。

所以目前使用下面的Sub,对于给定的数据透视表,为了选择例如从2017年1月1日到4月8日星期日的所有日期,我将选择:

  1. 2017
  2. 然后是2018年第一季度(名为" T1-JFM"下面)
  3. 然后没有几个月
  4. 然后是4月份的所有日期,直到8日,包括
  5. 然而,一旦我点击涉及日期的Sub,我就会收到错误:

    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    

    我得到了一个:

      

    "运行时错误' 13' :类型不匹配

    该行是实际应用日期过滤器的行,(在应用过滤器DIM_ARRAY之前)是一个"累积"在过滤器)。

    我尝试在数组的开头和结尾添加另一个引号给DIM_ARRAY,以确保它没有被严格评估为字符串,但这并没有成功。< / p>

    日期子部分是:

    Private Sub Cycle_Date(YEAR_i_max As String, TRIMESTRE_i As String,MONTH_i As String, MONTH_i_max As Integer)
    
    i = 0
    DATE_i_min = StdFilter(SheetName, "DATE_i_min")
    DATE_i_max = StdFilter(SheetName, "DATE_i_max")
    
    For i = DATE_i_min To DATE_i_max
    DATE_i=WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(YEAR_i_max
    ,MONTH_i_max, i), "YYYY-MM-DDTHH:MM:SS"))
    
    
    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" 
    & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]" & ".&[" & DATE_i & "]"
    'Debug.Print DIM_ARRAY_elmt
    
    If i = DATE_i_min Then
    DIM_ARRAY = DIM_ARRAY_elmt
    
    ElseIf i = DATE_i_max Then
        DIM_ARRAY = DIM_ARRAY & """" & "," & """" & DIM_ARRAY_elmt
    
    ElseIf DIM_ARRAY <> "" Then
        DIM_ARRAY = DIM_ARRAY & """" & "," & """" & DIM_ARRAY_elmt
    
    End If
    
    Next
    
    'Debug.Print DIM_ARRAY
    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    

    以下是整个宏。 Dim位于顶部,功能位于底部。我该如何解决这个问题?

    Option Explicit
    
    Dim DIM_DATE_CREATION_BASE As String
    Dim DIM_DATE_SUB As String
    Dim DIM_DATE_PTF As String
    
    Dim DIM_DATE_MOD_YEAR As String
    Dim DIM_DATE_MOD_TRIMESTRE As String
    Dim DIM_DATE_MOD_MONTH As String
    Dim DIM_DATE_MOD_DATE As String
    
    Dim DIM_ARRAY As Variant
    Dim DIM_ARRAY_elmt As String
    
    Dim YEAR_i As Integer
    Dim YEAR_i_min As String
    Dim YEAR_i_max As String
    
    Dim TRIMESTRE_i As String
    Dim TRIMESTRE_i_max As String
    Dim TRIMESTRE_i_min As String
    
    Dim MONTH_i As String
    Dim MONTH_i_max As Integer
    Dim MONTH_i_min As Integer
    
    Dim DATE_i As String
    Dim DATE_i_min As Integer
    Dim DATE_i_max As Integer
    
    Dim i As Integer
    
    Dim ws As Variant
    Dim SheetNames As Variant
    Dim SheetName As String
    
    Dim Continue_Flag As Boolean
    
    
    Sub Launch_Update()
    
    Application.ScreenUpdating = False
    
    Call Date_Filters
    
    Application.ScreenUpdating = True
    
    End Sub
    
    
    Private Sub Date_Filters()
    
    Continue_Flag = True
    
    SheetNames = Array("NOW", "A-0 || J-7", "A-1 || à Date Equiv.", "A-1 || J-7 Atterissage")
    
    DIM_DATE_CREATION_BASE = "[DIM_DATE_CREATION].[CALENDRIER_CREATION]"
    DIM_DATE_SUB = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_YEAR
    
    For Each ws In SheetNames
    
    Sheets(ws).Select
    SheetName = ActiveSheet.Name
    
    
    DIM_DATE_MOD_YEAR = ".[ANNEE]"
    DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_YEAR
    
    Call Cycle_Year
    
    DIM_DATE_MOD_TRIMESTRE = ".[TRIMESTRE]"
    DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_TRIMESTRE
    
    Call Cycle_Trimestre(YEAR_i_max)
    
    DIM_DATE_MOD_MONTH = ".[MOIS]"
    DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_MONTH
    
    Call Cycle_Month(YEAR_i_max, TRIMESTRE_i)
    
    DIM_DATE_MOD_DATE = ".[DATE]"
    DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_DATE
    
    Call Cycle_Date(YEAR_i_max, TRIMESTRE_i, MONTH_i, MONTH_i_max)
    
    
    Next ws
    
    Continue_Flag = False
    
    MsgBox "Date Filter Sub has ended"
    
    End Sub
    
    Private Sub Cycle_Year()
    
    YEAR_i_min = StdFilter(SheetName, "YEAR_i_min")
    YEAR_i_max = StdFilter(SheetName, "YEAR_i_max")
    
    If YEAR_i_min = YEAR_i_max Then
    YEAR_i_max = YEAR_i_min + 1
    End If
    
    
    For YEAR_i = YEAR_i_min To YEAR_i_max - 1
    
    DIM_ARRAY_elmt = DIM_DATE_PTF & ".&[" & YEAR_i & "]"
    
    If YEAR_i = YEAR_i_min Then
    DIM_ARRAY = DIM_ARRAY_elmt
    
    ElseIf YEAR_i = YEAR_i_max - 1 Then
    DIM_ARRAY = DIM_ARRAY & "," & DIM_ARRAY_elmt
    
    ElseIf DIM_ARRAY <> "" Then
    DIM_ARRAY = DIM_ARRAY & "," & DIM_ARRAY_elmt
    
    End If
    
    Next
    
    
    
    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    
    
    End Sub
    
    Private Sub Cycle_Trimestre(YEAR_i_max As String)
    
    
    TRIMESTRE_i_min = StdFilter(SheetName, "TRIMESTRE_i_min")
    TRIMESTRE_i_max = StdFilter(SheetName, "TRIMESTRE_i_max")
    
    For i = TRIMESTRE_i_min To TRIMESTRE_i_max
    
    If i = 1 Then
    TRIMESTRE_i = "T1 - JFM"
    
    ElseIf i = 2 Then
    TRIMESTRE_i = "T2 - AMJ"
    
    ElseIf i = 3 Then
    TRIMESTRE_i = "T3 - JAS"
    
    ElseIf i = 4 Then
    TRIMESTRE_i = "T4 - OND"
    
    End If
    
    
    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]"
    
    
    If i = TRIMESTRE_i_min Then
    DIM_ARRAY = DIM_ARRAY_elmt
    
    ElseIf i = TRIMESTRE_i_max Then
    DIM_ARRAY = DIM_ARRAY_elmt
    GoTo ApplyFilter1
    
    ElseIf DIM_ARRAY <> "" Then
    DIM_ARRAY = DIM_ARRAY & "," & DIM_ARRAY_elmt
    
    End If
    
    Next
    
    ApplyFilter1:
    
    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    
    
    End Sub
    Private Sub Cycle_Month(YEAR_i_max As String, TRIMESTRE_i As String)
    
    i = 0
    MONTH_i_min = StdFilter(SheetName, "MONTH_i_min")
    MONTH_i_max = StdFilter(SheetName, "MONTH_i_max")
    
    
    For i = MONTH_i_min To MONTH_i_max
    
    MONTH_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(2018, i, 1), "[$-40C]MMMM"))
    
    
    
    
    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]"
    
    
    If i = MONTH_i_min Then
    DIM_ARRAY = DIM_ARRAY_elmt
    
    ElseIf i = MONTH_i_max Then
    DIM_ARRAY = DIM_ARRAY_elmt
    GoTo ApplyFilter2
    
    ElseIf DIM_ARRAY <> "" Then
    DIM_ARRAY = DIM_ARRAY & "," & DIM_ARRAY_elmt
    
    End If
    
    Next
    
    ApplyFilter2:
    
    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    
    MONTH_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(2018, i - 1, 1), "[$-40C]MMMM"))
    
    End Sub
    Private Sub Cycle_Date(YEAR_i_max As String, TRIMESTRE_i As String, MONTH_i As String, MONTH_i_max As Integer)
    
    i = 0
    DATE_i_min = StdFilter(SheetName, "DATE_i_min")
    DATE_i_max = StdFilter(SheetName, "DATE_i_max")
    
    
    For i = DATE_i_min To DATE_i_max
    
    DATE_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(YEAR_i_max, MONTH_i_max, i), "YYYY-MM-DDTHH:MM:SS"))
    
    
    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]" & ".&[" & DATE_i & "]"
    
    Debug.Print DIM_ARRAY_elmt
    
    
    If i = DATE_i_min Then
    DIM_ARRAY = DIM_ARRAY_elmt
    
    ElseIf i = DATE_i_max Then
    DIM_ARRAY = DIM_ARRAY & """" & "," & """" & DIM_ARRAY_elmt
    
    ElseIf DIM_ARRAY <> "" Then
    DIM_ARRAY = DIM_ARRAY & """" & "," & """" & DIM_ARRAY_elmt
    
    End If
    
    Next
    
    Debug.Print DIM_ARRAY
    
    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
    
    End Sub
    
    Public Function StdFilter(SheetPointer As String, DateField As String)
    
    StdFilter = WorksheetFunction.Index(Sheets("Standard_FILTERS").Range("A1:J5"), _
     WorksheetFunction.Match(SheetPointer, Sheets("Standard_FILTERS").Range("A:A"), 0), _
     WorksheetFunction.Match(DateField, Sheets("Standard_FILTERS").Range("1:1"), 0))
    
    End Function
    

2 个答案:

答案 0 :(得分:0)

在这种情况下,最好的调试是使用硬编码值传递Array并查看它是否有效。像这样:

void mylogger(const char *format, ...)  __attribute__((format(printf, 1, 2)));

如果有效,请尝试找到一种方法将数组中的值作为变量传递。

答案 1 :(得分:0)

解决方案

DIM_ARRAY必须是 Array 数据类型,并且是 String 数据类型(以误导的方式类似于数组,但不是一个)。< / p>

我相信代码的其他部分只是因为每次在&#34;假数组&#34;中只应用了1个元素,可以肯定的是&#34;中使用的数据/参数。测试条件&#34;导致我误入歧途。

(获得的经验:改变您的测试条件以确定它们是否允许您收集新信息)

在完整代码的下方,真的这次正常工作:

Private Sub Date_Filters()

        SheetNames = Array("NOW", "A-0 || J-7", "A-1 || à Date Equiv.", "A-1 || J-7 Atterissage") 'list of relevant sheets

        'setting variables:
        DIM_DATE_CREATION_BASE = "[DIM_DATE_CREATION].[CALENDRIER_CREATION]"
        DIM_DATE_SUB = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_YEAR
        mymsg = "Dates à jour pour TDC :"
        i = 0

    For Each ws In SheetNames

        Sheets(ws).Select
        SheetName = ActiveSheet.Name

            DIM_DATE_MOD_YEAR = ".[ANNEE]"
            DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_YEAR

        Call Cycle_Year

            i = 0
            DIM_DATE_MOD_TRIMESTRE = ".[TRIMESTRE]"
            DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_TRIMESTRE

        Call Cycle_Trimestre(YEAR_i_max)

            i = 0
            DIM_DATE_MOD_MONTH = ".[MOIS]"
            DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_MONTH

        Call Cycle_Month(YEAR_i_max, TRIMESTRE_i)

            i = 0
            DIM_DATE_MOD_DATE = ".[DATE]"
            DIM_DATE_PTF = DIM_DATE_CREATION_BASE & DIM_DATE_MOD_DATE

        Call Cycle_Date(YEAR_i_max, TRIMESTRE_i, MONTH_i, MONTH_i_max)


        mymsg = mymsg & SheetName & " -ET- "
        Application.StatusBar = mymsg

    Next ws

End Sub

Private Sub Cycle_Year()

        YEAR_i_min = StdFilter(SheetName, "YEAR_i_min")
        YEAR_i_max = StdFilter(SheetName, "YEAR_i_max")
        ReDim TRUE_ARRAY(1 To 2)
        Erase TRUE_ARRAY
        ReDim TRUE_ARRAY(YEAR_i_min To YEAR_i_max)

    If YEAR_i_min = YEAR_i_max Then ' Fork-out scenario

        ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array("")

        Exit Sub

    End If


    For YEAR_i = YEAR_i_min To YEAR_i_max - 1 ' Loop through

        DIM_ARRAY_elmt = DIM_DATE_PTF & ".&[" & YEAR_i & "]"
        TRUE_ARRAY(YEAR_i) = DIM_ARRAY_elmt

        Debug.Print "Year   "; YEAR_i; TRUE_ARRAY(YEAR_i)

    Next

    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = TRUE_ARRAY

End Sub

Private Sub Cycle_Trimestre(YEAR_i_max As String)

        TRIMESTRE_i_min = StdFilter(SheetName, "TRIMESTRE_i_min")
        TRIMESTRE_i_max = StdFilter(SheetName, "TRIMESTRE_i_max")
        ReDim TRUE_ARRAY(1 To 2)
        Erase TRUE_ARRAY
        ReDim TRUE_ARRAY(TRIMESTRE_i_min To TRIMESTRE_i_max)

    If TRIMESTRE_i_min = TRIMESTRE_i_max Then ' Fork-out scenario

        ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array("")

        Exit Sub

    End If


    For i = TRIMESTRE_i_min To TRIMESTRE_i_max ' Loop through

        If i = TRIMESTRE_i_max Then

                If i = 1 Then
                    TRIMESTRE_i = "T1 - JFM"

                    ElseIf i = 2 Then
                        TRIMESTRE_i = "T2 - AMJ"

                    ElseIf i = 3 Then
                        TRIMESTRE_i = "T3 - JAS"

                    ElseIf i = 4 Then
                        TRIMESTRE_i = "T4 - OND"

                End If

            GoTo ApplyFilter
            Else

                If i = 1 Then
                    TRIMESTRE_i = "T1 - JFM"

                    ElseIf i = 2 Then
                        TRIMESTRE_i = "T2 - AMJ"

                    ElseIf i = 3 Then
                        TRIMESTRE_i = "T3 - JAS"

                    ElseIf i = 4 Then
                        TRIMESTRE_i = "T4 - OND"

                End If
        End If

    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]"
    TRUE_ARRAY(i) = DIM_ARRAY_elmt

    Debug.Print "Trimestre "; i; TRUE_ARRAY(i)

    Next

ApplyFilter:

    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = TRUE_ARRAY

End Sub
Private Sub Cycle_Month(YEAR_i_max As String, TRIMESTRE_i As String)


        MONTH_i_min = StdFilter(SheetName, "MONTH_i_min")
        MONTH_i_max = StdFilter(SheetName, "MONTH_i_max")
        ReDim TRUE_ARRAY(1 To 2)
        Erase TRUE_ARRAY
        ReDim TRUE_ARRAY(MONTH_i_min To MONTH_i_max)

    If MONTH_i_min = MONTH_i_max Then ' Fork-out scenario

        ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array("")

        MONTH_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(2018, MONTH_i_min, 1), "[$-40C]MMMM"))

        Exit Sub

    End If

    For i = MONTH_i_min To MONTH_i_max - 1 ' Loop through

    MONTH_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(2018, i, 1), "[$-40C]MMMM"))

    DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]"
    TRUE_ARRAY(i) = DIM_ARRAY_elmt

    Debug.Print "Month    "; i; TRUE_ARRAY(i)

    Next

    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = TRUE_ARRAY

    MONTH_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(2018, i, 1), "[$-40C]MMMM"))

End Sub
Private Sub Cycle_Date(YEAR_i_max As String, TRIMESTRE_i As String, MONTH_i As String, MONTH_i_max As Integer)


        DATE_i_min = StdFilter(SheetName, "DATE_i_min")
        DATE_i_max = StdFilter(SheetName, "DATE_i_max")
        ReDim TRUE_ARRAY(1 To 2)
        Erase TRUE_ARRAY
        ReDim TRUE_ARRAY(1 To DATE_i_max)

    If DATE_i_min = DATE_i_max Then ' Fork-out scenario begin

        i = 1

        DATE_i = WorksheetFunction.Proper(WorksheetFunction.Text(DateSerial(YEAR_i_max, MONTH_i_max, i), "YYYY-MM-DDTHH:MM:SS"))

        DIM_ARRAY = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]" & ".&[" & DATE_i & "]"

        ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)

        Exit Sub

    End If ' Fork-out scenario end



    For i = DATE_i_min To DATE_i_max ' Loop through

        DATE_i = Format(DateSerial(YEAR_i_max, MONTH_i_max, i), "YYYY-MM-DDTHH:MM:SS")

        DIM_ARRAY_elmt = DIM_DATE_SUB & DIM_DATE_MOD_YEAR & ".&[" & YEAR_i_max & "]" & ".&[" & TRIMESTRE_i & "]" & ".&[" & MONTH_i & "]" & ".&[" & DATE_i & "]"
        TRUE_ARRAY(i) = DIM_ARRAY_elmt

    Debug.Print "Date      "; Format(i, "00 "); TRUE_ARRAY(i)

    Next

    ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = TRUE_ARRAY

End Sub