UserForm_Initialize creates Late Bound Controls BUT btnClose_*******() does nothing!

shell_l_d

Board Regular
Joined
Jun 25, 2010
Messages
73
I'm trying to get around VB library/reference issues by using late binding of controls/activex objects on a userform (instead of a worksheet) I cant get my button Click methods to work at all. I've even added a msgbox in its code to see if it gets called & it doesnt.

Any ideas please?

I have a blank userform called 'ufrmUpdateData' & it has this code (so far):
Rich (BB code):
'---------------------------------------------------------------------------------------
' Module    : UserForm2
' Purpose   : USER FORM CODE
'---------------------------------------------------------------------------------------

Private Const MODULE_NAME As String = "UserForm2."

Private Sub btnClose_Click()
    MsgBox "clicked close"
    'ufrmUpdateData.Hide
    Unload Me
End Sub
Rich (BB code):
 Private Sub btnUpdateData_Click()
    MsgBox "clicked update data now"
End Sub

Private Sub UserForm_Initialize()
'---------------------------------------------------------------------------------------
' Procedure  : UserForm_Initialize
' Purpose    : Creates controls (labels,combobox,buttons) on fly using
'              late binding so uses correct VB library/reference
'              DTPicker late binding code per post#5 by timbereng in:
'              http://www.access-programmers.co.uk/forums/showthread.php?t=164021
'---------------------------------------------------------------------------------------

    ' For Error Reporting
    Dim sErrorDescr As String
    Const sErrSource As String = MODULE_NAME & "UserForm_Initialize"
    On Error GoTo Error_In_UserForm_Initialize

    ' Late binding (As Object) of controls so uses correct VB library/reference
    Dim oLblStartDate As Object, oLblEndDate As Object, oLblFilterOn As Object
    Dim oCboFilterOn As Object
    Dim oBtnUpdateData As Object, oBtnClose As Object
    Dim oDtpStartDate As Object, oDtpEndDate As Object
    Dim bHasDtPicker As Boolean
    
    ' Create control objects
    Set oLblStartDate = Me.Controls.Add("Forms.Label.1", "lblStartDate", True)
    Set oLblEndDate = Me.Controls.Add("Forms.Label.1", "lblEndDate", True)
    Set oLblFilterOn = Me.Controls.Add("Forms.Label.1", "lblFilterOn", True)
    Set oCboFilterOn = Me.Controls.Add("Forms.ComboBox.1", "cboFilterOn", True)
    Set oBtnUpdateData = Me.Controls.Add("Forms.CommandButton.1", "btnUpdateData", True)
    Set oBtnClose = Me.Controls.Add("Forms.CommandButton.1", "btnClose", True)
    
    ' Formatting properties
    With oLblStartDate
        .TabIndex = 0
        .Top = 36
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "Start Date:"
        .Font.Size = 12
    End With
    With oLblEndDate
        .TabIndex = 2
        .Top = 84
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "End Date:"
        .Font.Size = 12
    End With
    With oLblFilterOn
        .TabIndex = 4
        .Top = 132
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "Filter On:"
        .Font.Size = 12
    End With
    With oCboFilterOn
        .TabIndex = 5
        .Top = 132
        .Left = 120
        .Height = 22
        .Width = 132
        .Font.Size = 12
        .AddItem ("CallTime")
        .AddItem ("TechComp")
        .AddItem ("CloseDate")
        .AddItem ("Calc Compl Date")
        .ListIndex = 0      ' default value
    End With
    With oBtnUpdateData
        .TabIndex = 6
        .Top = 186
        .Left = 30
        .Height = 36
        .Width = 126
        .Caption = "Update Data Now"
        .Font.Size = 12
    End With
    With oBtnClose
        .TabIndex = 7
        .Top = 186
        .Left = 198
        .Height = 36
        .Width = 126
        .Caption = "Close"
        .Font.Size = 12
    End With
    
    '---------------------------
    ' DTPicker's
    '---------------------------
    On Error Resume Next
    Set oDtpStartDate = Me.Controls.Add("MSComCtl2.DTPicker", "dtpStartDate", True)
    Set oDtpEndDate = Me.Controls.Add("MSComCtl2.DTPicker", "dtpEndDate", True)
     
    ' If DTPicker doesnt exist, use text boxes instead
    If Err.Number <> 0 Or oDtpStartDate Is Nothing Then
        On Error GoTo Error_In_UserForm_Initialize
        bHasDtPicker = False
        Set oDtpStartDate = Me.Controls.Add("Forms.TextBox.1", "dtpStartDate", True)
        Set oDtpEndDate = Me.Controls.Add("Forms.TextBox.1", "dtpEndDate", True)
        oDtpStartDate.ControlTipText = "Enter date in format: dd mmm yyyy   Eg: 01 Apr 2010"
        oDtpEndDate.ControlTipText = "Enter date in format: dd mmm yyyy   Eg: 31 Mar 2010"
    Else
        bHasDtPicker = True
        oDtpStartDate.Format = dtpLongDate
        oDtpEndDate.Format = dtpLongDate
    End If
    
    ' Formatting properties
    With oDtpStartDate
        .TabIndex = 1
        .Top = 84
        .Left = 120
        .Height = 22
        .Width = 210
        .Font.Size = 12
    End With
    With oDtpEndDate
        .TabIndex = 3
        .Top = 36
        .Left = 120
        .Height = 22
        .Width = 210
        .Font.Size = 12
    End With
    
' ===== Exit Handler =====
Exit_UserForm_Initialize:
    oLblStartDate = Nothing
    oLblEndDate = Nothing
    oLblFilterOn = Nothing
    oCboFilterOn = Nothing
    oBtnUpdateData = Nothing
    oBtnClose = Nothing
    oDtpStartDate = Nothing
    oDtpEndDate = Nothing
    Exit Sub

' ===== ERROR HANDLER =====
Error_In_UserForm_Initialize:
    
    With Err
        sErrorDescr = "Error '" & .Number & " " & _
            .Description & "' occurred in " & sErrSource & _
            IIf(Erl <> 0, " at line " & CStr(Erl) & ".", ".")
    End With

    Select Case MsgBox(sErrorDescr, vbAbortRetryIgnore, "Error in " & sErrSource)
        Case vbRetry
            Resume
        Case vbIgnore
            Resume Next
        Case Else
            Resume Exit_UserForm_Initialize
        End
    End Select

End Sub
 
Last edited:
Late bound UserForm & Controls BUT combobox has no values in drop-down ?

Ok I managed to get around that issue by making the UserForm itself also created using late binding (instead of just the controls on it).

However now I'm presented with another problem...
The combobox never fills with values, if click drop-down arrow, it's all empty.

Any ideas please?

Code:
'---------------------------------------------------------------------------------------
' Module    : Module1
' Purpose   : USER FORM CODE
'---------------------------------------------------------------------------------------

Private Const scModuleName As String = "Module1."
Private Const scUserForm As String = "ufrmUpdateData"
Private Const icUserForm As Integer = 3

Public Sub DeleteUserForm()
'---------------------------------------------------------------------------------------
' Procedure  : DeleteUserForm
' Purpose    : Deletes all userforms on ThisWorkbook
'---------------------------------------------------------------------------------------
    On Error Resume Next
    
    Dim oUserForm As Object
    
    ' Remove all userforms (only ever want 1 - created on the fly)
    ThisWorkbook.Activate
    With ActiveWorkbook.VBProject.VBComponents
        For i = .Count To 1 Step -1
            Set oUserForm = .Item(i)
            If oUserForm.Type = icUserForm Then
                .Remove oUserForm
            End If
        Next i
    End With
    
End Sub

Public Sub CreateUserForm()
'---------------------------------------------------------------------------------------
' Procedure  : CreateUserForm
' Purpose    : Creates a userform & it's controls (labels,combobox,buttons) on the fly using
'              late binding so uses correct VB libraries/references.
'              Extracts by faq707-5757: http://www.tek-tips.com/faqs.cfm?fid=5757
'              Extracts by timbereng (#5): http://www.access-programmers.co.uk/forums/showthread.php?t=164021
'---------------------------------------------------------------------------------------

    ' For Error Reporting
    Dim sErrorDescr As String
    Const sErrSource As String = scModuleName & "CreateUserForm"
    On Error GoTo Error_In_CreateUserForm

    ' Late binding (As Object) of controls so uses correct VB library/reference
    Dim oUserForm As Object
    Dim oLblStartDate As Object, oLblEndDate As Object, oLblFilterOn As Object
    Dim oCboFilterOn As Object
    Dim oCmdUpdateData As Object, oCmdClose As Object
    Dim oDtpStartDate As Object, oDtpEndDate As Object
    Dim bHasDtPicker As Boolean
    
    ' Create the UserForm
    Set oUserForm = ThisWorkbook.VBProject.VBComponents.Add(icUserForm)
    
    ' NOTE: .Name may error if userform existed but was deleted & no close or save has taken place since
    On Error Resume Next
    oUserForm.Name = scUserForm
    If Err.Number <> 0 Then
        Select Case Err.Number
           Case Is = 75, 438, 50135
                ' 75: Path/File access error
                ' 438:   Object doesn't support this property or method.
                ' 50135: Application-defined or object-defined error.
                MsgBox "Unable to create Update Data Criteria user entry form." _
                        & vbCrLf & "Please close workbook & re-open."
                GoTo Exit_CreateUserForm
           Case Else
                ' An unknown error was encountered, so alert the user
                GoTo Error_In_CreateUserForm
        End Select
    End If
    On Error GoTo Error_In_CreateUserForm
    
    With oUserForm
        .Properties("Caption") = "Update Data Criteria"
        .Properties("Width") = 366.75
        .Properties("Height") = 272.25
    End With

    ' Create control objects
    Set oLblStartDate = oUserForm.Designer.Controls.Add("Forms.Label.1", "lblStartDate", True)
    Set oLblEndDate = oUserForm.Designer.Controls.Add("Forms.Label.1", "lblEndDate", True)
    Set oLblFilterOn = oUserForm.Designer.Controls.Add("Forms.Label.1", "lblFilterOn", True)
    Set oCboFilterOn = oUserForm.Designer.Controls.Add("Forms.ComboBox.1", "cboFilterOn", True)
    Set oCmdUpdateData = oUserForm.Designer.Controls.Add("Forms.CommandButton.1", "cmdUpdateData", True)
    Set oCmdClose = oUserForm.Designer.Controls.Add("Forms.CommandButton.1", "cmdClose", True)
    On Error Resume Next
    Set oDtpStartDate = oUserForm.Designer.Controls.Add("MSComCtl2.DTPicker", "dtpStartDate", True)
    Set oDtpEndDate = oUserForm.Designer.Controls.Add("MSComCtl2.DTPicker", "dtpEndDate", True)
     
    ' If DTPicker doesnt exist, use text boxes instead
    If Err.Number <> 0 Or oDtpStartDate Is Nothing Then
        On Error GoTo Error_In_CreateUserForm
        bHasDtPicker = False
        Set oDtpStartDate = oUserForm.Designer.Controls.Add("Forms.TextBox.1", "dtpStartDate", True)
        Set oDtpEndDate = oUserForm.Designer.Controls.Add("Forms.TextBox.1", "dtpEndDate", True)
        oDtpStartDate.ControlTipText = "Enter date in format: dd mmm yyyy   Eg: 01 Apr 2010"
        oDtpEndDate.ControlTipText = "Enter date in format: dd mmm yyyy   Eg: 31 Mar 2010"
    Else
        bHasDtPicker = True
        oDtpStartDate.Format = dtpLongDate
        oDtpEndDate.Format = dtpLongDate
    End If
    
    ' Control formatting properties
    With oLblStartDate
        .Top = 36
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "Start Date:"
        .Font.Size = 12
    End With
    With oLblEndDate
        .Top = 84
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "End Date:"
        .Font.Size = 12
    End With
    With oLblFilterOn
        .Top = 132
        .Left = 36
        .Height = 22
        .Width = 72
        .Caption = "Filter On:"
        .Font.Size = 12
    End With
    With oDtpStartDate
        .TabIndex = 1
        .Top = 36
        .Left = 120
        .Height = 22
        .Width = 210
        .Font.Size = 12
    End With
    With oDtpEndDate
        .TabIndex = 2
        .Top = 84
        .Left = 120
        .Height = 22
        .Width = 210
        .Font.Size = 12
    End With
    With oCboFilterOn
        .TabIndex = 3
        .Top = 132
        .Left = 120
        .Height = 22
        .Width = 132
        .Font.Size = 12
        '.Clear
        .AddItem ("CallTime")
        .AddItem ("TechComp")
        .AddItem ("CloseDate")
        .AddItem ("Calc Compl Date")
        .ListIndex = 0      ' default value
    End With
    With oCmdUpdateData
        .TabIndex = 4
        .Top = 186
        .Left = 30
        .Height = 36
        .Width = 126
        .Caption = "Update Data Now"
        .Font.Size = 12
    End With
    With oCmdClose
        .TabIndex = 5
        .Top = 186
        .Left = 198
        .Height = 36
        .Width = 126
        .Caption = "Close"
        .Font.Size = 12
    End With
    
    ' Create Event Handler Code For The Command Buttons
    With oUserForm.CodeModule
        ' cmdClose_Click()
        .InsertLines .CountOfLines + 1, "Private Sub cmdClose_Click()"
        .InsertLines .CountOfLines + 1, "    unload Me"
        .InsertLines .CountOfLines + 1, "End Sub"
        ' cmdUpdateData_Click ()
        .InsertLines .CountOfLines + 1, "Private Sub cmdUpdateData_Click()"
        .InsertLines .CountOfLines + 1, "    MsgBox ""To do stuff here..."" "
        .InsertLines .CountOfLines + 1, "End Sub"
    End With
    
' ===== Exit Handler =====
Exit_CreateUserForm:
    oUserForm = Nothing
    oLblStartDate = Nothing
    oLblEndDate = Nothing
    oLblFilterOn = Nothing
    oCboFilterOn = Nothing
    oCmdUpdateData = Nothing
    oCmdClose = Nothing
    oDtpStartDate = Nothing
    oDtpEndDate = Nothing
    Exit Sub

' ===== ERROR HANDLER =====
Error_In_CreateUserForm:
    
    With Err
        sErrorDescr = "Error '" & .Number & " " & _
            .Description & "' occurred in " & sErrSource & _
            IIf(Erl <> 0, " at line " & CStr(Erl) & ".", ".")
    End With

    Select Case MsgBox(sErrorDescr, vbAbortRetryIgnore, "Error in " & sErrSource)
        Case vbRetry
            Resume
        Case vbIgnore
            Resume Next
        Case Else
            Resume Exit_CreateUserForm
        End
    End Select

End Sub
Code:
'---------------------------------------------------------------------------------------
' Module    : ThisWorkbook
' Author    : shell l d
' Date      : 10Jul2010
' Purpose   : This Workbook code
'---------------------------------------------------------------------------------------

Private Const scModuleName As String = "ThisWorkbook."

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    On Error Resume Next
    Call DeleteUserForm
End Sub

Private Sub Workbook_Open()
    On Error Resume Next
    Call DeleteUserForm
    Call CreateUserForm
End Sub
 
Last edited by a moderator:
Upvote 0
Populate the combobox by code in the UserForm_Initialize event by amending the following section as follows :

Code:
    ' Create Event Handler Code For The Command Buttons
    With oUserForm.CodeModule
        ' cmdClose_Click()
        .InsertLines .CountOfLines + 1, "Private Sub cmdClose_Click()"
        .InsertLines .CountOfLines + 1, "    unload Me"
        .InsertLines .CountOfLines + 1, "End Sub"
        ' cmdUpdateData_Click ()
        .InsertLines .CountOfLines + 1, "Private Sub cmdUpdateData_Click()"
        .InsertLines .CountOfLines + 1, "    MsgBox ""To do stuff here..."" "
        .InsertLines .CountOfLines + 1, "End Sub"
       [COLOR=red][COLOR=green][B]'Populate the cboFilterOn combobox[/B][/COLOR]
        .InsertLines .CountOfLines + 1, "Private Sub UserForm_Initialize()"
        .InsertLines .CountOfLines + 1, "    cboFilterOn.AddItem(""CallTime"") "
        .InsertLines .CountOfLines + 1, "    cboFilterOn.AddItem(""TechComp"") "
        .InsertLines .CountOfLines + 1, "    cboFilterOn.AddItem(""CloseDate"") "
        .InsertLines .CountOfLines + 1, "    cboFilterOn.AddItem(""Calc Compl Date"") "
        .InsertLines .CountOfLines + 1, "    cboFilterOn.ListIndex = 0  "
        .InsertLines .CountOfLines + 1, "End Sub"
[/COLOR]   End With
 
Upvote 0
Thnx Jaafar... I'm already in the process of testing something similar... manually created a userform & then used the populate combo box in it's initialize method. As I know it worked that way for an already existing userform & a late bound combobox... will let you know shortly :)
 
Last edited:
Upvote 0
Yep Thnx Jafaar that surely works... why are there so many temperamental things with VBA & Office... yikes, try to do 1 way but something fails, so try another way & something else fails...

ETA... cool I didnt realise u could colour code stuff in code tags.. :)
 
Last edited:
Upvote 0
Hi

Also, to avoid the need of saving or closing the workbook after each time you delete the userform, you could amend the following portion of your code as follows :

Code:
[COLOR=green]' Create the UserForm[/COLOR]
    Set oUserForm = ThisWorkbook.VBProject.VBComponents.Add(icUserForm)
   [COLOR=green]' NOTE: .Name may error if userform existed but was deleted & no close or save has taken place since[/COLOR]
    On Error Resume Next
    [COLOR=red]With ThisWorkbook[/COLOR]
[COLOR=red]       .Saved = True[/COLOR]
[COLOR=red]       .ChangeFileAccess xlReadOnly[/COLOR]
[COLOR=red]       oUserForm.Name = scUserForm[/COLOR]
[COLOR=red]       .ChangeFileAccess xlReadWrite[/COLOR]
[COLOR=red]   End With[/COLOR]
  
    If Err.Number <> 0 Then
        Select Case Err.Number
[COLOR=seagreen][COLOR=green]'           Case Is = 75, 438, 50135[/COLOR]
[COLOR=seagreen]'                ' 75: Path/File access error[/COLOR]
[COLOR=seagreen]'                ' 438:   Object doesn't support this property or method.[/COLOR]
[COLOR=seagreen]'                ' 50135: Application-defined or object-defined error.[/COLOR]
[COLOR=seagreen]'                MsgBox Err.Number & " Unable to create Update Data Criteria user entry form." _[/COLOR]
[COLOR=seagreen]'                        & vbCrLf & "Please close workbook & re-open."[/COLOR]
[COLOR=seagreen]'                GoTo Exit_CreateUserForm[/COLOR]
[/COLOR]          Case Else
              [COLOR=green]  ' An unknown error was encountered, so alert the user[/COLOR]
                GoTo Error_In_CreateUserForm
        End Select
    End If
    On Error GoTo Error_In_CreateUserForm
 
Last edited:
Upvote 0
Awesome thnx for the info Jafaar... :)

I ended up completely removing the naming code last night though & always use UserForm1... if I run in to troubles with this, I'll put it back in with your code. :)
 
Upvote 0

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top