Edited 1/17/2017 - Additional sample at end of answer.
Hello,
First let me state the answer by @jimk is valid (+1).
Filtering can be done with & without macros. I have posted 10 to 20 on this forum using many variations. There is also Filter/Search with Forms you may want to look at.
With that said, here is what I see in your question. You do not really need combo boxes for new treatments. If it isn’t in the ‘treatment’ table it needs to be added there for a centralization of items. Next is that you are working on the probability that an animal will receive more than one treatment at the same time so possibly using a Table control for data entry and history may be the method of choice. This is where the problem arises. You can certainly have list boxes in a table control. What I haven’t seen is a table control with one list box based upon another in the same record. The question has previously arisen & I have finally came to somewhat of a solution. It does, however, utilize two small macros. While small, to someone not accustomed to macros they are quite large (as you have mentioned).
Here is a sample containing the form with a Table Control. It is somewhat based upon your needs as I created it from a previous answer for you. The DogTreatments
form is simple to use. Use the listbox on top left to select a ‘dog’ then press button (Select Dog) which then lists all previous treatments for that animal. New items can be added at the end of the table. ‘treatment_type’ and ‘treatment_subtype’ are both listboxes. A selection in ‘type’ will show only related selections in ‘subtype’. On a NEW record, nothing will show in ‘subtype’ until a ‘type’ is selected.
Sample - Dogsjohnh009.odb - This is revised copy (1/17/2017) correcting error on new entries. ‘subtype’ listbox had incorrect display. Macro code below modified with corrections. Thanks to @johnh009 for find.
Here are the two macros contained within:
REM ***** BASIC *****
Option Explicit
Sub RefreshList
Rem This routine is called each time the 'treatment_type' field is exited OR
Rem another record is selected (called from ClearList sub).
Dim oForm As Object
Dim oSubForm As Object
Dim oTable As Object
Dim oColumn As Object
Dim oStatement As Object
Dim oResult As Object
Dim sSQL As String
Dim sSelectedValue As String
Dim bCursorTest As Boolean
Dim iItemCount As Integer
Dim x As Integer
Rem Get the main Form
oForm = ThisComponent.getDrawPage().getForms().getByName("Form")
Rem Get the SubForm
oSubForm = oForm.getByName("SubForm")
Rem Get the Table control
oTable = oSubForm.getByName("Table Control 1")
Rem Get the value selected in 'type'
oColumn = oTable.getByName("treatment_type")
sSelectedValue = oColumn.SelectedValue
Rem Use SQL (query) to retrieve the 'subtypes' for 'type'
oStatement = oForm.ActiveConnection.createStatement() 'Create an SQL statement object'
sSQL = "Select ""treatment_subtype"" FROM ""treatment"" WHERE ""treatment_type"" = '" & sSelectedValue & "'"
oStatement.ResultSetType = com.sun.star.sdbc.ResultSetType.SCROLL_INSENSITIVE
oResult = oStatement.executeQuery(sSQL)
REM Check if record set returned
bCursorTest = oResult.first
REM Exit if record set is empty
If (bCursorTest = "False") and (NOT oSubForm.IsNew) Then
MsgBox "Treatment Type is Not Selected"
Exit Sub
End If
Rem Clear existing items in the listbox
oColumn = oTable.getByName("treatment_subtype")
iItemCount = oColumn.ItemCount
If iItemCount > 1 Then
for x = 1 to iItemCount
oColumn.removeItem(0)
Next
EndIf
Rem Fill the 'subtype' with the retrieved values
Rem Since this fills from the top & pushes down,
Rem the first item added is actually the last item selected in the query
oResult.afterLast
While oResult.previous
oColumn.insertItem(0,oResult.getString(1),0)
wend
End Sub
Sub ClearList
Rem This routine to be called each time the record changes
Dim oForm As Object
Dim oSubForm As Object
Dim oTable As Object
Dim oColumn As Object
Dim iItemCount As Integer
Dim x As Integer
Rem Get the Form
oForm = ThisComponent.getDrawPage().getForms().getByName("Form")
Rem Get the SubForm
oSubForm = oForm.getByName("SubForm")
Rem Get the TableControl
oTable = oSubForm.getByName("Table Control 1")
Rem Get the Column affected in the TableControl
oColumn = oTable.getByName("treatment_subtype")
Rem Clear existing items in the listbox
iItemCount = oColumn.ItemCount
for x = 1 to iItemCount
oColumn.removeItem(0)
Next
REM Call this sub to fill listbox if existing record
RefreshList
End Sub
I have added many comments so they appear larger than needed. Also, to keep it simple many lines which could have been combined are separated for ease of reading.
The RefreshList
macro is attached to the When losing focus
event of the ‘treatment_type’ column. The ClearList
macro is attached to the After record change
event of the subform. With that, each time a different record is selected, the ‘subtype’ is cleared then if it is an existing record the list is refreshed based upon ‘type’. Also, each time an item is selected in ‘treatment_type’ the subtype will reflect the choices.
Please note one other change in the form. While the ‘treatment_type’ column is still based upon an SQL select, the 'treatment_‘subtype’ is now based upon a Valuelist
with NO items actually in the control itself. It all comes from the macro.
Now of course (if you undertake the task) the biggest hurdle in using this is to fit it into you Base file. Most of the problem will be to get the form & control names correct. Even if you don’t use it, this was certainly not a waste of time by any means. As mentioned earlier, this has come up before. Just never took the time to figure it out until now.
Edit 1/17/2017:
The above relates to working with a table control. Additionally the following sample uses regular controls and requires less code. It has two listboxes with the list of the second based upon the selection in the first.
The basis of the sample is the sample pointed to in answer by @jimk for this question.
Sample #2 - ProgressiveListboxes.odb - two bugs fixed.
Code is in .odb. Also, please pardon me for any bugs still present. Have done quite a bit of tests but you can never test enough. Will try to correct any problems.