MVF Technical Discussion and Uses (If you plan to Use Them)

There is no reason to store the data as a delimited list. Store it normalized and display it as delimited text. I started with MajP's sample db and replace the list with a treeview control. The sample form has 2 "MVF", controls displaying the selections as a list and the other fill's the combo box value with delimited list. The user selections tables differ only in name. I am still working on positioning and sizing.

1754437138524.png


1754437024218.png

1754437093269.png
 
There is no reason to store the data as a delimited list. Store it normalized and display it as delimited text.
That's right!.. That's just what I said to Isladogs and MajP. Store each value, one value per record, in a regular child table so I can slice and dice the data with regular queries.
 
Last edited:
Why can't a real listbox control be used to select multiple values that binds each value to a regular table?
Obviously you can do that. That is what people have been doing for years. But that does not give the feel of the MVF combo. The idea was to give you some of the function of an MVF control. Expandable working on the combobox down arrow, checkboxes, ability to close the list. In my case in addition the ability to select all, deselect all, and order the list.

That's right!.. That's just what I said to Isladogs and MajP. Store each value, one per record, in a regular child table so I can slice and dice the data with regular queries
And that is what my original demo showed.
 
I started with MajP's sample db and replace the list with a treeview control...
Interesting. Does that treeview control work in 64-bit Access? How are values selected from the tree stored? Are there cascading tables for each level of the tree?
 
Yes, I am using 64-bit Access it works in 32bit without change. The treeview control is filled the same as the original forms in-memory recordset. The data is written back to the user selections table when the ok button is clicked by going though the tree looking for newly checked and un-checked leafs. The available selections table has 3 columns, [SelectionID],[ValueText],[ParentID], processed recursively starting with [ParentID] = 0. Selection tables without structure like the color table pass a query column 0 As [ParentID].
 
Yes, I am using 64-bit Access it works in 32bit without change.
I thought treeviews only worked in 32-bit Access because mscomctl.ocx cannot be used in 64-bit?
The treeview control is filled the same as the original forms in-memory recordset. The data is written back to the user selections table when the ok button is clicked
So how, for example, would a selection in the tree's 3rd level be stored in the table? Example: 4, M, M1 in your sample tree.
by going though the tree looking for newly checked and un-checked leafs. The available selections table has 3 columns, [SelectionID],[ValueText],[ParentID], processed recursively starting with [ParentID] = 0. Selection tables without structure like the color table pass a query column 0 As [ParentID].
 
Microsoft has released a x64 version of common controlls that also works in x32 without change.

The only part of the tree saved to user selections are the leafs i.e. no child nodes "M1", the rest are for grouping.
 
The 4 tables used for selections look like the following.

1754482082492.png


The queries for the record sets passed to the tree are as follows

Code:
        ' Available Selections Recordset
        Set AvailSelections _
                = CurrentDb.OpenRecordset( _
                    "SELECT tblSelectionsTree.SelectionID, " & _
                           "tblSelectionsTree.SelectionText, " & _
                           "tblSelectionsTree.ParentID " & _
                    "FROM tblSelectionsTree;", _
                    RecordsetTypeEnum.dbOpenSnapshot)
        ' User's current selections Recordset
        ' Edited by MVF form
        Set UserSelections _
                = CurrentDb.OpenRecordset( _
                    "SELECT tblUserSelections.UserID_FK, " & _
                           "tblUserSelections.SelectionID_FK " & _
                    "FROM tblUserSelections " & _
                    "WHERE tblUserSelections.UserID_FK=" & Me.UserID & ";", _
                    RecordsetTypeEnum.dbOpenDynaset, _
                    RecordsetOptionEnum.dbFailOnError)

'--------------- Color -----------'
        ' Available Selections Recordset
        Set AvailSelections _
                = CurrentDb.OpenRecordset( _
                    "SELECT tblColorSelections.SelectionID, " & _
                           "tblColorSelections.SelectionText, " & _
                           "0 as ParentID " & _
                    "FROM tblColorSelections " & _
                    "ORDER BY tblColorSelections.SelectionText;", _
                    RecordsetTypeEnum.dbOpenSnapshot)
        ' User's current selections Recordset
        ' Edited by MVF form
        Set UserSelections _
                = CurrentDb.OpenRecordset( _
                    "SELECT tblUserColorSelections.UserID_FK, " & _
                           "tblUserColorSelections.SelectionID_FK " & _
                    "FROM tblUserColorSelections " & _
                    "WHERE tblUserColorSelections.UserID_FK=" & Me.UserID & ";", _
                    RecordsetTypeEnum.dbOpenDynaset, _
                    RecordsetOptionEnum.dbFailOnError)
 
Really? I thought multiselect list boxes used MVF's to store multiple selections.
No.
A standard multiselect listbox (simple or extended) has been available since at least A2000.
It does not depend on MVFs. It allows multiple selections on a form but does not have checkboxes.

However, you can also choose a listbox control when creating an MVF field. That also allows multiple sections and does show checkboxes
The two approaches may look 'similar' but work in different ways.
 
No. A standard multiselect listbox (simple or extended) has been available since at least A2000. It does not depend on MVFs. It allows multiple selections on a form but does not have checkboxes.
I've always noticed in field properties that you can choose multiselect yes/no for combo and list controls. So without the checkboxes, how does one multiselect, hold down the shift key and click on multiple values?
However, you can also choose a listbox control when creating an MVF field. That also allows multiple sections and does show checkboxes
The two approaches may look 'similar' but work in different ways.
Can controls other than lists be used with mvf's and the checkboxes will appear?
 
I've always noticed in field properties that you can choose multiselect yes/no for combo and list controls. So without the checkboxes, how does one multiselect, hold down the shift key and click on multiple values?
Already provided you the demo along with a video presentation on how to do this.
Can controls other than lists be used with mvf's and the checkboxes will appear?
There is a listbox, textbox, and combobox control designed for MVF. The checkboxes appear in the listbox and combobox. These are not the same controls as a multiselect listbox or standard combo.
 
There is a listbox, textbox, and combobox control designed for MVF. The checkboxes appear in the listbox and combobox. These are not the same controls as a multiselect listbox or standard combo.
and those controls are for exclusive use with mvf's, and cannot be adapted to work directly with normal tables, thus reason for mimicking them with popup modal form, right?
 
and those controls are for exclusive use with mvf's, and cannot be adapted to work directly with normal tables, thus reason for mimicking them with popup modal form, right?
Have you looked at the Demo? As you asked the demo shows multiple ways to select multiple values and store in a normal junction table. The subform and pop up have checkboxes. The multi select does not. The crosstab uses just a click.
The specific MVF controls only work with MVF fields and cannot be used on a normal junction table. You can fake it like @arnelgp did where you are using an MVF field but saving somewhere in addition. A hybrid. @Josef P. also adapts this idea here where you leverage the MVF field only to support the MVF control.
 
Converting MVF to a Standard Junction / Child table.

One concern about MVFs can be alleviated because if you ever want to convert it to a traditional junction table or child table, it is extremely simple to do. For example if you decide that you want to convert to SQL Server or another RDMS or if you find a potential limitation.

In the example Companies have an MVF field to hold Regions. This lookup is storing the foreign key to the tblRegions

Company.PNG


Although you see a list of states that is only display. What is being stored is the foreign key to the Regions table in the hidden junction table. It is normalized.

But if you wanted to create the junction table and migrate to a standard design you could make a junction table like this
JunctionCompRegion.PNG


Simply run an append query like this
Append.PNG


And your results are
appendResults.PNG


So my opinion has changed in that you really cannot paint yourself into a corner that you cannot get out of if you had to. Obviously you would then have to modify your forms. You could use some of the Fake MVF ideas that would use the junction table but require little modification to the forms since you would not have to add a subform for the child records.
 
Union an MVF
The question was asked here if you could union an MVF.

If by now you understand that an MVF if not a field but a display of a hidden table, then unioning an MVF is no different than what you would do if you could see the junction tables.

I added a second table called tblExternalCompanies to union with tblCompanies. Just like tblCompanies, It has a company name field and an MVF Regions using the State lookup table.

1. First create two like queries for each table linking to the lookup table by StateID . To pull in the State Names.
Remember that even though Regions shows a concatenation of text it is storing a StateID in the hidden table.

QryCompany.PNG


2. Make sure to Alias your names if not you we get some painful field names pulling in the table names
Names.PNG

3. Now union these two queries
Union.PNG



4. If you did this with MVF or a traditional design you could build a function to concatenate the records

Code:
Public Function ConcatStates(CompanyName As String) As String
  Dim rs As DAO.Recordset
  Dim strOut As String
  Set rs = CurrentDb.OpenRecordset("select State from qryUnionCompanyRegions where companyName = '" & CompanyName & "'")
  Do While Not rs.EOF
    If strOut = "" Then
      strOut = rs!State
    Else
     strOut = strOut & ", " & rs!State
    End If
    rs.MoveNext
  Loop
  ConcatStates = strOut
End Function

5. Then you could use that in a query
Code:
SELECT qryUnionCompanyRegions.CompanyName, concatStates([companyname]) AS Regions
FROM qryUnionCompanyRegions
GROUP BY qryUnionCompanyRegions.CompanyName, concatStates([companyname]);

7. Results
ConcatResults.PNG


Bottom line. If you understand that an MVF field is not a field but a display of concatenated fields in a hidden table then this method is exactly how you would do this with a standard design. Since an MVF is not a field but a display, the fact that you cannot Union them is not really a drawback of an MVF, it is just not an added feature.
 
Update Query
One common statement about MVF is that you cannot easily update them. However here again the update is exactly how you would do it in a traditional design. Like the other examples the hard part is understanding the hidden table.

1. The MVF Region field is a numeric storing the Key to the State table in the hidden table. But the MVF display shows concatenated states. But again that is just a display.

California.PNG


If the companies that use to work in CA all work in Texas you want to update California to Texas.

2. The data really looks like this in the hidden table where it is a junction table
HiddenReal.PNG


3. The keys for CA are 6 and 51 for TX in the Regions table
4.
caltotex.PNG

5 Results
CalTexRes.PNG
 

Users who are viewing this thread

Back
Top Bottom