简体   繁体   中英

Excel 2010 VBA Shape Control

I've been working on an Excel workbook which contains a number of worksheets which all work in a very similar manner:
1. They have a PivotTable1
2. They have a PivotChart1
3. 4 slicers are used to filter data
4. And finally I've created shapes, with VBA code behind them to allow me to control the drilldown functionality

This has taken quite some time, researching various sites for sample code, recording and digesting what's happening with macro's in order to get to where I am. And I'm quite pleased with the current result.

However, I'm now at a stage where I'd like to ensure the code is as efficient as possible, in order to
1. Keep the filesize as small as possible
2. Ensure operating speed is at its best

So, to my problem.

I have 4 buttons, which are made with standard Excel shapes. My VBA code for each button looks like this:

Sub Top10SelectorByValue()
'
' Top10Selector Macro
'      
Range("Q15").Select
'
' Clear All Filters
'
    ActiveSheet.PivotTables(ActiveCell.PivotTable.Name).PivotFields(ActiveCell.PivotField.Name). _
ClearAllFilters
'
' Apply Top 10 Filter
'
    ActiveSheet.PivotTables(ActiveCell.PivotTable.Name).PivotFields(ActiveCell.PivotField.Name). _
    PivotFilters.Add Type:=xlTopCount, DataField:=ActiveSheet.PivotTables( _
    ActiveCell.PivotTable.Name).PivotFields("Sum of LineTotalValue"), Value1:=10
'
' Format Shapes
 '
    ActiveSheet.Shapes(Application.Caller).ThreeD.BevelTopType =     IIf(ActiveSheet.Shapes(Application.Caller).ThreeD.BevelTopType = 3, 7, 3)
    ActiveSheet.Shapes("btnTop30").ThreeD.BevelTopType = 3
    ActiveSheet.Shapes("btnTop20").ThreeD.BevelTopType = 3
    ActiveSheet.Shapes("btnSelectAll").ThreeD.BevelTopType = 3

    End Sub   

As mentioned, I have this code for each of my buttons, which represent Top30, Top20, Top10, and SelectAll options for my customer to click on.

So here are my 2 questions:
1. Is it possible to make this code more efficient so that I can set all buttons, with the same styling, except the one clicked, in any other way than I have acheived here.
2. Is it possible to only have one instance of this code, accessible by all buttons. 3. I'd like to ensure that at least one option is selected from the 4 buttons, thus leaving it in it's 'down' state

Many thanks, I am a VBA newbie, so please bear with me

Quick answer to Part 3. Name all your buttons something like "btnSlice10", btnSlice20", etc, and assign the same handler to all of them.

Sub ClickMe()

Dim b As String, s As Shape, clr As Long, btnName As String
Dim v, pt as PivotTable, pf as PivotField

    b = Application.Caller

    For Each s In ActiveSheet.Shapes
        If s.Name Like "btnSlice*" Then
            clr = IIf(s.Name = b, vbRed, vbYellow)
            s.Fill.ForeColor.RGB = clr
        End If
    Next s

    If b Like "btnSlice*" Then
        With ActiveSheet

            Set pt = .PivotTables(.Range("Q15").PivotTable.Name)
            Set pf = pt.PivotFields(.Range("Q15").PivotField.Name)

            pf.ClearAllFilters

            v = -999
            Select Case b
                Case "btnSlice10": v = 10
                Case "btnSlice20": v = 20
                Case "btnSlice30": v = 30
            End Select

            If v > 0 Then
                pf.PivotFilters.Add Type:=xlTopCount, _
                     DataField:=pt.PivotFields("Sum of LineTotalValue"), _
                     Value1:=v
            Else
                'code for slice="all"
            End If

        End With
    End If
End Sub

Substitute your button formatting for the simple example here...

You can extend this to add the common parts of your existing filtering code, then use a Select Case on the value of b to call an appropriate Sub which performs the button-specific part.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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