【问题标题】:Button loop repeats the same buttons many times, and .delete fails按钮循环多次重复相同的按钮,并且 .delete 失败
【发布时间】:2018-08-20 02:01:48
【问题描述】:

我在工作表上有一些使用宏创建的按钮,每次添加新项目时(本质上,它们是“删除此行”按钮和“创建列表”按钮)。

我使用For Each/Next 循环编写了一个宏来删除与我单击的形状范围相交的所有按钮,但它不起作用。

我添加了一堆Debug.Print 命令来查看发生了什么,结果让我很困惑。

For Each 循环一遍又一遍地点击相同的按钮,即使按钮被识别为与范围相交,删除功能也会失败,并且循环会再次重复相同的按钮。

我有 2 个问题:

  1. 有什么方法可以防止我的 For Each 循环一遍又一遍地重复相同的按钮?和
  2. 我做错了什么,按钮没有被删除?

这是我的代码:

Sub DeleteBtn()
    Dim i As Integer   'variable to keep track of how many loops we've done

    'returns the number of entries on my sheet
    NumTasks = Application.WorksheetFunction.CountA(Sheets("Tasks").Range("B7:B10000"))
    'uses the clicked shape to position the macro
    Set rctngl = ActiveSheet.Shapes(Application.Caller)
    'using topleftcell, this creates an address reference for the shape that called the macro
    With rctngl.TopLeftCell
        'sets this variable to hold the characters in the address for the clicked shape
        rctnglAdd = .Address
        ''''show shape address in immediate window
        Debug.Print "Rectangle location is " & rctnglAdd
        ''''sets this variable to hold the integer value of the clicked shape row
        rctnglRow = .Row
        ''''show shape row value in immediate window
        Debug.Print "Rectangle row is " & rctnglRow
        ''''sets a range to check against for button deletion
        Set btnRng = Sheets("Tasks").Range("$M$" & rctnglRow & ":$N$" & rctnglRow)
        ''''show range to check for intersect
        Debug.Print "Intersect Range is " & btnRng.Address
    End With

    i = 1     ''''sets i to 1 for the first time through the loop
    For Each btn In Sheets("Tasks").Buttons  ''''begin loop for every button in the sheet
        On Error Resume Next   'ignore errors
        newName = btn.Name    ''''This instance name is
        newAdd = btn.TopLeftCell.Address  ''''this instance address is
        Debug.Print "Round " & i & "!"   ''''Show loop number in immediate window
        ''''Show this instance address in immediate window
        Debug.Print "This Button's address = " & newAdd
        ''''Show this instance name in immediate window,
        Debug.Print "This Button's Name = " & newName
        ''''if this instance intersects with intersect range
        If Not Intersect(Range(newAdd), btnRng) Is Nothing Then
            ''''message to say button intersects
            Debug.Print "Button address " & newAdd & " intersects with delete range " & btnRng.Address
            ''''message to say button will be deleted
            Debug.Print "Deleting Button: " & """" & newName & """"
            ActiveSheet.Buttons("""" & newName & """").Delete ''''Original code was btn.delete
        End If
        i = i + 1     ''''increase i for next loop
    Next btn          ''''begin loop for next

End Sub

当我用 4 个按钮在工作表上运行即时窗口时,它显示的内容如下:

Rectangle location is $N$8
Rectangle row is 8
Intersect Range is $M$8:$N$8
Round 1!
This Button's address = $M$5
This Button's Name = Button 1139
Round 2!
This Button's address = $N$5
This Button's Name = Button 1144
Round 3!
This Button's address = $N$5
This Button's Name = Button 1144
Round 4!
This Button's address = $N$5
This Button's Name = Button 1144
Round 5!
This Button's address = $N$5
This Button's Name = Button 1144
Round 6!
This Button's address = $N$5
This Button's Name = Button 1144
Round 7!
This Button's address = $N$5
This Button's Name = Button 1144
Round 8!
This Button's address = $N$5
This Button's Name = Button 1144
Round 9!
This Button's address = $N$5
This Button's Name = Button 1144
Round 10!
This Button's address = $N$5
This Button's Name = Button 1144
Round 11!
This Button's address = $N$5
This Button's Name = Button 1144
Round 12!
This Button's address = $N$5
This Button's Name = Button 1144
Round 13!
This Button's address = $M$7
This Button's Name = Button 1175
Round 14!
This Button's address = $M$7
This Button's Name = Button 1175
Round 15!
This Button's address = $M$7
This Button's Name = Button 1175
Round 16!
This Button's address = $M$7
This Button's Name = Button 1175
Round 17!
This Button's address = $M$7
This Button's Name = Button 1175
Round 18!
This Button's address = $M$7
This Button's Name = Button 1175
Round 19!
This Button's address = $M$7
This Button's Name = Button 1175
Round 20!
This Button's address = $M$7
This Button's Name = Button 1175
Round 21!
This Button's address = $M$7
This Button's Name = Button 1175
Round 22!
This Button's address = $M$7
This Button's Name = Button 1175
Round 23!
This Button's address = $M$7
This Button's Name = Button 1175
Round 24!
This Button's address = $M$7
This Button's Name = Button 1175
Round 25!
This Button's address = $M$7
This Button's Name = Button 1175 
Round 26!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 27!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 28!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 29!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 30!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 31!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 32!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 33!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 34!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 35!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 36!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"
Round 37!
This Button's address = $M$5
This Button's Name = Button 1139
Round 38!
This Button's address = $N$5
This Button's Name = Button 1144
Round 39!
This Button's address = $M$7
This Button's Name = Button 1175
Round 40!
This Button's address = $M$8
This Button's Name = Button 1215
Button address $M$8 intersects with delete range $M$8:$N$8
Deleting Button: "Button 1215"

【问题讨论】:

  • 尝试向后循环并从最后一个删除到第一个
  • @Scott,请原谅我的无知,但我不知道如何向后运行。我试过:With Sheets("Tasks")For i = Sheets("Tasks").Buttons.count To 1 Step -1newAdd = Buttons(i).TopLeftCell.AddressIf Not Intersect(Range(newAdd), btnRng) Is Nothing Then.Buttons(i).DeleteEnd IfNext,但它没有用。 @GMalc,此代码的部分目的是删除可能彼此重叠的按钮。我不知道有一种方法可以轻松判断有多少按钮可能与某个范围相交。即使您对 $M$8 的解释是准确的,它仍然无法解释 $N$5、$M$7 等。

标签: vba excel for-loop button


【解决方案1】:

使用 MS Forms 按钮进行多次测试后,此代码对我有用。以下代码无法识别 ActiveX 按钮

注意,尤其是我删除了On Error Resume Next。你永远不能在该语句生效的情况下调试代码,因为它会忽略所有错误。

Sub buttons()

    Dim btnRng As Range
    Set btnRng = Sheets("Tasks").Range("A1:Z100")

    Dim i As Long
    i = 1     ''''sets i to 1 for the first time through the loop

    Dim btn As Object
    For Each btn In Sheets("Tasks").buttons  ''''begin loop for every button in the sheet


        Dim newName As String
        newName = btn.Name    ''''This instance name is

        Dim newAdd As String
        newAdd = btn.TopLeftCell.Address  ''''this instance address is

        Debug.Print "Round " & i & "!"   ''''Show loop number in immediate window
        ''''Show this instance address in immediate window
        Debug.Print "This Button's address = " & newAdd
        ''''Show this instance name in immediate window,
        Debug.Print "This Button's Name = " & newName
        ''''if this instance intersects with intersect range


        If Not Intersect(Sheets("Tasks").Range(newAdd), btnRng) Is Nothing Then
            ''''message to say button intersects
            Debug.Print "Button address " & newAdd & " intersects with delete range " & btnRng.Address
            ''''message to say button will be deleted
            Debug.Print "Deleting Button: " & """" & newName & """"
            btn.Delete
        End If

        i = i + 1     ''''increase i for next loop

    Next btn

End Sub

【讨论】:

  • 谢谢!这解决了我的问题。我最终使用我的“i”计数器对抗第二个“i2”变量来保存buttons.count,以防止循环在最后重新启动。 i = 1i2 = Sheets("Tasks").buttons.countFor Each btn In Sheets("Tasks").buttonsnewAdd = btn.TopLeftCell.AddressIf Not Intersect(Sheets("Tasks").Range(newAdd), btnRng) Is Nothing Thenbtn.DeleteEnd IfIf i >= i2 Then GoTo jmpIf i >= i2 Then GoTo jmpi = i + 1Next btnNext btnNext btnNext btn@9876543333433434345谢谢你谢谢你@9876!
猜你喜欢
  • 2023-03-05
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
相关资源
最近更新 更多