Error when passing workbook object to VBA form - excel

I am working on a VBA script with Microsoft Word that allows the user to select text that will be copied to the clipboard so that it can exported to an Excel file. The user will make a number of selections and finally indicate he/she is done when the contents of the clipboard will be copied to a template Excel file.
The form (frmModeLessForInput) is a modeless form. The form has two buttons "Continue" and "Done". The user is allowed to navigate the document and place the cursor anywhere in the document. Then when "Continue" is pressed the form will call a subroutine (Highlight_Sentence) to copy the selected text to a "clipboard" variable. When "Done" is pressed control will be passed to called subroutine which will then copy the clipboard to the Excel file.
The problem I am having is that I don't seem to have correct code needed to pass workbook object in created in the MAIN MODULE to the form using a form property.
Below is the code. I have inserted comments in the code in the Select_Sentence_Form_Test and cmdDone subroutines where I am having the problem passing the workbook object.
Any assistance in resolving these problems is appreciated. As VBA programming is a sideline for me I am still learning.
Option Explicit
Public str_clipboard As String
Public txt_active_document As String
Public i_how_many_sentences As Integer
Public str_active_document
Public str_Excel_Filename As String
Public i_starting_row_ID As Integer
Public i_rows_of_data As Integer
MAIN MODULE
Sub Master_Module_Test()
Dim oExcel As Object
Dim wb As Excel.Workbook 'Object
Set oExcel = New Excel.Application
str_Excel_Filename = "C:\Test\Excel_Template.xlsx"
Documents.Open ("C:\Test\Doc_to_process.docx")
oExcel.Workbooks.Open str_Excel_Filename
i_how_many_sentences = 0
i_starting_row_ID = 1
Set wb = ActiveWorkbook
Call Select_Sentence_Form_Test(wb)
End Sub
Sub Select_Sentence_Form_Test(wb_open As Workbook)
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
' At this point wb_open is instantiated, i.e. I get "Excel_Template.xlsx" for wb_open.name
' But this code gives me an error "Object or block not set". If I leave this statement out then "Me.Book1.ActiveSheet.PasteSpecial..." in cmd_Done in the frmModelessForInput module gives the same error
Set frmModelessForInput.Book1 = wb_open
With frmModelessForInput
.str_word_doc_filename = str_active_document
.str_no_copied = "0"
.Show False
End With
Set frm = Nothing
End Sub
Below is the code for the frmModelessForInput form
Option Explicit
Private m_Book1 As Workbook
Public Property Get Book1() As Workbook
Set Book1 = m_Book1
End Property
Public Property Set Book1(ByRef Value As Workbook)
Set m_Book1 = Value
End Property
Private Sub UserForm_Activate()
'Position the form near the top-left of the window
'So that the user can work with the document
Me.Top = Application.ActiveWindow.Top + 15
Me.Left = Application.ActiveWindow.Left + 15
End Sub
Private Sub cmdContinue_Click()
Dim str_clipboard, str_clipboard_line As String
Call Highlight_Sentence(str_clipboard_line)
i_how_many_sentences = i_how_many_sentences + 1 'Problem: VBA reports i_how_many_sentences as undefined even though it is a Public variable
frmModelessForInput.str_no_copied = i_how_many_sentences 'Same Problem
str_clipboard = str_clipboard + str_clipboard_line 'Problem: each time I select a new text/sentence str_clipboard does not contain the contents of the previous selection
End Sub
Private Sub cmdCancel_Click()
b_abort = True
Unload frmModelessForInput
End Sub
Private Sub cmdContinue_Click()
Dim str_clipboard_line As String
Dim i_row_number As Integer
i_row_number = i_how_many_sentences + i_starting_row_ID
i_how_many_sentences = i_how_many_sentences + 1
Call Highlight_Sentence_Test(str_clipboard_line, i_row_number)
frmModelessForInput.str_no_copied = i_how_many_sentences
str_clipboard = str_clipboard + str_clipboard_line
End Sub
Private Sub cmdDone_Click()
' When the "Done" button is pressed the contents of the str_clipboard variable is copied to the Windows clipboard
Dim str_filename As String
str_filename = getName(str_Excel_Filename)
MsgBox "I will now copy the data to the Excel file."
Call SendToClipboard(str_clipboard) 'This sub puts the contents of str_clipboard into the Windows clipboard
' Uses the Book1 property --- this is the code line that produces the error "Object or block variable not set. Activeworkbook.name shows that Excel_Template.xlsx is active
Me.Book1.ActiveSheet.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
Unload frmModelessForInput
MsgBox "Done pasting data to: " & getName(str_Excel_Filename)
End Sub
Private Sub Highlight_Sentence(clipboard As String, i_row_no As Integer)
Dim txt_sentence, txt_page_no As String
Dim txt_section_index As String
With Selection
' Collapse current selection.
.Collapse
' Expand selection to current sentence.
.Expand Unit:=wdSentence
End With
clipboard = i_row_no & vbTab & txt_sentence & vbCrLf
End Sub

Related

Set a variable name to a Workbook selected from a VBA ComboBox

I will always have Workbook SQ_Macro_v1 as my main DB.
Two named Workbooks old_wk and new_wk will have different names, as I will choose them among the currently active WB on my computer.
I am going for a VBA ComboBox listing it all to a choice of mine, but in the end I am not able to store the name of my chosen WB.
Sub Macro1()
Dim main_wk, old_wk, new_wk As Workbook
Set main_wk = Workbooks("SQ_Macro_v1.xlsm")
Set old_wk = Workbooks(old_chosen) 'also tried UserForm1.ComboBox1.Value
Set new_wk = Workbooks(FileName_New) '
main_wk.Sheets("Main_DB").Range("C4").Value = old_wk.Worksheets("Sheet 1 Synthese").Range("C35").Value
As I run the UserForm code below, the old_chosen variable I set as empty in the main Sub. It seems that as I close the UserForm after it runs, nothing remains stored. Any clues to keep that variable saved after I close the UserForm?
Option Explicit
Public Sub UserForm_Activate()
Dim vWorkbook As Workbook
ComboBox1.Clear
For Each vWorkbook In Workbooks
ComboBox1.AddItem vWorkbook.Name
Next
End Sub
Public Sub CommandButton1_Click()
If ComboBox1.ListIndex <> -1 Then
Call YourMacro(ComboBox1)
End If
End Sub
Public Sub YourMacro(vWorkbookName As String)
Dim old_chosen As String
old_chosen = Me.ComboBox1.Value
MsgBox "You choose: " & Workbooks(vWorkbookName).Name
End Sub
The MsgBox pops up but no value is stored afterward:
Public Sub YourMacro(vWorkbookName As String)
Dim old_chosen As String
old_chosen = Me.ComboBox1.Value
MsgBox "You choose: " & Workbooks(vWorkbookName).Name
End Sub
You have declared the variable at procedure level and hence it is not visible after the userform is closed.
To make this variable available to all procedures in the project, precede it with the Public statement. Insert a module and paste this there
Public old_chosen As String
Having said that, I would recommend moving Macro1 inside the userform and handle the code from there after declaring the variable at module level

Write to the cell next to a checkbox when that checkbox is checked

I have a to do list in excel. When a check box is checked a macro is ran that selects a specific cell and adds values to offsets of that cell. The problem is I have 600 check boxes and they all need their own code to reference the correct cells.
private sub checkbox1_click ()
Range ("I2").offset(0,3).value= "hello world"
Sub end
I want something like this:
Range ("location of checkbox I just checked").offset(0,3).value= "hello world"
This would be easier if you are using ActiveX control checkboxes instead of Form control.
With ActiveX control checkboxes, you can refer to the object as a part of Me, which points to the worksheet itself and use something like this:
Private Sub CheckBox1_Click()
If Me.CheckBox1.Value = True Then
Me.CheckBox1.TopLeftCell.Offset(0, 3).Value = "hello world"
End If
End Sub
If you can't use ActiveX controls, please let me know and I can adjust my answer. Note that you could also look at more information on how to make a checkbox refer to itself by looking at the answer to this question.
In the answer from PeterT, you can also see how to use a Class Module to avoid the problem of having one macro per checkbox. Here, I'm copying the relevant part of the answer:
[...] Create a class module that you can instantiate for any number of
CheckBoxes.
Code for Class module MyCheckBoxClass
Dim WithEvents cbControl As MSForms.CheckBox
Private controlName As String
Public Sub cbControl_Click()
Debug.Print controlName & " is now " & cbControl.Value
If cbControl.Value = True Then
Range("CheckBoxCount") = Range("CheckBoxCount") + 1 'choose to store on the sheet
groupCheckBoxCount = groupCheckBoxCount + 1 'or in a variable
Else
Range("CheckBoxCount") = Range("CheckBoxCount") - 1
groupCheckBoxCount = groupCheckBoxCount - 1
End If
End Sub
Public Sub Attach(newCB As MSForms.CheckBox, newName As String)
Set cbControl = newCB
controlName = newName
End Sub
Private Sub Class_Initialize()
controlName = ""
End Sub
Code in a regular code module:
Public groupClickCount As Integer
Private cbCollection As Collection
Public Sub SetUpControlsOnce()
Dim thisCB As MyCheckBoxClass
Dim ctl As OLEObject
Dim cbControl As MSForms.CheckBox
If cbCollection Is Nothing Then
Set cbCollection = New Collection
End If
For Each ctl In ThisWorkbook.Sheets("Sheet1").OLEObjects
If TypeName(ctl.Object) = "CheckBox" Then
'--- this is an ActiveX CheckBox
Set thisCB = New MyCheckBoxClass
thisCB.Attach ctl.Object, ctl.name
cbCollection.Add thisCB
End If
Next ctl
End Sub
Of course, you would have to replace "Sheet1" with the appropriate name for your sheet and
If cbControl.Value = True Then
Range("CheckBoxCount") = Range("CheckBoxCount") + 1 'choose to store on the sheet
groupCheckBoxCount = groupCheckBoxCount + 1 'or in a variable
Else
Range("CheckBoxCount") = Range("CheckBoxCount") - 1
groupCheckBoxCount = groupCheckBoxCount - 1
End If
With
If cbControl.Value = True Then
cbControl.TopLeftCell.Offset(0, 3).Value = "hello world"
End If
And finally, I would suggest to run the SetUpControlsOnce macro when you open the workbook by including it in the Open Event of the Workbook Object (Thisworkbook). ie.:
Private Sub Workbook_Open()
Call SetUpControlsOnce
End Sub

Excel VBA how to link a class and a control?

I am using Excel 2003 with VBA, I am dynamically creating check box controls on a sheet and want to link the VBA controls to a class so that when a user clicks on a checkbox an event is fired so I can do something.
From what I've read it would seem that creating a user class is the solution, but having tried this I can't get it to work.
My user class looks like this:
Option Explicit
Public WithEvents cbBox As MSForms.checkbox
Private Sub cbBox_Change()
MsgBox "_CHANGE"
End Sub
Private Sub cbBox_Click()
MsgBox "_CLICK"
End Sub
My code to create the checkboxes:
For Each varExisting In objColumns
'Insert the field name
objColumnHeadings.Cells(lngRow, 1).Value = varExisting
'Insert a checkbox to allow selection of the column
Set objCell = objColumnHeadings.Cells(lngRow, 2)
Dim objCBclass As clsCheckbox
Set objCBclass = New clsCheckbox
Set objCBclass.cbBox = ActiveSheet.OLEObjects.Add( _
ClassType:="Forms.CheckBox.1" _
, Left:=300 _
, Top:=(objCell.Top + 2) _
, Height:=10 _
, Width:=9.6).Object
objCBclass.cbBox.Name = "chkbx" & lngRow
objCBclass.cbBox.Caption = ""
objCBclass.cbBox.BackColor = &H808080
objCBclass.cbBox.BackStyle = 0
objCBclass.cbBox.ForeColor = &H808080
objCheckboxes.Add objCBclass
lngRow = lngRow + 1
Next
The checkboxes are visible in the sheet, but when I click on them, no message box is displayed so the link to the class doesn't seem to be working.
Why?
Edit...If after adding the checkboxes I go into the VB IDE and select one of the created checkboxes from the list of controls, then select Click from the Procedure drop down list, it will insert the code for a call back which if I add a message box to this, works when I click on the same checkbox...so how can I achieve this in code? I've tried recording a macro to do this, nothing was recorded.
Edit by S.Platten, jump to the bottom for how this helped me fix the problem...
Due to some weird reason, VBA doesn't hook up the events for Sheet's ActiveX control in the same execution cycle in which they were added. So, we need to come out of the cycle which added the controls and then invoke the event adding proc in next cycle. Application.OnTime helps here.
Its seems a bit of overkill but it works :)
Option Explicit
Dim collChk As Collection
Dim timerTime
Sub master()
'/ Add the CheckBoxes First
Call addControls
'<< Due to some weird reason, VBA doesn't hook up the events for Sheet's ActiveX control in the same
'execution cycle in which they were added. So, we need to come out of the cycle which added the controls
'and then invoke the event adding proc in next cycle. >>
'/ Start Timer. Timer will call the sub to add the events
Call StartTimer
End Sub
Sub addControls()
Dim ctrlChkBox As MSForms.CheckBox
Dim objCell As Range
Dim i As Long
'Intialize the collection to hold the classes
Set collChk = New Collection
'/ Here Controls are added. No Events, yet.
For i = 1 To 10
Set objCell = Sheet1.Cells(i, 1)
Set ctrlChkBox = Sheet1.OLEObjects.Add( _
ClassType:="Forms.CheckBox.1" _
, Left:=1 _
, Top:=(objCell.Top + 2) _
, Height:=objCell.Height _
, Width:=100).Object
ctrlChkBox.Name = "chkbx" & objCell.Row
Next
End Sub
Sub addEvents()
Dim ctrlChkBox As MSForms.CheckBox
Dim objCBclass As clsCheckBox
Dim x As Object
'Intialize the collection to hold the classes
Set collChk = New Collection
'/ Here we assign the event handler
For Each x In Sheet1.OLEObjects
If x.OLEType = 2 Then
Set ctrlChkBox = x.Object
Set objCBclass = New clsCheckBox
Set objCBclass.cbBox = ctrlChkBox
collChk.Add objCBclass
Debug.Print x.Name
End If
Next
'/ Kill the timer
Call StopTimer
End Sub
Sub StartTimer()
timerTime = Now + TimeSerial(0, 0, 1)
Application.OnTime EarliestTime:=timerTime, Procedure:="addEvents", _
Schedule:=True
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=timerTime, Procedure:="addEvents", _
Schedule:=False
End Sub
Class Module: clsCheckBox
Option Explicit
Public WithEvents cbBox As MSForms.CheckBox
Private Sub cbBox_Change()
MsgBox "_CHANGE"
End Sub
Private Sub cbBox_Click()
MsgBox "_CLICK"
End Sub
Edit continued...
The class (clsCheckbox):
Option Explicit
Public WithEvents cbBox As MSForms.checkbox
Private Sub cbBox_Click()
MsgBox "_CLICK"
End Sub
Module1
Public objCheckboxes As Collection
Public tmrTimer
Public Sub addEvents()
Dim objCheckbox As clsCheckbox
Dim objMSCheckbox As Object
Dim objControl As Object
Set objCheckboxes = New Collection
For Each objControl In Sheet1.OLEObjects
If objControl.OLEType = 2 _
And objControl.progID = "Forms.CheckBox.1" Then
Set objMSCheckbox = objControl.Object
Set objCheckbox = New clsCheckbox
Set objCheckbox.cbBox = objMSCheckbox
objCheckboxes.Add objCheckbox
End If
Next
Call stopTimer
End Sub
Public Sub startTimer()
tmrTimer = Now + TimeSerial(0, 0, 1)
Application.OnTime EarliestTime:=tmrTimer _
, Procedure:="addEvents" _
, Schedule:=True
End Sub
Public Sub stopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=tmrTimer _
, Procedure:="addEvents" _
, Schedule:=False
End Sub
The code in the sheet that adds the controls:
Dim objControl As MSForms.checkbox
For Each varExisting In objColumns
'Insert the field name
objColumnHeadings.Cells(lngRow, 1).Value = varExisting
'Insert a checkbox to allow selection of the column
Set objCell = objColumnHeadings.Cells(lngRow, 2)
Set objControl = ActiveSheet.OLEObjects.Add( _
ClassType:="Forms.CheckBox.1" _
, Left:=300 _
, Top:=(objCell.Top + 2) _
, Height:=10 _
, Width:=9.6).Object
objControl.Name = "chkbx" & lngRow
objControl.Caption = ""
objControl.BackColor = &H808080
objControl.BackStyle = 0
objControl.ForeColor = &H808080
lngRow = lngRow + 1
Next
This isn't the entire project, but enough to demonstrate the workings.
You are currently using ActiveX controls. Yet, ActiveX controls are bound to specific naming conventions. For example: if you insert an ActiveX button onto a sheet and name it btnMyButton then the sub must be named btnMyButton_Click. The same applies to checkboxes. If you insert a new checkbox with the name CheckBox2 then the sub's name must be CheckBox2_Click. In short, there cannot be a sub with the name cbBox_Change associated to any ActiveX checkbox.
So, what you really need (with ActiveX controls) is a way to change the VBA code on a sheet. But thus far I have never come across any such code (VBA code to change VBA code on a sheet).
A much easier route would be if you'd be willing to use form controls instead.
The following sub will create a (form control) checkbox and assign the macro tmpSO to it. The sub tmpSO (unlike subs for ActiveX controls) does not need to reside on the sheet but can be in any module.
Sub Insert_CheckBox()
Dim chk As CheckBox
Set chk = ActiveSheet.CheckBoxes.Add(390.75, 216, 72, 72)
chk.OnAction = "tmpSO"
End Sub
Since a from control is calling the sub tmpSO you can use Application.Caller in that sub and thereby know which checkbox has been calling this sub.
Sub tmpSO()
Debug.Print Application.Caller
End Sub
This will return the name of the CheckBox. So, you can use this one sub for all of your checkboxes any dynamically handle them based on their names (possibly using a Case Select).
Here is another example for tmpSO:
Sub tmpSO()
With ThisWorkbook.Worksheets(1).CheckBoxes(Application.Caller)
MsgBox "The checkbox " & Application.Caller & Chr(10) & _
"is currently " & IIf(.Value = 1, "", "not") & " checked."
End With
End Sub

A checkbox that refers to itself in Excel VBA

I have an excel spreadsheet that sets a cell's value to the number of checked boxes in a group. I would like to assign a macro to each that looks like this:
Sub clickedBox()
If thisBox(or however you would do it).Checked = True Then
Range("D9").Value = Range("D9").Value + 1
Else
Range("D9").Value = Range("D9").Value - 1
End If
End Sub
The cell defaults to 0 and all the boxes default to unchecked. That way, ticking a box ups the count, and unticking it knocks it down one and it can never go below zero or higher than the number of boxes.
I realize that I should also make it so that the macro triggers when a checkbox's state is changed not only when it's clicked, but I want to make sure this is possible first.
Is there a way to have a checkbox just reference itself like that?
It really depends if you're tied into ActiveX controls or Form Controls. Either can work, and either path likely directs how to clearly implement it.
Using ActiveX Controls (checkboxes):
You have two options to code your "click handlers" for ActiveX controls. The first is hard-coding a public sub for each control:
control on Thisworkbook.Sheets("Sheet1"): CheckBox1
code in Excel Object Sheet1:
Private groupCheckBoxCount As Integer
Private Sub CheckBox1_Click()
Debug.Print "Control on " & Me.Name & " is now " & Me.CheckBox1.Value
RegisterCheckedValue Me.CheckBox1.Value
End Sub
Private Sub RegisterCheckedValue(cbVal As Boolean)
If cbVal = True Then
Range("CheckBoxCount") = Range("CheckBoxCount") + 1 'choose to store on the sheet
groupCheckBoxCount = groupCheckBoxCount + 1 'or in a variable
Else
Range("CheckBoxCount") = Range("CheckBoxCount") - 1
groupCheckBoxCount = groupCheckBoxCount - 1
End If
End Sub
Then if you have ten checkboxes, you'll have ten CheckBox(x)_Click subs, each specifically tied to a single ActiveX control. Each of these click handlers can increment or decrement your counter in stored in a worksheet cell (or in a module private variable).
The second option is to create a class module that you can instantiate for any number of CheckBoxes.
code for class module MyCheckBoxClass
Dim WithEvents cbControl As MSForms.CheckBox
Private controlName As String
Public Sub cbControl_Click()
Debug.Print controlName & " is now " & cbControl.Value
If cbControl.Value = True Then
Range("CheckBoxCount") = Range("CheckBoxCount") + 1 'choose to store on the sheet
groupCheckBoxCount = groupCheckBoxCount + 1 'or in a variable
Else
Range("CheckBoxCount") = Range("CheckBoxCount") - 1
groupCheckBoxCount = groupCheckBoxCount - 1
End If
End Sub
Public Sub Attach(newCB As MSForms.CheckBox, newName As String)
Set cbControl = newCB
controlName = newName
End Sub
Private Sub Class_Initialize()
controlName = ""
End Sub
code in a regular code module:
Public groupClickCount As Integer
Private cbCollection As Collection
Public Sub SetUpControlsOnce()
Dim thisCB As MyCheckBoxClass
Dim ctl As OLEObject
Dim cbControl As MSForms.CheckBox
If cbCollection Is Nothing Then
Set cbCollection = New Collection
End If
For Each ctl In ThisWorkbook.Sheets("Sheet1").OLEObjects
If TypeName(ctl.Object) = "CheckBox" Then
'--- this is an ActiveX CheckBox
Set thisCB = New MyCheckBoxClass
thisCB.Attach ctl.Object, ctl.name
cbCollection.Add thisCB
End If
Next ctl
End Sub
Using Form Controls (checkboxes):
While there are several ways to catch the click event for a Form checkbox, the simplest is to connect ALL checkboxes in a group to a single macro:
Public groupClickCount As Integer
Public Sub cbControl_Click()
'--- loop through all the controls on the form and filter for
' only checkboxes, then count up how many are checked
Dim ctl As Shape
Dim checkCount As Integer
checkCount = 0
For Each ctl In ActiveSheet.Shapes
If ctl.Type = msoFormControl Then
On Error Resume Next
If ctl.ControlFormat = xlCheckBox Then
If ctl.ControlFormat.Value = 1 Then
checkCount = checkCount + 1
Else
checkCount = checkCount - 1
End If
End If
End If
Next ctl
Range("CheckBoxCount") = checkCount 'choose to store on the sheet
groupClickCount = checkCount 'or in a variable
End Sub
Either solution can be adapted in many ways, depending on your needs and how you'd like to track your checkboxes.

Listbox Userform Workaround for Wrap Text by Displaying Popup of Selection

A user asked a question about using a mouseover tool to display cut off data in a Listbox column. "Dee" posted the following solution (see, https://stackoverflow.com/a/15301355/4362915):
Option Explicit
Public ListItemInfo As Control
Private Sub UserForm_Initialize()
Set ListItemInfo = Me.Controls.Add("Forms.TextBox.1", "ListItemInfo", False)
With Me.ListItemInfo
.Top = Me.ListBox1.Top
.Left = Me.ListBox1.Left
.Width = Me.ListBox1.Width
.Height = Me.ListBox1.Height
.MultiLine = True
End With
End Sub
Private Sub ListBox1_Change()
Me.ListItemInfo.text = GetSelectedItemsText
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
SwitchListItemInfo
End Sub
Private Sub UserForm_Click()
SwitchListItemInfo
End Sub
Private Function GetSelectedItemsText() As String
Dim text As String
Dim i As Integer
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Selected(i) Then
text = text & Me.ListBox1.List(i) & vbNewLine
End If
Next i
GetSelectedItemsText = text
End Function
Private Sub SwitchListItemInfo()
If Me.ListItemInfo.text = "" Then Exit Sub
Me.ListItemInfo.Visible = Not Me.ListItemInfo.Visible
Me.ListBox1.Visible = Not Me.ListBox1.Visible
End Sub
In brief, Dee's code populates ListBox1 from a select range dictated in the RowSource value of the listbox; when you double click one of the items, a new TextBox pops up listing the contents of the item double clicked. All of this is done, of course, simply because ListBox cannot wrap text and cuts off text when the value is too long.
I have a listbox populated with 5 columns of data pulled from an Access db. I frequently have the problem where certain columns of data are cut off -- thus, Dee's solution of a pop-up text box is very appealing. However, I am struggling revising Dee's code so that the listbox is populated from my access db and not a pre-specified range in the RowSource field of the ListBox properties. I'm struggling to do this, but I'm guessing the solution is pretty obviously to an expert, so any help would be greatly, greatly appreciated. The code of my current listbox is as follows:
Sub UserForm_Initialize()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim NoOfRecords As Long
'Open the .accdb form database to retrieve data
s = ActiveCell.Value
Set db = OpenDatabase("\\BTT\test.accdb")
'Define the first recordset
Set rs = db.OpenRecordset("SELECT * FROM Entities WHERE [Entity Name] Like '" & s & "' & '*' ")
'Determine the number of records in the recordset
On Error GoTo ErrHandler
With rs
.MoveLast
NoOfRecords = .RecordCount
.MoveFirst
End With
'Set the number of ListBox columns = number of fields in the recordset
ListBox1.ColumnCount = 5
'Load the listbox with the retrieved records
ListBox1.Column = rs.GetRows(NoOfRecords)
'Cleanup
rs.Close
db.Close
Call Easy
Set rs = Nothing
Set db = Nothing
lbl_Exit:
Exit Sub
ErrHandler:
MsgBox "No historical results for this entity"
Exit Sub
End Sub
Try
Set Me.Listbox1.Recordset = rs
Untested but some further info here

Resources