注意:第一次發佈有關代碼的問題。我沒有接受VBA的正式培訓,我所學到的一切都是通過經驗或在網絡上。Dyamically創建UserForm,命令按鈕和文本框:不註冊文本框更改
我正在爲僱主做一些工作。我正在創建一個調度系統,我不希望用戶在設計模式下訪問表單。所以我通過代碼動態地創建表單(我希望這是正確的術語)。我通過代碼創建一個用戶表單,並通過代碼添加所有控件。我在命令按鈕上有一個點擊事件,用戶輸入的數據存儲在這個事件按鈕上,表單關閉。代碼很複雜(對我來說)並分解成許多工作表,子例程和類,但下面的代碼片段組合成幾個子例程,以解釋情況。在這個例程中,一個表單顯示在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 = "!%[email protected]")
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 <> "!%[email protected]" 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
謝謝您的評論:)雖然這在我的文章中肯定不是很清楚,'_Exit'事件與'btnSave'綁定,因爲表格我將使用「父母」幾個文本框。在這種形式下,每個文本框對輸出做出貢獻,因此我想觸發'btnSave_Exit'(或'_Click')事件中的代碼。但是,即使將'_Exit'事件切換到'txtTest',並且在運行時在文本框中進行了用戶更改,消息框仍會在'_Exit'事件中讀取原始(預先更改)的文本框文本。我需要消息框在文本框中註冊更改。思考? – geekeel
@geekeel,請參閱我提供的解決方案的答案。 –
這很好。謝謝 – geekeel