注: コードエバーに関する質問を初めて投稿しました。私は VBA の正式なトレーニングを受けていません。私が学んだことはすべて、経験を通じて、または Web 上にあります。
私は雇用主のためにいくつかの仕事をしています。ユーザーがデザイン モードでフォームにアクセスできないようにするスケジューリング システムを作成しています。そのため、コードを使用してフォームを動的に作成しています (これが正しい用語であることを願っています)。コードでユーザー フォームを作成し、コードですべてのコントロールを追加します。コマンドボタンにクリックイベントがあり、ユーザーが入力したデータが保存され、フォームが閉じられます。
コードは (私にとっては) 複雑で、多くのシート、サブ ルーチン、およびクラスに分割されていますが、以下は、状況を説明する方法でいくつかのサブ ルーチンにまとめられたコードの一部です。このルーチンでは、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