我有下面的代码,它是一个私有子,它是从一个公共子中的Userform3.show初始化的,据我所知,下面的代码可以工作,但是在完成时它不会返回到public sub。
请注意,当我更改sheet8.range(I16)的值时,会调用另一个私有子。但是我相信下面的代码就是问题所在。
有人可以建议我如何在完成后让私人子公司返回公共子公司吗?
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.Clear ' clear previous items (not to have "doubles")
.AddItem "BISSB"
.AddItem "MORIB"
.AddItem "RMIB"
End With
End Sub
Private Sub CommandButton1_Click()
If Me.ComboBox1.ListIndex = -1 Then
UserForm3.Hide
MsgBox "No board was selected, please re-run macro and select appropriate board"
Exit Sub
Else
Sheet8.Range("I16").Value = ComboBox1.Text
End If
End Sub
Private Sub CommandButton2_Click()
UserForm3.Hide
MsgBox "No board was selected, please re-run macro and select appropriate board"
End
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
MsgBox "No board was selected, please re-run macro and select appropriate board"
End
End If
End Sub
Public Sub
的开始Sub newResumeAssessment_Click()
Dim answer As Variant
Dim Proceed As Boolean
Dim Uname As String
If UCase(Sheets("Main Menu").Range("A1")) = "YES" Then
answer = 6
Else
answer = MsgBox("Click Yes to start a Business Case." & _
vbCrLf & "Click No to resume the Business Case." & vbCrLf & _
"Click Cancel to go back to the main menu." & vbNewLine & _
vbNewLine & "Please note, you will need to load the board submission " & _
"tracker before you start a new business case.", 35, "Business Case")
End If
If answer = 6 Then
UserForm3.Show
答案 0 :(得分:4)
第一件事,删除End
,无处不在。 End
是一个大的红色NUKE'EM ALL按钮,结束执行,然后 - End
执行后,你在调用堆栈中的位置无关紧要,对于 ,不再有调用堆栈 ;你的代码不再运行了,没有地方可以“返回”。
第二件事,请勿将状态保留在表单的默认实例中。像对象一样对待它,并在需要的时候New
新建一个实例 - 这样你就不需要被Unload
打扰和/或重置调用之间的状态: _Initialize
处理程序每次都会运行,并且不需要Clear
上一次调用中的项目,因为您每次都会使用新的实例。你这样做:
With New UserForm3 'UserForm_Initialize handler runs here
.Show 'UserForm_Activate handler runs here
'anything after .Show will only run after the form is closed
If Not .Cancelled Then
Sheet8.Range("I16").Value = .ComboBox1.Text
End If
End With 'UserForm_Terminate handler runs here
请注意,工作表不是由表单写的 - 它不是它的工作!那么我们如何让Cancelled
成员合法?
首先,您为事物命名,并使CommandButton1
为OkButton
,CommandButton2
为CancelButton
- 或者其他 - 只是不是Button1和Button2。< / p>
我喜欢您隐藏表单实例,而不是使用Unload Me
进行核心操作,但是显式正在使用默认值实例,这意味着上面的New UserForm3
代码不会隐藏正在显示的同一个实例。当您打算使用Me
时,从不使用默认实例限定成员通话。
换句话说:
UserForm3.Hide 'hides the default instance of UserForm3
Me.Hide 'hides whatever the current instance is
Hide 'same as Me.Hide
因此。添加一个Private isCancelled As Boolean
私有字段(模块级变量),然后公开一个返回它的Public Property Get Cancelled() As Boolean
公共属性getter:
Option Explicit
Private isCancelled As Boolean
Public Property Get Cancelled() As Boolean
Cancelled = isCancelled
End Property
接下来,让取消按钮设置标志:
Private Sub CancelButton_Click()
isCancelled = True
Me.Hide
End Sub
然后让QueryClose
处理程序也设置它 - 并尽可能使用现有的命名常量:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
isCancelled = True
Me.Hide
End If
End Sub
然后在OK按钮的处理程序中实现“happy-path”逻辑:
Private Sub OkButton_Click()
Me.Hide
End Sub
我会禁用“确定”按钮,直到用户进行选择 - 这样他们可以取消,x-out或进行有效选择!
Public Property Get SelectedBoard() As String
SelectedBoard = IIf(Me.ComboBox1.ListIndex = -1, vbNullString, Me.ComboBox1.Text)
End Property
Private Sub ComboBox1_Change()
ValidateForm
End Sub
Private Sub ValidateForm()
Me.OkButton.Enabled = (SelectedBoard <> vbNullString)
End Sub
Private Sub UserForm_Activate()
ValidateForm
End Sub
现在调用者看起来像这样:
With New UserForm3
.Show
If Not .Cancelled Then
Sheet8.Range("I16").Value = .SelectedBoard
Else
MsgBox "No board was selected, please re-run macro and select appropriate board"
End If
End With
现在你有一个表单,它只不过是代码的I / O设备,应该是它。而你正在使用对象而不是全局状态。
End
指令无论身在何处。UserForm3
(请改用UserForm3
)。Me
实例。New
成员以便访问调用代码,以抽象出调用者不需要关心的控件。答案 1 :(得分:0)
除非您以非模态方式显示表单,否则开头代码会一直停止,直到表单关闭