VBA用户窗体重复点击事件代码简化求助(含尝试代码)
VBA UserForm 重复点击事件简化方案
作为VBA新手,在为UserForm编写代码时,编写了5个逻辑完全一致的chkAddleave点击事件,希望简化为调用单个私有子过程但未能实现。
原重复代码
Private Sub chkAddleave1_Click() With SickLeaveForm If chkAddleave1 = True Then .txtShiftDate1.Enabled = True .txtShiftDate1.BackColor = &H80000005 .OptionButtonAM1.Enabled = True .OptionButtonPM1.Enabled = True .OptionButtonND1.Enabled = True Else .txtShiftDate1.Enabled = False .txtShiftDate1.BackColor = &H8000000A .OptionButtonAM1.Enabled = False .OptionButtonPM1.Enabled = False .OptionButtonND1.Enabled = False End If End With End Sub Private Sub chkAddleave2_Click() With SickLeaveForm If chkAddleave2 = True Then .txtShiftDate2.Enabled = True .txtShiftDate2.BackColor = &H80000005 .OptionButtonAM2.Enabled = True .OptionButtonPM2.Enabled = True .OptionButtonND2.Enabled = True Else .txtShiftDate2.Enabled = False .txtShiftDate2.BackColor = &H8000000A .OptionButtonAM2.Enabled = False .OptionButtonPM2.Enabled = False .OptionButtonND2.Enabled = False End If End With End Sub Private Sub chkAddleave3_Click() With SickLeaveForm If chkAddleave3 = True Then .txtShiftDate3.Enabled = True .txtShiftDate3.BackColor = &H80000005 .OptionButtonAM3.Enabled = True .OptionButtonPM3.Enabled = True .OptionButtonND3.Enabled = True Else .txtShiftDate3.Enabled = False .txtShiftDate3.BackColor = &H8000000A .OptionButtonAM3.Enabled = False .OptionButtonPM3.Enabled = False .OptionButtonND3.Enabled = False End If End With End Sub Private Sub chkAddleave4_Click() With SickLeaveForm If chkAddleave4 = True Then .txtShiftDate4.Enabled = True .txtShiftDate4.BackColor = &H80000005 .OptionButtonAM4.Enabled = True .OptionButtonPM4.Enabled = True .OptionButtonND4.Enabled = True Else .txtShiftDate4.Enabled = False .txtShiftDate4.BackColor = &H8000000A .OptionButtonAM4.Enabled = False .OptionButtonPM4.Enabled = False .OptionButtonND4.Enabled = False End If End With End Sub Private Sub chkAddleave5_Click() With SickLeaveForm If chkAddleave5 = True Then .txtShiftDate5.Enabled = True .txtShiftDate5.BackColor = &H80000005 .OptionButtonAM5.Enabled = True .OptionButtonPM5.Enabled = True .OptionButtonND5.Enabled = True Else .txtShiftDate5.Enabled = False .txtShiftDate5.BackColor = &H8000000A .OptionButtonAM5.Enabled = False .OptionButtonPM5.Enabled = False .OptionButtonND5.Enabled = False End If End With End Sub
尝试的错误代码
Private Sub EnableAddLeave() Dim i As Integer Dim chkAddleave As MSForms.CheckBox Dim txtshiftdate As MSForms.textbox Dim OptionButtonAM As MSForms.OptionButton Dim OptionButtonPM As MSForms.OptionButton Dim OptionButtonND As MSForms.OptionButton For i = 1 To 5 With SickLeaveForm If chkAddleave(i) = True Then txtshiftdate(i).Enabled = True txtshiftdate(i).BackColor = &H80000005 OptionButtonAM(i).Enabled = True OptionButtonPM(i).Enabled = True OptionButtonND(i).Enabled = True Else txtshiftdate(i).Enabled = False txtshiftdate(i).BackColor = &H8000000A OptionButtonAM(i).Enabled = False OptionButtonPM(i).Enabled = False OptionButtonND(i).Enabled = False End If End With Next i End Sub
错误原因
你尝试的代码中,直接使用chkAddleave(i)这类索引方式是错误的——VBA中这些控件并非数组,不能直接通过索引访问,必须通过UserForm的Controls集合,用控件名称拼接字符串的方式获取对应控件。
两种简化方案
方案1:传入索引参数的通用子过程
先编写一个接收索引参数的通用处理子过程,再修改所有点击事件调用该过程:
' 通用处理子过程,接收索引参数 Private Sub HandleAddLeaveCheck(ByVal index As Integer) With SickLeaveForm ' 通过Controls集合获取对应索引的控件 Dim chk As MSForms.CheckBox Set chk = .Controls("chkAddleave" & index) Dim txtDate As MSForms.TextBox Set txtDate = .Controls("txtShiftDate" & index) Dim optAM As MSForms.OptionButton Set optAM = .Controls("OptionButtonAM" & index) Dim optPM As MSForms.OptionButton Set optPM = .Controls("OptionButtonPM" & index) Dim optND As MSForms.OptionButton Set optND = .Controls("OptionButtonND" & index) ' 根据复选框状态设置控件属性 If chk.Value = True Then txtDate.Enabled = True txtDate.BackColor = &H80000005 optAM.Enabled = True optPM.Enabled = True optND.Enabled = True Else txtDate.Enabled = False txtDate.BackColor = &H8000000A optAM.Enabled = False optPM.Enabled = False optND.Enabled = False End If End With End Sub ' 修改原点击事件,调用通用子过程 Private Sub chkAddleave1_Click() HandleAddLeaveCheck 1 End Sub Private Sub chkAddleave2_Click() HandleAddLeaveCheck 2 End Sub Private Sub chkAddleave3_Click() HandleAddLeaveCheck 3 End Sub Private Sub chkAddleave4_Click() HandleAddLeaveCheck 4 End Sub Private Sub chkAddleave5_Click() HandleAddLeaveCheck 5 End Sub
方案2:自动识别触发控件的灵活方案
利用Application.Caller获取触发事件的控件名称,自动提取索引,无需手动传入参数,后续新增复选框时只需复制点击事件代码即可:
' 通用处理子过程,自动识别触发控件 Private Sub HandleAddLeaveCheck() ' 获取触发事件的控件名称 Dim callerName As String callerName = Application.Caller ' 提取名称中的数字索引 Dim index As Integer index = Val(Right(callerName, Len(callerName) - Len("chkAddleave"))) With SickLeaveForm Dim chk As MSForms.CheckBox Set chk = .Controls(callerName) Dim txtDate As MSForms.TextBox Set txtDate = .Controls("txtShiftDate" & index) Dim optAM As MSForms.OptionButton Set optAM = .Controls("OptionButtonAM" & index) Dim optPM As MSForms.OptionButton Set optPM = .Controls("OptionButtonPM" & index) Dim optND As MSForms.OptionButton Set optND = .Controls("OptionButtonND" & index) If chk.Value = True Then txtDate.Enabled = True txtDate.BackColor = &H80000005 optAM.Enabled = True optPM.Enabled = True optND.Enabled = True Else txtDate.Enabled = False txtDate.BackColor = &H8000000A optAM.Enabled = False optPM.Enabled = False optND.Enabled = False End If End With End Sub ' 所有点击事件只需调用该子过程,内容完全一致 Private Sub chkAddleave1_Click() HandleAddLeaveCheck End Sub Private Sub chkAddleave2_Click() HandleAddLeaveCheck End Sub Private Sub chkAddleave3_Click() HandleAddLeaveCheck End Sub Private Sub chkAddleave4_Click() HandleAddLeaveCheck End Sub Private Sub chkAddleave5_Click() HandleAddLeaveCheck End Sub
内容的提问来源于stack exchange,提问作者Cealizar Serrano
相关产品推荐
相关产品推荐

