Получение "несоответствия типов" с сводными таблицами VBA и датами фильтрации

98
6

Я пишу скрипт в Excel VBA (MS0 365 - версия 1708).

Цель сценария - применять разные диапазоны дат к "предварительно структурированным" сводным таблицам, сводные таблицы связаны с табличным кубом.

У меня есть Googled и я видел подобные проблемы, но я не нашел никаких решений для моей проблемы, к сожалению

В сценарии я прохожу через годы, а затем кварталы, месяцы и, наконец, Даты по мере необходимости (даты вычисляются с помощью листа), идея здесь заключается в том, чтобы имитировать то, что пользователь делает с помощью мыши, но я понимаю, что там может быть более эффективным методом? (Я попробовал .PivotFilters.Add2 вместо этого, но он, похоже, не работает, поскольку это поле xlPageField).

Итак, на данный момент с приведенным ниже Sub для данной сводной таблицы, чтобы выбрать, например, все даты, начиная с 1 января 2017 года, до воскресенья 8 апреля, я выберу:

2017 то первый квартал 2018 года (называемый "T1-JFM" ниже) то ничего месяца тогда все даты апреля до 8-го включали

Однако, как только я попал в Sub, который относится к датам, я получаю сообщение об ошибке:

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

Там я получаю:

"Ошибка времени выполнения 13": несоответствие типов

эта строка - это линия, которая фактически применяет фильтры Date (до применения фильтров DIM_ARRAY - это массив, который "накапливает" строки, используемые в фильтре).

Я попытался добавить еще один кавычек в DIM_ARRAY в начале и в конце массива, чтобы убедиться, что он не был плохо оценен как строка, это не сработало.

Параметр Dates 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)

Ниже представлен весь макрос. Дим находятся сверху и Функции внизу. Как я могу это решить?

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

спросил(а) 2021-01-25T19:17:50+03:00 5 месяцев назад
1
Решение
77

РЕШЕНИЕ:

DIM_ARRAY должен был быть типом данных Array и был типом данных String (который напоминал массив в заблуждении, но не был одним).

Я считаю, что другие части кода работали только потому, что каждый раз в "поддельном массиве" каждый раз применялся только один элемент, что определенно состоит в том, что данные/параметры, используемые в "условиях теста", привели меня к ошибочному диагнозу.

(Извлеченный урок: измените условия тестирования, чтобы убедиться, что они позволяют вам собирать новую информацию)

Ниже полного кода, который действительно работает на этот раз:

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

ответил(а) 2021-01-25T19:17:50+03:00 5 месяцев назад
45

В таких случаях наилучшей отладкой является передача массива с жестко закодированными значениями и просмотр того, работает ли он. Как это:

..._DATE_PTF)..VisibleItemsList = Array(CDate("08.04.2018"), CDate("09.05.2018"))

Если он работает, попробуйте найти способ передать значения в массиве как переменные.

ответил(а) 2021-01-25T19:17:50+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема