1

I have a Userform with 2 Comboboxes on that should get the data ranges from an external workbook. I'm stepping through the code with F8 to see the process, everything runs without errors but the ComboBoxes are empty when the userform shows.

The named ranges are set and works when I check it in the Watch window. I'm not sure if the problem comes in with the userform_initialize when I set the named ranges to the combo boxes?

Any suggestions will be appreciated.

Option Explicit
Public m_Cancelled As Boolean
Public Const myRangeNameVendor As String = "myNamedRangeDynamicVendor"
Public Const myRangeNameVendorCode As String = "myNamedRangeDynamicVendorCode"
Public VendorName As String
Public VendorCode As String



Sub NamedRanges(wb As Workbook, wSh As Worksheet)

    'declare variables to hold row and column numbers that define named cell range (dynamic)
    Dim myFirstRow As Long
    Dim myLastRow As Long

    'declare object variable to hold reference to cell range
    Dim myNamedRangeDynamicVendor As Range
    Dim myNamedRangeDynamicVendorCode As Range


    'identify first row of cell range
    myFirstRow = 2


    'Vendor Name range
    With wSh.Cells

        'find last row of source data cell range
        myLastRow = .Find(What:="*", LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

        'specify cell range
        Set myNamedRangeDynamicVendor = .Range(.Cells(myFirstRow, "A:A"), .Cells(myLastRow, "A:A"))

    End With

    'create named range with workbook scope. Defined name is as specified. Cell range is as identified, with the last row being dynamically determined
    wb.Names.Add Name:=myRangeNameVendor, RefersTo:=myNamedRangeDynamicVendor

    'Vendor Code range
    With wSh.Cells

        'specify cell range
        Set myNamedRangeDynamicVendorCode = .Range(.Cells(myFirstRow, "B:B"), .Cells(myLastRow, "B:B"))

    End With

    'create named range with workbook scope. Defined name is as specified. Cell range is as identified, with the last row being dynamically determined
    wb.Names.Add Name:=myRangeNameVendorCode, RefersTo:=myNamedRangeDynamicVendorCode

End Sub


' Returns the textbox value to the calling procedure
Public Property Get Vendor() As String
    VendorName = cboxVendorName.Value
    VendorCode = cboxVendorCode.Value
End Property

Private Sub buttonCancel_Click()
    ' Hide the Userform and set cancelled to true
    Hide
    m_Cancelled = True
End Sub

' Hide the UserForm when the user click Ok
Private Sub buttonOk_Click()
    Hide
End Sub

' Handle user clicking on the X button
Private Sub FrmVendor_QueryClose(Cancel As Integer, CloseMode As Integer)

    ' Prevent the form being unloaded
    If CloseMode = vbFormControlMenu Then Cancel = True

    ' Hide the Userform and set cancelled to true
    Hide
    m_Cancelled = True

End Sub


Private Sub FrmVendor_Initialize()

'add column of data from spreadsheet to your userform ComboBox
With Me
    cboxVendorName.RowSource = ThisWorkbook.Names(Split(.Tag, "|")(0)).Address(external:=True)
    cboxVendorCode.RowSource = ThisWorkbook.Names(Split(.Tag, "|")(1)).Address(external:=True)

End With
cboxVendorCode.ColumnCount = 2

End Sub


Sub Macro5()

Dim wb As Workbook
Dim ws As Worksheet
Dim path As String
Dim MainWB As Workbook
Dim MasterFile As String
Dim MasterFileF As String

Set ws = Application.ActiveSheet
Set MainWB = Application.ActiveWorkbook

Application.ScreenUpdating = False

'Get folder path
path = GetFolder()

MasterFile = Dir(path & "\*Master data*.xls*")
MasterFileF = path & "\" & MasterFile

'Check if workbook open if not open it
If Not wbOpen(MasterFile, wb) Then
    Set wb = Workbooks.Open(MasterFileF, False, True)
End If


'Set Vendor Name and Code Range names
Call NamedRanges(wb, wSh)


'Select Vendor name and Vendor code with User Form and set variables

    ' Display the UserForm
With New FrmVendor
    .Tag = myRangeNameVendor & "|" & myRangeNameVendorCode
    .Show
End With

    VendorName = FrmVendor.cboxVendorName.Value
    VendorCode = FrmVendor.cboxVendorCode.Value


    ' Clean up
    Unload FrmVendor
    Set FrmVendor = Nothing
Simone Evans
  • 183
  • 2
  • 17
  • 1
    **Integrate** the closing assignments to `VendorName =...` and `VendorCode =...` into the `With New FrmVendor` construction (after `.Show` and `End With`), but simply omit referencing the UserForm's default instance `FrmVendor`: e.g. `VendorName = .cboxVendorName.Value` (take care to write the point-prefix). Thus you are referencing the current "newed" up instance and not a possibly entered value at design time. - Find further explanations at [AddItem not populating options in combobox](https://stackoverflow.com/questions/60917016/additem-not-populating-options-in-combo-box/60917415#60917415) – T.M. Apr 07 '20 at 15:22
  • btw you needn't do the whole clean up as the new userform instance's life time ends automatically with `End With` here. Side note: generally any further call of `FrmVendor` would reactivate the default instance which you are trying to destroy though it isn't used in your case:-) – T.M. Apr 07 '20 at 15:30
  • @T.M. I tried changing the code to your first suggestion. I'm still getting the same problem with the comboboxes being empty. I'm not sure if moving those 2 arguments will help with the comboboxes not filling with the ranges though since they are only to capture the chosen value that was selected in the boxes(when they eventually populate). Thanks though, any other suggestions will be of great help. I've never used userforms and comboboxes before, so struggling with the code for it. – Simone Evans Apr 07 '20 at 19:18
  • 1
    Assume there are also issues before (see chat) - tldr:-; possibly the answer below plus my hints will help you :-) – T.M. Apr 08 '20 at 11:13
  • Definitively the naming convention is `UserForm_Initialize()` whatever the form name is, i.e. not `FrmVendor_Initialize()`; similar `UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)` :-) – T.M. Apr 08 '20 at 20:02

1 Answers1

1

The FrmVendor_Initialize() sub is triggered by the line With New FrmVendor which is before the tag is set. Move the code into a new sub

Sub SetCboxRowSource()

    'add column of data from spreadsheet to your userform ComboBox
    With Me
        cboxVendorName.RowSource = ThisWorkbook.Names(Split(.Tag, "|")(0)).Address(external:=True)
        cboxVendorCode.RowSource = ThisWorkbook.Names(Split(.Tag, "|")(1)).Address(external:=True)
    End With
    cboxVendorCode.ColumnCount = 2

End Sub

and call it after the tag is set

With New UserForm1
    .Tag = myRangeNameVendor & "|" & myRangeNameVendorCode
    .SetCboxRowSource
    .Show
End With

alternatively set the rowsource directly with

 With New FrmVendor
      .cboxVendorName.RowSource = wb.Names(myRangeNameVendor).RefersToRange.Address(external:=True)
      .cboxVendorCode.RowSource = wb.Names(myRangeNameVendorCode).RefersToRange.Address(external:=True)
      .Show
   End With
CDP1802
  • 13,871
  • 2
  • 7
  • 17
  • I tried the above code and first error I get is on `.SetCboxRowSource` error: **method or data member not found**. So I replaced it with `Call SetCboxRowSource`, then it runs but I get and error **variable not defined** on Sub SetCboxRowSource line `cboxVendorName`. I also had an error with the Sub SetCboxRowSource, `With Me` error: **invalid use of Me**. Thank CDP1802, any suggestions where something is going wrong? – Simone Evans Apr 07 '20 at 19:10
  • @Simone DId you put the sub in the form code same place as the FrmVendor_Initialize() ? – CDP1802 Apr 07 '20 at 19:19
  • all the code is in the same module at the moment, none of it is in the userform code – Simone Evans Apr 07 '20 at 19:28
  • @Simone Put SetCboxRowSource() in the userform code so that it becomes a method on that form. It just replaces the code you had in _Initialize. – CDP1802 Apr 07 '20 at 19:35
  • I changed the code as per your instruction. I now get an error in the Sub SetCboxReowSource on line `cboxVendorName.RowSource = ThisWorkbook.Names(Split(.Tag, "|")(0)).Address(external:=True)`, error: **Application defined or object defined error** – Simone Evans Apr 07 '20 at 19:42
  • @SImone add MsgBox Me.Tag before that line and check what is being set in .Tag are vaild ranges – CDP1802 Apr 07 '20 at 19:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/211160/discussion-between-cdp1802-and-simone-fick). – CDP1802 Apr 07 '20 at 19:51