简体   繁体   English

通过 VBA 迭代切片器并每次选择一个项目

[英]Iterate over slicer via VBA and select a single item each time

I have several slicers within a spreadhseet.我在一个电子表格中有几个切片器。 I'd like to be able to loop over one of these via VBA, and select every option one by one.我希望能够通过 VBA 循环其中之一,并一个一个地选择每个选项。 The macro below seems fine to my tired eyes, but it obviously doesn't work when I run it.下面的宏对我疲惫的眼睛来说似乎很好,但是当我运行它时它显然不起作用。 When I add a breakpoint at the 'BREAKPOINT tag here below, the first item gets selected, but then the macro goes to the second one while keeping the first one selected and I end up with all my items selected...当我在下面的“BREAKPOINT”标签处添加断点时,第一个项目被选中,但随后宏转到第二个,同时保持第一个选中,最终我选择了所有项目......

    Sub slicers(slName As String)
    Dim slItem As SlicerItem, slDummy As SlicerItem
    Dim slBox As SlicerCache
    Set slBox = ActiveWorkbook.SlicerCaches(slName)
    For Each slItem In slBox .SlicerItems
      For Each slDummy In slBox .SlicerItems
          slDummy.Selected = (slDummy.Name = slItem.Name)
      Next slDummy
    Next slItem 'BREAKPOINT
    End Sub

    Sub test()
    Call slicers("A_slicer_name")
    End Sub

Thanks for your help谢谢你的帮助

EDIT:编辑:
As pointed out by Scott Holtzman, turns out that I just need to clear the filter (slBox.ClearManualFilter) upon selecting a new item.正如 Scott Holtzman 所指出的,事实证明我只需要在选择新项目时清除过滤器 (slBox.ClearManualFilter)。

Why is that necessary whereas the boolean test works properly when I debug.print it?为什么这是必要的,而布尔测试在我 debug.print 时正常工作?

The code below works fine:下面的代码工作正常:

    Sub slicers(slName As String)
    Dim slItem As SlicerItem, slDummy As SlicerItem
    Dim slBox As SlicerCache
    Set slBox = ActiveWorkbook.SlicerCaches(slName)
    For Each slItem In slBox .SlicerItems
      slBox.ClearManualFilter 'THIS IS THE LINE I NEEDED TO ADD
      For Each slDummy In slBox .SlicerItems
          slDummy.Selected = (slDummy.Name = slItem.Name)
      Next slDummy
    Next slItem
    End Sub

    Sub test()
    Call slicers("A_slicer_name")
    End Sub

Since the question I linked you too in my comment does not have an accepted answer (the user never choose to answer or reply to my suggestion), I will provide the solution to your problem here as well.由于我在评论中也链接到您的问题没有被接受的答案(用户从不选择回答或回复我的建议),我也会在这里提供您的问题的解决方案。

Sub slicers(slName As String)

    Dim slItem As SlicerItem, slDummy As SlicerItem
    Dim slBox As SlicerCache

    Set slBox = ActiveWorkbook.SlicerCaches(slName)

    'loop through each slicer item
    For Each slItem In slBox.SlicerItems

        'show all items to start
        slBox.ShowAllItems 'or .ClearManualFilter

        'test each item against itself
        For Each slDummy In slBox.SlicerItems

            'if the item equals the item in the first loop, then select it
            'otherwise don't show it (thus showing 1 at a time between the nested loops)
            If slItem.Name = slDummy.Name Then slDummy.Selected = True Else: slDummy.Selected = False

            'more code to process the data (I suspect)

        Next slDummy

    Next slItem

End Sub

You can indeed have several selected items within an excel spreadsheet.您确实可以在 Excel 电子表格中选择多个项目。 The code you posted do nothing instead of selecting all items satisfying slDummy.Name = slItem.Name .您发布的代码什么也不做,而是选择满足slDummy.Name = slItem.Name所有项目。

If I understand well, you want to run some code once the item is selected, and then go to the next item.如果我理解得很好,您想在选择项目后运行一些代码,然后转到下一个项目。 You can achieve this by unselecting one item after use, with item.selected = False .您可以通过在使用后取消选择一项来实现这一点,使用item.selected = False

You may also want to select all items needed at first stage and then run a loop that will afect only the item that have the property .selected set to true .您可能还想选择第一阶段所需的所有项目,然后运行一个循环,该循环仅影响将.selected属性设置为true However it will probably be longer to execute as you'd have one more loop.但是,执行时间可能会更长,因为您还有一个循环。

I tried the above solutions but can't get them to work.我尝试了上述解决方案,但无法让它们工作。 I kept getting a 1004 object not defined error;我一直收到 1004 object not defined 错误; might be because I'm using the data model.可能是因为我正在使用数据模型。 In the end I cobbled together this solution which picks up the slicer values from a range and then calls another macro to save in pdf (which was my ultimate objective).最后,我拼凑了这个解决方案,它从一个范围内获取切片器值,然后调用另一个宏以保存在 pdf 中(这是我的最终目标)。 Not elegant but effective.不优雅但有效。

Sub looop()

Dim rng As Range, cell As Range
Set rng = Sheet1.Range("B4:B5")
For Each cell In rng

ActiveWorkbook.SlicerCaches("Slicer_MasterBrand").VisibleSlicerItemsList = Array("[Customer].[MasterBrand].&[" & cell.Value & "]")

a_ExportPDF

Next cell
    
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM