#excel #vba
#excel #vba
Вопрос:
Я пытаюсь динамически фильтровать сводную таблицу OLAP. В зависимости от того, устанавливает ли пользователь флажок для определенного месяца или нет, он будет соответствующим образом фильтровать сводку. Можно установить несколько флажков (несколько месяцев). Пример: если они проверят апрель и июнь, сводная таблица OLAP будет отфильтрована по апрелю и июню. Вот мой код:
Dim Apr18 As String
Dim May18 As String
Dim Jun18 As String
If Workbooks("A").Sheets("FilePath").CheckApr.Value = True Then
Apr18 = "[Calendar].[Date Hierarchy].[Year].amp;[2018].amp;[April]"
End If
If Workbooks("A").Sheets("FilePath").CheckMay.Value = True Then
May18 = "[Calendar].[Date Hierarchy].[Year].amp;[2018].amp;[May]"
End If
If Workbooks("A").Sheets("FilePath").CheckJun.Value = True Then
Jun18 = "[Calendar].[Date Hierarchy].[Year].amp;[2018].amp;[June]"
End If
Workbooks("B").SlicerCaches("Slicer_Date_Hierarchy") _
.VisibleSlicerItemsList = Array(Apr18, May18, Jun18)
Когда все месяцы проверены, код работает нормально. Тем не менее, я изо всех сил пытаюсь найти решение для тех случаев, когда пользователь выбирает апрель и июнь, но не май. В этом случае массив должен быть:
Workbooks("B").SlicerCaches("Slicer_Date_Hierarchy") _
.VisibleSlicerItemsList = Array(Apr18, Jun18)
Как мне изменить код, чтобы, если флажок снят, игнорировать это поле? Выполнение
ELse
Apr18 = ""
Не работает.
Примечание: у меня есть 12 месяцев
Ответ №1:
Я думаю, вам нужно будет создавать массив по ходу работы (arr в примере), аналогичный (непроверенный):
dim arr as variant
Dim Apr18 As String, May18 As String, Jun18 As String
'
redim arr(0)
If Workbooks("A").Sheets("FilePath").CheckApr.Value = True Then
if not arr(ubound(arr)) = "" then redim preserve arr(ubound(arr) 1) 'redimensions the array to be 1 size larger, preserviing previous data
arr(ubound(arr)) = "[Calendar].[Date Hierarchy].[Year].amp;[2018].amp;[April]" 'put into array
End If
'add other items
Workbooks("B").SlicerCaches("Slicer_Date_Hierarchy") _
.VisibleSlicerItemsList = arr 'use array you generated
Правка1:
Немного измените это, чтобы помочь учесть ваши 12 месяцев:
dim arr as variant, brr as variant, crr as variant, i as long
brr = array("CheckJan","CheckFeb","CheckMar","CheckApr","CheckMay") 'etc...
crr = array("January","February","March","April","May") 'etc...
redim arr(0)
For i = lbound(brr) to ubound(brr) 'ensure brr and crr are the same length
If Workbooks("A").Sheets("FilePath").CheckBoxes(brr(i)).Value = True Then
if not arr(ubound(arr)) = "" then redim preserve arr(ubound(arr) 1) 'redimensions the array to be 1 size larger, preserviing previous data
arr(ubound(arr)) = "[Calendar].[Date Hierarchy].[Year].amp;[2018].amp;[" amp; crr(i) amp; "]" 'put into array
End If
next i
Workbooks("B").SlicerCaches("Slicer_Date_Hierarchy").VisibleSlicerItemsList = arr 'use array you generated
Комментарии:
1. Это дает мне ошибку, определяемую приложением или объектом, в последней строке
2. @Jade просто об использовании
arr
для определения срезов? похоже, что у вас была бы аналогичная ошибка в вашем примере кода, если только что-то не было добавлено в массив (возможно, вам потребуется проверить, что имена вошли как ожидалось, используяDebug.Print
для каждого элемента массива…3. Я попробовал код Edit1, и теперь он выдает мне ошибку на . Строка Checkboxes(brr(i)), «Не удается получить свойство Checkboxes класса worksheet»… Как мне использовать Debug. Печатать для каждого элемента?
4. @Jade простое использование кода может быть проблемой, так как может потребоваться внести несколько изменений. В коде Edit1 я предположил, что вы использовали флажки с именами CheckJan и т.д., Что может быть неуместно; это было в первую очередь, как привести пример в виде цикла, чтобы сэкономить на куче дополнительных строк кода. Сосредоточившись на вашем предыдущем комментарии и
Debub.Print
, в вашем коде вы бы добавили что-то вродеFor i = lbound(arr) to ubound(arr)
thendebug.print arr(i)
, и вы должны увидеть значение вImmediate Window
. Это позволит вам увидеть, правильный ли формат.5. @Jade Если возможно, давайте сосредоточимся на первом наборе кода, чтобы мы могли обработать вашу ошибку вокруг ошибки 1004. Была ли ошибка на стороне назначения или проблема заключалась в использовании
arr
?
Ответ №2:
Может быть, попробуйте использовать Split
для создания массива из строки (которую вы можете создать)? Несколько уродливый пример:
Dim list As String
list = list amp; "|abc"
list = list amp; "|def"
Dim arr As Variant: arr = Split(Mid(list, 2), "|") ' assumes list non-empty; ignore first char (delimiter)
Debug.Print arr(0)
Debug.Print arr(1)