2

注意:第一次发布关于代码的问题。我没有接受过正式的 VBA 培训,我所学到的一切都是通过经验或网络获得的。

我正在为雇主做一些工作。我正在创建一个调度系统,我不希望用户在设计模式下可以访问表单。所以我通过代码动态地创建表单(我希望这是正确的术语)。我通过代码创建用户表单,并通过代码添加所有控件。我在命令按钮上有一个单击事件,在该事件上存储用户输入的数据并关闭表单。

代码很复杂(对我来说)并且分成许多表、子例程和类,但下面是一些代码片段,它们以应该可以解释情况的方式组合成几个子例程。在此例程中,在 WorkSheet_Selection_Change 事件上显示一个表单。该表单由一个文本框和一个命令按钮组成。单击命令按钮时,会出现一个消息框,显示文本框中的文本。

表单很好,点击事件“触发”。但是,有关文本框中更改的事件似乎不会触发,即。如果文本框中的文本发生更改,则这些更改不会出现在消息框中。如果我在关闭表单之前(在单击命令按钮之前)停止该过程,并进入新创建的表单的代码并从表单本身运行代码,那么一切都会正常运行。

当动态编写代码时,是什么阻止了文本框事件的触发?我错过了什么吗?下面提供了代码。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Call Add_Form
End Sub


Private Sub Add_Form()
        Dim VBProj As VBIDE.VBProject
        Dim VBComp As VBIDE.VBComponent

        Set VBProj = ActiveWorkbook.VBProject
        VBProj.VBComponents.Add (vbext_ct_MSForm)

        Dim myForm As Object
        Set myForm = ThisWorkbook.VBProject.VBComponents("UserForm1")

        Call AddControlToForm(ThisWorkbook.VBProject. _
                      VBComponents("UserForm1"), "CommandButton", 60, _
                      20, 135, 90, "btnSave", "Save")
        Call AddControlToForm(ThisWorkbook.VBProject. _
                      VBComponents("UserForm1"), "TextBox", 80, _
                      20, 90, 90, "txtTest")

        Dim Line As Integer
        Line = myForm.CodeModule.CountOfLines

        myForm.CodeModule.InsertLines Line + 1, "Private Sub UserForm_Initialize()"
        myForm.CodeModule.InsertLines Line + 2, "Me.txtTest.SetFocus"
        myForm.CodeModule.InsertLines Line + 3, "Me.txtTest.Text = ""Change Text"""
        myForm.CodeModule.InsertLines Line + 4, "End Sub"


        Dim NewButton As MSForms.CommandButton
        Set NewButton = myForm.Designer.Controls.Item(btnSave)

        myForm.CodeModule.InsertLines Line + 5, "Private Sub btnSave_Click()"
        myForm.CodeModule.InsertLines Line + 6, "  Unload me"
        myForm.CodeModule.InsertLines Line + 7, "End Sub"

        myForm.CodeModule.InsertLines Line + 8, "Private Sub btnSave" & _
                "_Exit(ByVal Cancel As MSForms.ReturnBoolean)"
        myForm.CodeModule.InsertLines Line + 9, "    MsgBox(UserForm1.txtTest.Text)"
        myForm.CodeModule.InsertLines Line + 10, "End Sub"
    Call ShowForm("UserForm1")
    Call RemoveForm("UserForm1")
End Sub

Public Sub AddControlToForm(objForm As Object, strCtlType As String, intWidth As _
                        Integer, intHeight As Integer, intTop As Integer, _
                        intLeft As Integer, strName As String, _
                        Optional strCaption As String = "!%!@")
    Dim objControl As Object
    Set oForm = objForm

    Set objControl = oForm.Designer.Controls.Add("Forms." & strCtlType & ".1")
    With objControl
        .Name = strName
        .Width = intWidth
        .Height = intHeight
        .Top = intTop
        .Left = intLeft
    End With

    If strCaption <> "!%!@" Then
        With objControl
            .Caption = strCaption
        End With
    End If


End Sub

Private Sub ShowForm(strFormName As String)

    Dim objForm As Object

    Set objForm = ThisWorkbook.VBProject.VBComponents(strFormName)

    VBA.UserForms.Add(objForm.Name).Show

End Sub


Private Sub RemoveForm(strFormName As String)
    Dim VBProj As VBIDE.VBProject
    Dim VBComp As VBIDE.VBComponent

    Set VBProj = ActiveWorkbook.VBProject
    Set VBComp = VBProj.VBComponents(strFormName)
    VBProj.VBComponents.Remove VBComp
End Sub
4

1 回答 1

0

根据您的问题中的信息,您想在有人退出名称为的文本框后触发事件txtTest。与此同时,您制作了exit eventbtn_Save button. 因此,您需要更改此行:

    myForm.CodeModule.InsertLines Line + 8, "Private Sub btnSave" & _
            "_Exit(ByVal Cancel As MSForms.ReturnBoolean)"

进入这个:

    myForm.CodeModule.InsertLines Line + 8, "Private Sub txtTest" & _
            "_Exit(ByVal Cancel As MSForms.ReturnBoolean)"

编辑在下面的一些评论之后,我现在明白了。所以,改变这一行:

myForm.CodeModule.InsertLines Line + 9, "    MsgBox(UserForm1.txtTest.Text)"

进入这个:

myForm.CodeModule.InsertLines Line + 9, "    MsgBox Me.txtTest.Text"

这似乎UserForm1是一个令人困惑的问题,因此您可以以这种建议的方式设置对用户表单的引用。这解决了我的测试代码中的问题。

顺便说一句,你的问题写得很好。如果您在网络的一些支持下自己编写了此代码,我只能祝贺您。:) 继续编程!

于 2013-08-22T17:13:52.807 回答