简体   繁体   中英

Worksheet_Change setting target range is slow

I have an excel macro used to manage button visibility in Excel in the "Worksheet_Change" function based from another SO question here .

The problem is the although the macro works it makes updating the Excel sheet rather laggy. I have managed to pin down the slowness to a single line:

Set rUpdated = Range(Target.Dependents.Address)

This sets the range of cells updated to a variable to be iterated through later in the script. If I call a script with just this line I found this is where all the delay is. It seems a rather simple line, but is there a better way to do it?

Full disclosure:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rUpdated As Range
    Dim shp As Shape
    Dim rCell As Range
    Set rUpdated = Range(Target.Dependents.Address)
    If Not rUpdated Is Nothing Then
        For Each rCell In rUpdated
            If rCell.Column = 1 Then
                'Look at each shape in the sheet and cross-reference with rCell.
                For Each shp In Target.Parent.Shapes
                    If shp.TopLeftCell.Row = rCell.Row Then
                        shp.Visible = (rCell.Value <> "")
                        Exit For 'Exit the loop - the correct button has been found.
                    End If
                Next shp
            End If
        Next rCell
    End If
End Sub

So if i understood it correctly you want to make a button visible if the cell in the row as been changed. The only things i can think of to slow it down are, that is has to check many rCell or Shapes . I dont know what the structure of your document is. So my Idea would be: instead of going through all shapes every time, i would name them in a pattern that you can identify them with the row they are in so you use the name to address them (ie Row2 for the Button in Row 2 ).

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rUpdated As Range
    Dim shp As Shape
    Dim rCell As Range
    Dim obj As OLEObject

    Set rUpdated = Range(Target.Dependents.Address)
    If Not rUpdated Is Nothing Then
        For Each rCell In rUpdated
            If rCell.Column = 1 Then
                On Error Resume Next
                Set obj = ActiveSheet.OLEObjects("Row" & rCell.Row)
                If Err.Number = 0 Then
                    obj.Visible = (rCell.Value <> "")
                End If
            End If
        Next rCell
    End If
End Sub

I replaced that config with the following single line (and companion line):

On Error Resume Next
ActiveSheet.Shapes("buttonRow" & Target.Row).Visible = (ActiveSheet.Cells(Target.Row, 1).Value <> "")

However to get this to work I first needed to rename all my shapes. I used this function to do that:

Function renamebuttons()
    For Each shp In ActiveSheet.Shapes
        shp.name = "buttonRow" & shp.TopLeftCell.Row
    Next shp
End Function

I ran that function once and deleted it. Once done my shapes can now be referred to by name and I no longer incur the delay of cycling through every shape and every target dependent. The delay experienced in the worksheet is now minimal.

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