Matrix of boolean values in an Access form - ms-access

I am designing a form at work where I need to be able to set "Properties" for a large number of (accounting) "structures". I have a "Value" field where the user enters the value that property must take and then I have 1 column for every structure where the user must be able to check / uncheck each property for each structure. Also, I need to be able to suggest checkbox values (aka mapping of properties to structures) to the user so that he/she doesn't have to manually click all the checkboxes that will always need to be ticked. Finally, the number of properties (rows) and the number of structures (columns) should not be assumed to be fixed though I don't want the user to be able to modify it himself. I just want it so that a dev (probably me) doesn't have a hard time adding or removing structures.
For now I have used a local table where each structure is a column and I have hardcoded my properties (which is good). However, I am not sure that using a local table is good design. We normally avoid having forms and tables in the same Access DB to separate forms and data. Also, I'm wondering if there is an elegant solution that I am missing. There will be at least 10-15 structures and 11 properties, that would make 110 (11*10) checkboxes to handle so I cannot do it manually (i.e. create 110 checkboxes and check 110 values everytime...).
Here you can see what that part of the form looks like for now.
I know this will be a chattier question but I really need a design check on this so here are a few questions that I try to make as general and objective as possible:
In Access, how is it possible to create a matrix of controls where 1 column contains a fixed (but changeable by a dev) number of properties, a "value" field that can take text and then 10+ columns with Yes/No values ?
Is it possible to do it without a local table ?
VBA is perfectly admissible.
Thanks.

In Access, how is it possible to create a matrix of controls where 1 column contains a fixed (but changeable by a dev) number of properties, a "value" field that can take text and then 10+ columns with Yes/No values ?
I've never seen any VBA code that does what you describe. VB6 allowed the creation of "control arrays" to logically group controls (and work around some limitations on the number of controls on a form), but I've never seen that mentioned for VBA.
Is it possible to do it without a local table?
Is it possible? Maybe, since you can modify a form via code by opening it in Design View and using CreateControl() to add controls.
Is it practical? Probably not, because the "Access Specifications" section of Access Help mentions the following limit...
"Number of controls and sections that you can add over the lifetime of the form or report: 754"
..so it sounds like code that repeatedly modifies a form could very well break after a while.
My recommendation would be to create a temporary table, use it, and then discard it. If you're worried about front-end bloat then you could create the temporary table in a temporary .accdb file and then link to it.

Maybe I'm missing something, but it seems pretty easy to me.
Make each structure a record.
Then in another table, make each property a record with a 1-many relationship with the structure table. So, each structure will have many properties.
Then a form based on the structure with a sub-form based on it's properties.
Default property values can be set in the table structure.
And of course the tables can be linked from another DB.

In Access, how is it possible to create a matrix of controls where 1 column contains a fixed (but changeable by a dev) number of properties, a "value" field that can take text and then 10+ columns with Yes/No values?
I'm still not certain why you want multiple bits/booleans in a single column, but you might be able to utilize bit logic and long integer column. VBA does something like this with its constants. For instance, in a MsgBox, you make your type = vbCritical + vbYesNo. Its result is in an integer value that VBA interprets to make a Critcal MsgBox with only a Yes and a No button. The reason this works is because the value of each constant is so distinct that any summation with like constants results in a unique value that can be de-parsed. It's fairly elegant from a user perspective, but I'd hate to do the math on the back-end to make such a function work.
It might be better to maintain a separate table of available properties and/or property sets and build / maintain your property sheet that way. You could assign property sets as well as individual properties to particular controls. You could also specify in either table whether there is a default value for that property and/or what that value is.
It is also likely that you do not need that many bits. I'd be happy to narrow my answer to your situation if you could update your question with more detail regarding the nature of your bit need(s).
Is it possible to do it without a local table?
You might be able to create a DAO.Recordset dynamically in Access.
It might be better to adjust your properties table(s) (see above) to be a permanent table in one of your databases rather than re-populating the same data every time.

You could take more of a master/detail approach, combining your bit fields into a string description describing the boxes which are checked.
For example, if you have a structure named 'structure1', value 100, and 5 condition bits set, you could have one string column with text 'cond1, cond2, cond7, cond8, cond9' and then another button allowing them to modify that set of conditions for that single structure.
You'd have fewer checkboxes, anyways.
The only thing I can think of equivalent to 'a matrix of controls where 1 column contains a fixed (but changeable by a dev) number of properties' is an editable query result set.
You'll need a table for your structure -> default conditions set, if nothing else, but it doesn't have to be in the same db as the front end.
HTH

Related

How can I get Access to list available values in column filters when using a non-Access backend?

I'm using MS-Access (365) as a frontend to a Postgres table backend. Communications mech between them is ODBC. That seems to work fine.
Before I migrated away from the MA-Access backend, a list of check-able options would appear in a column's filter options when filtering column data. For example, when you clicked on the little carat next to the column name/header, you would see the "Sort A to Z" and "Sort Z to A" (as before) then for the filtering, you would see "Text Filters" as before (with options for specifying the filtering), but then you would also see the options, including "Select All" (a toggle) and then each value with a checkable box next to it. The user could select/deselect to filter based on the values. But I no longer see that list of checkable values in the filtering.
The column values are constrained to values in a different table which contains the valid values for that column (a traditional primary/foreign key relationship) and that works fine in the pulldown as a means for a user to pick one of the valid values when editing a record/column.
Since the values of the column are constrained in a predictable, or at least queryable way, I would think that there might be a way to use that to restore those checkable boxes in the filtering. I looked at the "Design View" of the table and tried a few things to see if I could get this to work. No luck.
Any ideas ?
You can try this setting:
File->options->Current Database-> Filter lookup options.
the real problem here is that you really should not be loading up forms with SO MANY records in the first place. But you can try the above settings - and of course increase the 1000 rows. But this is going to cause a performance issues, since this suggests that forms and view are loading large recordsets and THEN you are applying filters to that data. So keep this pulling of data in mind. It is preferable to provide some kind of search form, and let the user search BEFORE you pulled large amounts of data.
So all in all this is a less then ideal option from a performance point of view. But if data pulls are not too large, then this certainly is a "nice" feature - just not a great from a performance point of view.

Access combo box for DB mapping table 2-1 Table relation

I've run into a bit of a snag with a project I'm working on, and being new to Access I don't know if what I want to do is possible without VBA. I've looked around but all I can find are answers related to showing multiple columns, not controlling multiple fields in my DB.
To paint a picture I have a mapping system set up in my DB to help me distinguish the name and type of data is held in a table.
The setup is as follows:
-Data table is "LineItems" with an ID and the line data (think typical excel format)
-Mapping table is "LineItem_Mapper" with LineItem_ID, DataType, and Entity_ID
-A helper table "Data_Type" with ID and Name
-two "Entity" tables with differing properties both have ID and Name
The reason for the split is on data type is that the two types of data behave differently. One type has a parent child relation, and the other is a standalone row. I want to preserve this structure in my DB and feel I have done so with this mapping.
Now, on to the issue I'm running into. In my Access data entry form I want to use a combo box, as the options a user may chose for each line when entering are finite. However, this combo box is affecting the Mapping table above. I have been able to populate the box with my desired list with a custom query built from my 2 entity tables, but I don't know how to get Access to create or update the Mapping table using this box.
what I want to happen is when I chose something in the box, a line is created (or changed) in the mapping table with all 3 columns being populated. first the LineItem_ID for the line I am populating, and then the DataType and Entity ID to reflect the proper mapping.
Can Access do this on its own? Or do I need to do this with VBA?
As requested by the OP converting my commend as an answer (with a little bit more detail):
By far your best option is to use VBA. I doubt there is another way and even if there is it would be so convoluted it would be unworkable and unmanageable.
This should get you started:
In the combo box properties go tot the events tab and in After Update or On Change (look up the difference between the two events to see which behavior you prefer) click the down arrow and select [Event Procedure], then click on the … button. This will create a VBA module for you complete with the function that runs when the selected event is triggered.
You can use DoCmd.RunSQL "[Access SQL INSERT statement]" to add records to tables.
You can use Me.[MyComboBoxName] to get the current value of the combo box. Similarly the value of anything else in your active form.
You can use DLookup to get the value of any record in your tables.
Hopefully these will give you a relatively quick start.

When to use lookup field?

Whenever I'm considering the option of making a field's contents being extracted from a predefined list, should I make a new table to list exclusively those options, then make a query, then make a form-level lookup field to select it?
This seems like creating A LOT of tables and queries from those tables, just to have a lookup field. I have no idea what the normal number should be, or if there is a clever way of doing queries without creating new tables everytime that I'm not aware of.
For example: I have an Addresses table, and each address can be of three types: home, professional, other. Should I make a table exclusively to list those items and then reference it through a query and a lookup field in a form?
What's the procedure here? Thanks in advance!
Use table lookup when you are going to use this lookup in another entity or you are going to allow the end-user to edit entries of this lookup. In other cases, be free to confine yourself to use constant list of values.
Feel free to ask more.

viewing underlying value in access lookup field

If I have a lookup field in Access with the first (bound) column hidden by setting field widths to 0";1", is there a way to see the real underlying value of the field without having to change the formatting of the lookup column?
I don't believe there is a way to access the available values without editing the lookup column.
With that said, I would point out the following:
Changing the formatting of the lookup column only impacts 2 things.
When you navigate the records from the table view you will see the new definition.
Any forms created in the future will now inherit the new definition.
In other words, changing the formatting of the lookup column doesn't impact any forms you may have already created based upon that field.
You can have a more descriptive description in your table that is completely separate from the definition in your forms.
If you want to know all of the values I suggest that you edit the drop down to show a concatenation of columns 1 and 2.
For example, lets say you had a value list of
1;foo;2;bar
The value list could be changed to
1;1-foo;2;2-bar
Then you know at a glance what the "hidden" field value represents. (The same could be done if the record source is a query.)
Turns out that there is a very simple way to do it. In the query, go to field properties and click on the "Lookup" tab, and choose textbox.

How safe using combobox to input foreign key

In a Related Tables, you need to enter a FK to link to the parent table.
You either key in the FG from memory !!!!!! or use help.
The standard procedure is to design the field as combo box AND use SQL to select the field that will help to input the ID of the parent table. So, if you want to input foreign key 3 , the combo box will display what 3 is then when you selected Access will insert 3 for you.
My question is since I can later on, edit the table and change the the value to another value, and mess the whole thing up!!! HOW can I lock my first choice so it will stay unedited ?
My second question is: Is this the only way to input the FK if you do not remember the exact ID number or there are thousands of records in the parent table.?
Re. #1
In Access 2010 you could use a trigger to check whether the value has been used in another table as a FK and not allow the change. In previous versions all you could do, would be to hide the navigation pane or make the table hidden.
Re. #2
You could use a listbox (basically the same idea as a combobox).
You could include the lookup table in the underlying query, but then there is more danger of the values getting changed, which is exactly what you were worried about in the first question.
Stick with the combobox.
You can create different versions of a form. One might have Allow Edits, No, another might be Data Entry, Yes, meaning that it can only be used to create new records.
However, suppose someone is creating a new record and they select the wrong FK by mistake. How can they correct this? You could use VBA to produce a confirmation dialog in the first instance, and perhaps an Undo button where VBA would deliberately perform the Undo. Access 2010 also has Data Macros (equivalent to triggers) that you might use to store the old and new values, and other information, when a user changes a FK value.
Access does not implement user-level security, so the user can still open and change data in the raw-data tables. You should, however, have enforced referential integrity on the table-join, so that a user cannot enter a FK that doesn't already exist as a PK in the related table.
In summary, you could add additional columns to the combobox to help the user select the correct item, and you might consider an additional confirmation dialog (a MsgBox) before a record is saved into the data-table. But you cannot prevent people from making mistakes. (Enforcing Referential Integrity will prevent nonsense data from being entered.)
Second question:
A combobox (or possibly a listbox) is the easiest way for users to enter a FK value, without relying on memory. An alternative would be to use a button (or other control and event) that opens a secondary form. This form might have some filtering features to help the user find the correct FK value. When this form is closed you would then need to write some code to update the relevant control on the main form.