使用 VBA 数据透视表和筛选日期获取 "Type Mismatch"
Getting "Type Mismatch" with VBA PivotTables and Filter Dates
我正在 Excel VBA(MS0 365 - 版本 1708)中编写脚本。
脚本的 objective 是将不同的日期范围应用于 "pre-structured" 数据透视表,数据透视表连接到表格立方体。
我用 Google 搜索过,也看到过类似的问题,但遗憾的是我没有找到任何解决方案
在脚本中,我循环遍历年份,然后是季度、月份,最后是需要的日期(日期是通过工作表计算的),这里的想法是模拟用户用他的鼠标做什么,但我知道可能有更有效的方法? (我试过 .PivotFilters.Add2
但它似乎不起作用,因为它是一个 xlPageField
字段)。
所以现在使用下面的子,对于给定的数据透视表,为了 select 例如从 2017 年 1 月 1 日开始到 4 月 8 日星期日的所有日期,我将 select:
- 2017
- 然后是 2018 年第一季度(以下称为 "T1-JFM")
- 然后几个月都没有
- 然后包括 4 月到 8 日的所有日期
但是,一旦我点击了与日期相关的子项,我就收到了一条错误消息:
ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
我得到一个:
"Run-time error '13' : Type mismatch
该行实际上是 应用 日期过滤器的行,(在应用过滤器之前 DIM_ARRAY
是一个数组,其中 "accumulates" 使用的字符串在过滤器中)。
我尝试在数组的开头和结尾为 DIM_ARRAY
添加另一个引号,以确保它不会被错误地评估为字符串,但没有成功。
日期子部分是这样的:
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) 在顶部,Functions 在底部。我该如何解决?
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
在这种情况下,最好的调试方法是传递带有硬编码值的数组并查看它是否有效。像这样:
..._DATE_PTF)..VisibleItemsList = Array(CDate("08.04.2018"), CDate("09.05.2018"))
如果可行,请尝试找到一种方法将数组中的值作为变量传递。
解决方案:
DIM_ARRAY 必须是 Array 数据类型并且是 String 数据类型(类似于误导性的方式,但不是一种方式)。
我认为代码的其他部分之所以有效,只是因为在 "fake array" 中每次只应用了 1 个元素,可以肯定的是 data/parameters 在 [=30= 中使用了] 让我误导了诊断。
(经验教训:改变你的测试条件,看看它们是否能让你收集到新信息)
在完整代码下方,这次确实有效:
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
我正在 Excel VBA(MS0 365 - 版本 1708)中编写脚本。
脚本的 objective 是将不同的日期范围应用于 "pre-structured" 数据透视表,数据透视表连接到表格立方体。
我用 Google 搜索过,也看到过类似的问题,但遗憾的是我没有找到任何解决方案
在脚本中,我循环遍历年份,然后是季度、月份,最后是需要的日期(日期是通过工作表计算的),这里的想法是模拟用户用他的鼠标做什么,但我知道可能有更有效的方法? (我试过 .PivotFilters.Add2
但它似乎不起作用,因为它是一个 xlPageField
字段)。
所以现在使用下面的子,对于给定的数据透视表,为了 select 例如从 2017 年 1 月 1 日开始到 4 月 8 日星期日的所有日期,我将 select:
- 2017
- 然后是 2018 年第一季度(以下称为 "T1-JFM")
- 然后几个月都没有
- 然后包括 4 月到 8 日的所有日期
但是,一旦我点击了与日期相关的子项,我就收到了一条错误消息:
ActiveSheet.PivotTables("PivotTable3").PivotFields(DIM_DATE_PTF).VisibleItemsList = Array(DIM_ARRAY)
我得到一个:
"Run-time error '13' : Type mismatch
该行实际上是 应用 日期过滤器的行,(在应用过滤器之前 DIM_ARRAY
是一个数组,其中 "accumulates" 使用的字符串在过滤器中)。
我尝试在数组的开头和结尾为 DIM_ARRAY
添加另一个引号,以确保它不会被错误地评估为字符串,但没有成功。
日期子部分是这样的:
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) 在顶部,Functions 在底部。我该如何解决?
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
在这种情况下,最好的调试方法是传递带有硬编码值的数组并查看它是否有效。像这样:
..._DATE_PTF)..VisibleItemsList = Array(CDate("08.04.2018"), CDate("09.05.2018"))
如果可行,请尝试找到一种方法将数组中的值作为变量传递。
解决方案:
DIM_ARRAY 必须是 Array 数据类型并且是 String 数据类型(类似于误导性的方式,但不是一种方式)。
我认为代码的其他部分之所以有效,只是因为在 "fake array" 中每次只应用了 1 个元素,可以肯定的是 data/parameters 在 [=30= 中使用了] 让我误导了诊断。
(经验教训:改变你的测试条件,看看它们是否能让你收集到新信息)
在完整代码下方,这次确实有效:
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