确定 Excel 切片器指向的字段
Determine the field an Excel slicer points to
我正在尝试编写一个宏,以便当工作簿的用户在数据透视表 table 上进行钻取时,该钻取会将相关的切片器筛选器应用于结果钻取(为什么以上帝的名义微软还没有这样做超出了我的范围)。
有问题的工作簿有两个基于单独数据的枢轴 table,我已经计算出(大部分)逻辑来检查是否有任何切片器甚至在应用过滤器,如果是的话是哪个选择值。我也有关于 Before_DoubleClick & Worksheet_Activate 操作的逻辑,让宏知道正在发生钻取(排除在外,因为我之前使用过代码并且知道它有效)。
最后一步是找到切片器所基于的列,并从钻取 sheet 中删除行,其中该列具有未选择的值。我以为我会根据记录切片器的创建来寻找 SlicerCache.Levels.SourceFiled
,但是当我尝试编写代码时它似乎不可用(至少它没有显示在自动完成选项中) .
我当前实际过滤演练的代码如下:
Sub Filter_Drill_Down(SourceSheet As Worksheet, Drill_Down_Sheet As Worksheet)
'
Dim Slicer_Column As String
Dim Selected_Values As String
Dim Selected_Cnt As Long
Dim Total_Values As Long
Dim All_Slicers As SlicerCaches
Dim SCache As SlicerCache
Dim Slicer_Obj As Slicer
Dim S_Item As SlicerItem
Dim DDS_Row As Long
Dim No_Match As Boolean
Application.ScreenUpdating = False
'Capture all the slicers in the workbook (since they're not natively sheet specific)
Set All_Slicers = ThisWorkbook.SlicerCaches
'Iterate through the slicer caches
For Each SCache In All_Slicers
'Check if the current cache has a Slicer Object on the source sheet
For Each Slicer_Obj In SCache.Slicers
If Slicer_Obj.Shape.Parent Is SourceSheet Then
'In order to prevent wasting time applying filters for slicers where no filtering occurs, we'll first check how many items are selected. Reset the counters to make
'sure we don't miscount, and clear Selected_Values so we don't include incorrect values
Selected_Cnt = 0
Total_Values = 0
Selected_Values = ""
For Each S_Item In SCache.SlicerItems
If S_Item.Selected Then
'Current item is selected, increment the selected count & add the value to the selected values string. That way if we do need to filter we can just check if
' a row's value for the relevant column is in the string & delete rows where that's not true
Selected_Cnt = Selected_Cnt + 1
Selected_Values = Selected_Values & "|" & S_Item.Name & "|"
End If 'else the item isn't selected, just need to increment the total count which happens anyway
Total_Values = Total_Values + 1
Next
'Check if the total = selected
If Total_Values > Selected_Cnt Then
'We actually need to filter. The first step in that is knowing which column to check
Slicer_Column = "A"
No_Match = True
'Find the matching column
Do While Drill_Down_Sheet.Range(Slicer_Column & 1).Value <> "" And No_Match
'Check if the header for the current column is the one we're looking for
If Drill_Down_Sheet.Range(Slicer_Column & 1).Value = <X> Then'HERE'S WHERE I NEED HELP
No_Match = False
Else
'Move to the next column
Slicer_Column = ColNumToStr(ColStrToNum(Slicer_Column) + 1) 'ColNumToStr converts a # to it's letter equivalent (i.e. 27 = AA) & ColStrToNum does the inverse
End If
Loop
'Iterate through the rows. Column A is ALWAYS filled, so use it to control the loop
DDS_Row = 2
Do While Drill_Down_Sheet.Range("A" & DDS_Row).Value <> ""
'Check the value in the target column against the selected items string
If InStr(1, Selected_Values, "|" & Drill_Down_Sheet.Range(Slicer_Column & DDS_Row).Value & "|") = 0 Then
'Value isn't selected, delete the row. Note: Since this will make what had been row DDS_Row + 1 into row DDS_Row, we do NOT increment DDS_Row
Drill_Down_Sheet.Range(DDS_Row & ":" & DDS_Row).Delete xlShiftUp
Else
'Not a filtered value, move to the next row
DDS_Row = DDS_Row + 1
End If
Loop
End If 'all the values are selected, which means none are filtered, so do nothing
End If 'else the slicer does not appear on the Source_Sheet, meaning it's not one that applies to the pivot table being drilled into. Just move to the next cache
Next
Next
Application.ScreenUpdating = True
End Sub
一些蛮力试验和错误让我找到了答案。您应该使用 SlicerCache.SourceName
来获取字段名称。
我正在尝试编写一个宏,以便当工作簿的用户在数据透视表 table 上进行钻取时,该钻取会将相关的切片器筛选器应用于结果钻取(为什么以上帝的名义微软还没有这样做超出了我的范围)。
有问题的工作簿有两个基于单独数据的枢轴 table,我已经计算出(大部分)逻辑来检查是否有任何切片器甚至在应用过滤器,如果是的话是哪个选择值。我也有关于 Before_DoubleClick & Worksheet_Activate 操作的逻辑,让宏知道正在发生钻取(排除在外,因为我之前使用过代码并且知道它有效)。
最后一步是找到切片器所基于的列,并从钻取 sheet 中删除行,其中该列具有未选择的值。我以为我会根据记录切片器的创建来寻找 SlicerCache.Levels.SourceFiled
,但是当我尝试编写代码时它似乎不可用(至少它没有显示在自动完成选项中) .
我当前实际过滤演练的代码如下:
Sub Filter_Drill_Down(SourceSheet As Worksheet, Drill_Down_Sheet As Worksheet)
'
Dim Slicer_Column As String
Dim Selected_Values As String
Dim Selected_Cnt As Long
Dim Total_Values As Long
Dim All_Slicers As SlicerCaches
Dim SCache As SlicerCache
Dim Slicer_Obj As Slicer
Dim S_Item As SlicerItem
Dim DDS_Row As Long
Dim No_Match As Boolean
Application.ScreenUpdating = False
'Capture all the slicers in the workbook (since they're not natively sheet specific)
Set All_Slicers = ThisWorkbook.SlicerCaches
'Iterate through the slicer caches
For Each SCache In All_Slicers
'Check if the current cache has a Slicer Object on the source sheet
For Each Slicer_Obj In SCache.Slicers
If Slicer_Obj.Shape.Parent Is SourceSheet Then
'In order to prevent wasting time applying filters for slicers where no filtering occurs, we'll first check how many items are selected. Reset the counters to make
'sure we don't miscount, and clear Selected_Values so we don't include incorrect values
Selected_Cnt = 0
Total_Values = 0
Selected_Values = ""
For Each S_Item In SCache.SlicerItems
If S_Item.Selected Then
'Current item is selected, increment the selected count & add the value to the selected values string. That way if we do need to filter we can just check if
' a row's value for the relevant column is in the string & delete rows where that's not true
Selected_Cnt = Selected_Cnt + 1
Selected_Values = Selected_Values & "|" & S_Item.Name & "|"
End If 'else the item isn't selected, just need to increment the total count which happens anyway
Total_Values = Total_Values + 1
Next
'Check if the total = selected
If Total_Values > Selected_Cnt Then
'We actually need to filter. The first step in that is knowing which column to check
Slicer_Column = "A"
No_Match = True
'Find the matching column
Do While Drill_Down_Sheet.Range(Slicer_Column & 1).Value <> "" And No_Match
'Check if the header for the current column is the one we're looking for
If Drill_Down_Sheet.Range(Slicer_Column & 1).Value = <X> Then'HERE'S WHERE I NEED HELP
No_Match = False
Else
'Move to the next column
Slicer_Column = ColNumToStr(ColStrToNum(Slicer_Column) + 1) 'ColNumToStr converts a # to it's letter equivalent (i.e. 27 = AA) & ColStrToNum does the inverse
End If
Loop
'Iterate through the rows. Column A is ALWAYS filled, so use it to control the loop
DDS_Row = 2
Do While Drill_Down_Sheet.Range("A" & DDS_Row).Value <> ""
'Check the value in the target column against the selected items string
If InStr(1, Selected_Values, "|" & Drill_Down_Sheet.Range(Slicer_Column & DDS_Row).Value & "|") = 0 Then
'Value isn't selected, delete the row. Note: Since this will make what had been row DDS_Row + 1 into row DDS_Row, we do NOT increment DDS_Row
Drill_Down_Sheet.Range(DDS_Row & ":" & DDS_Row).Delete xlShiftUp
Else
'Not a filtered value, move to the next row
DDS_Row = DDS_Row + 1
End If
Loop
End If 'all the values are selected, which means none are filtered, so do nothing
End If 'else the slicer does not appear on the Source_Sheet, meaning it's not one that applies to the pivot table being drilled into. Just move to the next cache
Next
Next
Application.ScreenUpdating = True
End Sub
一些蛮力试验和错误让我找到了答案。您应该使用 SlicerCache.SourceName
来获取字段名称。