首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用VBA PivotTables和过滤日期获取“类型不匹配”

利用VBA PivotTables和过滤日期获取“类型不匹配”
EN

Stack Overflow用户
提问于 2018-04-09 13:44:51
回答 2查看 453关注 0票数 0

我正在用Excel编写一个脚本(MS0 365-Version1708)。

脚本的目标是将不同的日期范围应用于“预结构化”枢轴表,枢轴表连接到表格立方体。

我在谷歌上搜索过,也看到过类似的问题,但不幸的是,我没有找到任何解决问题的方法

在脚本中,我循环了几年,然后是季度、月份,最后是需要的日期(日期是通过工作表计算出来的),这里的想法是模拟用户对鼠标做什么,但我知道可能有更有效的方法吗?(我尝试过.PivotFilters.Add2,但它似乎无法工作,因为它是一个xlPageField字段)。

因此,在下面的子图中,对于给定的PivotTable,为了选择从2017年1月1日开始到4月8日星期日的所有日期,我会选择:

  1. 2017年
  2. 然后是2018年第一季度(以下简称"T1-JFM“)
  3. 几个月后什么都没有
  4. 然后四月八号之前的所有日期包括

但是,一旦我点击了与日期有关的Sub,就会在行中得到一个错误:

代码语言:javascript
复制
ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)

在那里我得到了一个:

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

该行是实际应用日期筛选器的行(在应用筛选器之前,DIM_ARRAY是一个数组,它“累加”过滤器中使用的字符串)。

我尝试在数组的开头和结尾添加另一个引号,以确保它没有作为字符串进行糟糕的计算,这是行不通的。

Dates部分如下所示:

代码语言:javascript
复制
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(s)在顶部,功能在底部。我怎么解决这个问题?

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-11 16:02:17

决议

DIM_ARRAY必须是数组数据类型,并且是字符串数据类型(在误导的方式上类似于数组,但不是数组)。

我认为代码的其他部分之所以有效,只是因为每次在“假数组”中只应用了一个元素,可以肯定的是,在“测试条件”中使用的数据/参数导致了错误的诊断。

(吸取的教训:改变你的测试条件,看看它们是否允许你收集新信息)

在完整的代码下面,这一次真正有效:

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2018-04-09 14:19:34

在这种情况下,最好的调试方法是传递带有硬编码值的Array,并查看它是否工作。如下所示:

代码语言:javascript
复制
..._DATE_PTF)..VisibleItemsList = Array(CDate("08.04.2018"), CDate("09.05.2018"))

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49734497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档