使用VBA循环遍历工作簿切片器名称

4

我尝试过Google和搜索这个问题,但就是无法解决。我只是想在活动工作表上循环遍历切片器并删除它们,如果存在的话。

目前我有6个切片器。之前我有

    ActiveSheet.Shapes.Range(Array("Market Segment Name 2", "Line of Business 2" _
    , "Customer Name", "Product Group Name", "Product Type Name", "Product Code") _
    ).Select
    Selection.Delete

但如果我已经删除了切片器,这就没用了。

现在我正在尝试(请注意,wb是在名为“Public”的模块中设置为全局变量)

Option Explicit
Dim sl As Slicer
Dim slName As String

Set wb = ActiveWorkbook

For Each sl In wb.SlicerCaches
    If sl.Name = "Market Segment Name 2" Or _
        sl.Name = "Line of Business 2" Or _
        sl.Name = "Customer Name" Or _
        sl.Name = "Product Group Name" Or _
        sl.Name = "Product Type Name" Or _
        sl.Name = "Product Name" Then
        slName = sl.Name
        ActiveSheet.Shapes.Range(slName).Delete
    End If
Next sl

我觉得它应该能够正常工作。如果我降至SlicerItem级别,我已经成功地使它工作了,但我只是无法弄清楚如何在Slicer级别访问它...如有任何想法,将不胜感激。谢谢。 如果这种方法失败了,我会尝试建立数组并通过删除的方式来实现,但我仍然需要一种测试当前Slicer是否存在的方法。

我只是想不通如何在Slicer级别访问它... 我没有理解你的问题。 - Siddharth Rout
嗨,Siddharth Rout。我希望这个程序的结构和逻辑都是正确的。我是根据下面链接的图片(附在下面)进行操作的。当我看到工作表上的切片器时,我假设那就是“切片器”级别,那就是我可以访问名称以便检测是否可以删除它的地方。http://blogs.office.com/cfs-filesystemfile.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-00-44-metablogapi/0636.image_5F00_2ADE6206.png - Jay Killeen
你是想要所有切片器的名称还是检查一个切片器是否存在? - Siddharth Rout
我只想检查一个切片器是否存在,如果存在就删除它。 - Jay Killeen
好的,正在发布答案... - Siddharth Rout
谢谢,感谢Siddharth。 - Jay Killeen
2个回答

5

我可以想到两种方法。

一种是使用Force方法。在此方法中我们不会检查切片器是否存在,而只是简单地删除它(如果存在的话)。例如:

On Error Resume Next
ActiveSheet.Shapes.Range("Market Segment Name 2").Delete
ActiveSheet.Shapes.Range("Line of Business 2").Delete
'
'~~> And so on
'
On Error GoTo 0

另一种方法是实际检查切片器是否存在,然后再删除它。例如:

Dim sl As SlicerCache

On Error Resume Next
Set sl = ActiveWorkbook.SlicerCaches("Market Segment Name 2")
On Error GoTo 0

If Not sl Is Nothing Then sl.Delete

'For Each sl In ActiveWorkbook.SlicerCaches
    'Debug.Print sl.Name
'Next

编辑:

根据评论进行跟进。

将第一段代码转换为循环。

Sub Sample()
    Dim sSlicers As String
    Dim Myar
    Dim i As Long

    '~~> Slicers you want to delete
    sSlicers = "Market Segment Name 2,Line of Business 2"
    sSlicers = sSlicers & "," & "Customer Name,Product Group Name"
    sSlicers = sSlicers & "," & "Product Type Name,Product Code"

    '~~> Split the names using "," as a delimiter
    '~~> If your slicer names have "," then use a different delimiter
    Myar = Split(sSlicers, ",")

    For i = LBound(Myar) To UBound(Myar)
        On Error Resume Next
        ActiveSheet.Shapes.Range(Myar(i)).Delete
        On Error GoTo 0
    Next i
End Sub

感谢Siddarth Rout。目前我认为我会选择这个第一选项,因为它完成了工作(如果我将其包含在"On error Resume Next"中,这与我最初的想法类似)。我会再等一段时间,看看是否有人能够提出一个循环答案,因为可能我的工作表会有更多的切片器,我不想手动将它们全部添加到代码中。再次感谢,与人讨论这些问题是有帮助的。 - Jay Killeen
我也可以给你一个循环代码,但是你需要将那些名称存储在某个地方吗? - Siddharth Rout
@JayKilleen:请查看上面答案的编辑。您可能需要刷新页面。 - Siddharth Rout
非常感谢,Siddarth。我可能会将数据存储在用户窗体中,以便用户可以根据访问数据库中的字段选择要添加的切片器。再次感谢! :) - Jay Killeen

2

这是我最终找到的另一段代码,可以实现我最初想要达到的目标。

Sub LoopSlicerNames()

Dim slCaches As SlicerCaches
Dim slCache As SlicerCache

Set slCaches = ThisWorkbook.SlicerCaches

For Each slCache In slCaches

    'MsgBox (slCache.Name & " is used for " & slCache.PivotTables.Item(1).Name)
    If slCache.PivotTables.Item(1).Name = "PTDashboard" Then
        slCache.Delete
        'MsgBox ("Slicer has been deleted")
    End If

    'If slCache.Name = "Slicer_Market_Segment_Name2" Then slCache.Delete

Next slCache

End Sub

这个与其他不同的地方在于,我基于其父透视表所在的工作表定位了切片器,因此我不需要将切片器的确切名称添加到代码中。如果我确实想将切片器的名称添加到代码中,我只需更改注释即可。感谢Siddarth再次提供帮助。您帮我克服了最初的障碍并提供了良好的解决方案。我认为我的最初问题是认为切片器是切片缓存的子元素。现在看来,它似乎是切片缓存、切片缓存、然后是切片项,而我在原始问题中提到的“切片器”是“切片缓存”级别...所以我链接的那张图片让我非常困惑。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接