简体   繁体   English

excel vba - 有没有办法防止宏按钮垃圾邮件?

[英]excel vba - Is there a way to prevent macro button spamming?

I have a sheet with several macro buttons that all do slightly different things and all is well, unless the user spam clicks different buttons somewhat quickly. 我有一张带有几个宏按钮的工作表,它们都做了一些略有不同的事情,一切都很顺利,除非用户垃圾邮件有点快速点击不同的按钮。

I'm not experienced enough to know if this is a common issue or something with the way my code works, but it seems that everything works correctly if a macro button is clicked and properly executes before another is clicked. 我没有足够的经验来知道这是一个常见的问题,还是我的代码工作方式的问题,但是如果单击一个宏按钮并在点击另一个宏按钮之前正确执行,似乎一切正常。 Even spam clicking the same macro button seems to work well, but the moment two or more are clicked in rapid succession, the code doesn't execute properly. 即使垃圾邮件点击相同的宏按钮似乎也能正常工作,但是当快速连续点击两个或更多时,代码就无法正常执行。

The code itself just finds cells with particular values, and adds or deletes rows and sometimes copies and pastes from other areas of the sheet. 代码本身只是查找具有特定值的单元格,并添加或删除行,有时还会从工作表的其他区域复制和粘贴。 For example, if you were to click button X to find part X of the worksheet and add a row below it, and spam click button Y to find part Y of the worksheet and delete a row above it, button Y will fail at finding the cell it needs to find (even though it exists) and trigger an error messagebox telling the user that part Y seems to be missing, and meanwhile button X will have some weird issues itself like deleting the wrong row as if it anticipated/compensated for what it expected Y to do. 例如,如果您单击按钮X以查找工作表的X部分并在其下方添加一行,并且垃圾邮件单击按钮Y以查找工作表的Y部分并删除其上方的行,则按钮Y将无法找到它需要找到的单元格(即使它存在)并触发一个错误消息框,告诉用户Y部分似乎丢失了,同时按钮X会有一些奇怪的问题,就像删除错误的行一样,好像它预期/补偿了什么它希望Y做。

I tried using CommandButton1.Enabled = False for every command button at the start of macro and enabling the buttons again at the end of every macro, but I can still spam click the buttons regardless during the macro execution. 我尝试在宏的开始处为每个命令按钮使用CommandButton1.Enabled = False ,并在每个宏的末尾再次启用按钮,但我仍然可以在宏执行期间点击按钮。

Is there an easy way to prevent other macro buttons from being clicked until the current macro code has run? 有没有一种简单的方法可以阻止其他宏按钮被点击,直到当前的宏代码运行? I've tried disabling and enabling the buttons, I've tried adding wait times. 我尝试过禁用和启用按钮,我尝试添加等待时间。 If I can't solve this issue I will likely resort to saving a duplicate hidden worksheet that, upon error, is unhidden, and the problem worksheet deleted, another 'backup' copy of the duplicate is created and hidden, all the while the user is notified not to spam the macro buttons. 如果我无法解决这个问题,我可能会求助于保存一个重复的隐藏工作表,如果出现错误,该工作表被取消隐藏,并且问题工作表被删除,则会创建并隐藏该副本的另一个“备份”副本,同时用户被通知不要垃圾宏按钮。

I recommend using a UserForm to host your activeX controls, or if you just have one or two buttons, replace them with hyperlinks on the sheet and use the following code in a worksheet.followhyperlink event to check which hyperlink was clicked: 我建议使用UserForm来托管您的activeX控件,或者如果您只有一个或两个按钮,请将它们替换为工作表上的超链接,并使用workheet.followhyperlink事件中的以下代码来检查单击了哪个超链接:

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
    If Target.Range.Address(False, False) = "A1" Then MsgBox ("Woah I clicked cell A1!")
End Sub

If you have a userForm with buttons on, then you can make each button click hide the form until the macro is complete automatically: 如果你有一个带有按钮的userForm,那么你可以点击每个按钮隐藏表单,直到宏自动完成:

Private Sub CommandButton1_Click()
UserForm1.Hide
    ' Do the macro stuff
UserForm1.Show
End Sub

This is based on the observation that: 这是基于以下观察:

What you cannot see, you cannot click. 什么你看不到,你不能点击。

All buttons whether they are forms buttons or ActiveX buttons or AutoShapes are Shapes . 所有按钮无论是表单按钮还是ActiveX按钮或自选图形都是Shapes All Shapes are either Visible or not Visible . 所有Shapes都是Visible或不Visible

If a Shape is not Visible , it cannot be clicked. 如果ShapeVisible ,则无法单击它。 Therefore at the beginning of each button sub include a call to: 因此,在每个按钮子的开头包括一个调用:

Sub HideAllButtons()
    Dim s As Shape
    For Each s In ActiveSheet.Shapes
        s.Visible = False
    Next s
End Sub

and at the end of the button code include a call to: 并且在按钮代码的末尾包括对以下内容的调用:

Sub ShowAllButtons()
    Dim s As Shape
    For Each s In ActiveSheet.Shapes
        s.Visible = True
    Next s
End Sub

Thus while any button is running, the user is "locked out" from clicking any other button. 因此,当任何按钮运行时,用户被“锁定”而不能点击任何其他按钮。

Add a check at the start of each button to a global variable. 在每个按钮的开头添加一个检查到全局变量。 Only run the button's code if no other button is running at the same time. 如果没有其他按钮同时运行,则仅运行按钮的代码。

In case the code is taking a longer time to run I've added icon changes to show that the program is busy while code is being run, as suggested by Chronocidal. 如果代码运行时间较长,我已经添加了图标更改,以显示程序在运行代码时正忙,正如Chronocidal所建议的那样。

Public Running As Boolean

Private Sub CommandButton1_Click()
If Running = False Then
    Running = True
    Application.Cursor = xlWait        

    ' Your Buttons Code

    Running = False
    Application.Cursor = xlDefault
Else ' (Optional)
    MsgBox ("I'm busy, try again later!")
End If

End Sub

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

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