Excel 将代码放入循环中,以在任何鼠标单击后退出循环
在用户窗体上,我通过切换其可视性来关闭/打开一个帧。它闪烁可变次数,然后停止,但在闪烁之间,它会检查用户活动。如果在窗体或包含的任何控件上的任何位置单击鼠标,则闪烁立即停止 这就是我的眼罩的样子Excel 将代码放入循环中,以在任何鼠标单击后退出循环,excel,vba,userform,Excel,Vba,Userform,在用户窗体上,我通过切换其可视性来关闭/打开一个帧。它闪烁可变次数,然后停止,但在闪烁之间,它会检查用户活动。如果在窗体或包含的任何控件上的任何位置单击鼠标,则闪烁立即停止 这就是我的眼罩的样子 For i = 1 To numberOfBlinks <blink twice> DoEvents If <click detected> Then Exit Sub Next i 对于i=1到numberOfBlinks 多芬特 如果是
For i = 1 To numberOfBlinks
<blink twice>
DoEvents
If <click detected> Then Exit Sub
Next i
对于i=1到numberOfBlinks
多芬特
如果是,则退出Sub
接下来我
除了
部分外,其他一切正常。如何从循环内部执行此操作?是否尝试将mouseclick事件中的全局布尔变量更改为true(默认为false)
然后尝试在
中检查此全局布尔变量是否为真这似乎可以正常工作,但似乎有很多代码只是为了检测鼠标点击。例如,我认为应该可以创建一个包含所有表单控件的类,这样我就可以一次检测到对其中任何一个控件的单击,而不必单独检查每种控件。我做不到这一点,我希望有人能改进这一点
重申一下:在用户表单上,一个名为mapFrame的大框架可以容纳任意数量的其他框架和标签,所有包含的框架可以容纳任意数量的其他框架和标签,但这与嵌套的深度一样。我想启动一个循环(在本例中,循环会关闭和打开控件,但它可能是任何其他循环),并等待用户单击包含的任何帧或标签以发出退出循环的信号。我还想获取被单击的控件的名称
我采纳了Therelmarv的建议,并使用单击来设置一个公共布尔值,该布尔值在循环中得到测试
在新的类模块中:
Option Explicit
Public WithEvents classLabels As msForms.Label
Private Sub classLabels_Click()
clickedControlName = "" '<== Public String
With classLabels
If .Parent.Name = "mapFrame" Or _
.Parent.Parent.Name = "mapFrame" Then
isClickDetected = True '<== Public Boolean
clickedControlName = .Name
End If
End With
End Sub
Option Explicit
Public WithEvents classFrames As msForms.Frame
Private Sub classFrames_Click()
clickedControlName = "" '<== Public String
With classFrames
If .Name = "mapFrame" Or _
.Parent.Name = "mapFrame" Or _
.Parent.Parent.Name = "mapFrame" Then
isClickDetected = True '<== Public Boolean
clickedControlName = .Name
End If
End With
End Sub
选项显式
Public,事件类标签为msForms.Label
私有子类标签\u单击()
clickedControlName=“”鼠标单击可以是数百个控件中的任意一个。我猜我必须使用类模块来检测点击,但是有没有更简单的方法?如果不是的话,有人能推荐一个代码片段吗?你真的在Excel用户表单上有数百个控件吗?是的,我有。大容器框架中有一张地图,数百个子控件是地图上的特征。这听起来像是一个视觉测试,如果出现某个数字,他们会要求你单击鼠标:p这是一个好问题。可能是一个设置触发器的API函数或其他什么。事实上,我期待着一个好的答案。顺便说一句,我认为,你对第一个答案的评论也可能出现在你的问题中,以澄清问题。
Option Explicit
Dim frames() As New clsFrames
Dim labels() As New clsLabels
Private Sub createFrameListeners()
Dim ctl As msForms.Control
Dim frameCount as Long
For Each ctl In Me.Controls
' Debug.Print TypeName(ctl): Stop
If TypeName(ctl) = "Frame" Then
frameCount = frameCount + 1
ReDim Preserve frames(1 To frameCount)
'Create the Frame Listener objects
Set frames(frameCount).classFrames = ctl
End If
Next ctl
End Sub
Private Sub createLabelListeners()
Dim ctl As msForms.Control
Dim LabelCount as Long
For Each ctl In Me.Controls
' Debug.Print TypeName(ctl): Stop
If TypeName(ctl) = "Label" Then
LabelCount = LabelCount + 1
ReDim Preserve labels(1 To LabelCount)
'Create the Label Listener objects
Set labels(LabelCount).classLabels = ctl
End If
Next ctl
End Sub
Function blinkThisControl(ctrl As Control, ByVal blinkCount As Long)
isClickDetected = False
Dim i As Integer
For i = 1 To blinkCount
' <blink ctrl twice>
DoEvents
If isClickDetected Then Exit Function
'name of clicked control will be in clickedControlName
Next i
End Function
Private Sub userform_initialize()
Call createFrameListeners
Call createLabelListeners
' do other stuff
End Sub