Determine whether row is selected in MS Access 2007 List Box - ms-access

I have a situation where I want to associate multiple values from one table with a value from another. I've got my data structured with a many-to-many join table in between, and I'm trying to manage the membership in the join table.
This question is about the UI portion of the process. I think that what I want to do is to present the user with a multi-select List Box control on a form that holds the ID of TableA constant (and, incidentally, hidden). The List would be populated with all the (fairly short list of) rows from TableB (descriptions displayed, IDs in hidden column). On load, I'd select those rows of the list that participate in the M-M join. The user could select additions and/or deselect removals.
What I'm not sure about is how to tell whether or not any given row is selected. I know about the IsSelected collection--if I were just adding, I'd walk that with For Each, but I need to remove any that have been deselected, and I need to not re-add any that already exist. What I'm thinking at this point is walking the whole list, testing each selected value & inserting it if not already present, and testing each un-selected value for possible deletion (hmmm--that's starting to sound needlessly complex....).
What I started out to ask was "how do I tell if row(x) is selected?" I'd still like the answer to that, but I'm open to other suggestions for managing the base problem, as well

In seems that you have a list that you are using to create the selected items. After the user has updated the list box, you can compare .ItemsSelected to the rows of the list that participate in the M-M join. Missing items can be deleted and additional items can be added. A few very rough notes:
For Each itm In Me.AList.ItemsSelected
rsJoinList.Find "ID=" & Me.AList.Column(0, itm)
If rsJoinList.NoMatch Then
'To be added
Else
'To be deleted
End If
Next

Related

How to save row values from one field in subform to main form record? - Access

I have a parent form (frmGroupSession) that has a subform (SubFormParticipants) in datasheet view. The subform is based off a query that selects all participants ([CLIENT ID], [NAME], [ATTENDED]) that had attended a specific group [GroupID] on a specific date [GroupSessionDate]. The parent form saves to a table that logs group sessions (tblGroupSessionLog). I need to save the group's participants [CLIENT ID] to the record within tblGroupSessionLog
Basically, I need to pass data from the subform to the record within tblGroupSessionLog. I'm not sure what the most effective way to do this, if it's possible at all. Ideally, I would like to have each unique participant [CLIENT ID] stored in its own field within tblGroupSessionLog. If there were 20 participants in the subform then each row value from the first column/field [CLIENT ID] would be passed to the corresponding field within tblGroupSessionLog ([ClientID1] thru [ClientID20])
I am relatively new at this. Even asking the question was difficult.
I am not sure what else I can provide to help you wizards with the solve, but let me know and I will.
Thoughts? Ideas?
Access 101 : You have a many to many relationship You should look that term up but in short it means clients can belong to many groups and each group can have many clients. (so bang your data into a normalized structure similar to the following:
First tip make sure to add the relationships under database tools (you should look that up). Access needs to know how the tables are related to manage the keys behind the scenes and sometimes access makes better decisions about automatic form creating when it already knows the relationship structure. Once your data is properly structured access makes it easy to produce functional if much less than styling data entry forms which can also be used as even worse search forms. For instance Click on any table and hit create form on the ribbon and access will create the data entry form form you.
Basic Style tip 1: Always delete primary key fields like ClientID from the form. The field is still there in the form's record source being managed by access. Users almost never need to see any table keys. This gives you a basic data entry form which you can also use to scroll through any clients you have entered using the record selector circled at the bottom of the frmClients.
Play around with the record selector to see how it works. In particular go past the last record and you will find you can enter new clients and access will automatically give them a ClientID. You can also cycle through your Clients and update them using this form it just isn't stylish. In the same way we can make a form for the groups table.
You make a form for the frmGroupSessions table in the same manner as the others but add a step. Replace the text boxes holding ClientID and GroupID with human readable comboboxes. Here is a link to help with that: https://www.google.com/search?q=access+change+text+box+to+combo+box&oq=access+change+text+&aqs=chrome.0.0i457j0l2j69i57j0j0i22i30l2.7503j0j1&sourceid=chrome&ie=UTF-8#kpvalbx=_r0sFYJ7vBcfY5gLz2aTgBw15
Becomes:
At this point play around to learn. Use the Record Selector at the bottom of frmGroupSessions to add and modify data. Play with the Tables and see what happens. Start messing with the form properties in particular the default view. Soon you will have ideas about how the form could be better and you can start figuring out how to style them.

Open the Edit List Items Window with a button in Access for ListBox Object

I have a List Box in my form.
I'm allowing the user to edit the contents which is a feature I'd like to have and the default feature works great for my needs. I know if you right click the list you get the Edit List Items Window too.
But my issue is most of my users are not Access savvy, so they may not know to right click to open the window. I'd like to make it so the blue edit button will open that window with VBA, but I can't figure out how to call opening that window with VBA.
Is this even possible, if so I'd love to know the call.
You can simulate the click on edit
Private Sub btnValueListEdit_Click()
Me.myListBox.SetFocus
DoCmd.RunCommand acCmdEditListItems
End Sub
But this is not recomended!
Have a look at Add items to a Value List from Allen Browne.
You can remove items that are actually being used in other records.
You can correct a misspelled item, but the records that already have the misspelled item are not corrected.
You can add items to your form, but in a split database, other users don't get these items. Consequently, other users add items with other names to their forms, even where they should be the same item.
If you answer No after using one of the new items, you now have items in the data that don't match the list.
If you answer Yes in an unsplit database, you introduce strange errors as multiple users attempt to modify objects that could be in use by other people.
If you answer Yes in an split database, the list of items in one front end no longer matches the lists in the others.
Your changes don't last anyway: they are lost when the front end is updated.
Conclusion
Use tables, not value lists, to manage lookup data. Create relationships with Relational Integrity.
Use these lookup tables (or queries based on them), as the RowSource for your combos. Do not use Value Lists for anything more than the simplest of choices that the user never needs to edit.
Use the Not In List event to add data to simple, single-field lookups such as types or categories.
If you only use Access 2007 or later, the List Items Edit Form property is a quick and easy way to nominate the form to use for managing the list items.
To edit the list in any version of Access, or to control how the editing works, use another event such as the combo's DblClick.

Access: Appending Related Tables

I am working on a small side project. Below is an image of all my relations. I only have the tables set up so far, and a couple Queries that sorted my a couple of my tables a certain way to be used as lookup columns.
Is there a way to append new records to multiple tables at once?
I have experimented with this a few different ways. The thing that stumps me is when I create a form and corresponding sub forms (I can make sub form after sub form that has the entire string of things that could be input across multiple tables, which is not very aesthetically pleasing or easy to use), I have to enter data multiple times. Referring to appending the invoice item as well as the item list tables. I would have to enter the following;
Invoice Number (From invoice item)
Item Code (From invoice item)
Item Code (From item list)
So I end up having to type the item code multiple times, this occurs across the entire chain of tables I need to update in order to create an order.
Also in case you are wondering, all the tables seen in the diagram are update at time a new order is created. (This is a resale business so inventory is never held and item (in the Item List table) are added new at time of order.
So the Invoice table needs to be appended which starts the chain that I am trying to accomplish. Invoice number gets entered which I would like to automatically carry over to Invoice Item in wait for the Item Code to be entered to complete the composite key but without having to type the Invoice number again, and so on and so forth.
This is referred to as a Cascading Update and is essential to enforcing Referential Integrity.
What you want to do is:
Click the relationship line for the relationship that you want to
change. The relationship line appears thicker when it is selected.
Double-click the relationship line. –or– On the Design tab, in the Tools group, click Edit Relationships.
The Edit Relationships dialog box appears.
Select the Enforce Referential Integrity check box.
Select either the Cascade Update Related Fields or Cascade Delete
Related Records check box, or select both.

How to filter a table field's listbox by the current record

How do I set up a table's field so that the listbox is filtered by that row's data?
I have a master table (TblMain) with 2 important fields: Client and Division. Currently, the Division field is set up as a simple Listbox that pulls from another table (TblDiv).
However, the Divisions are specific to each client with little overlap. My current basic setup doesn't make that distinction, so any division can be chosen for any client.
How do I set up Division so that the listbox is specific to that row?
I've tried doing an inner join within the row source (i.e. Select TblDiv.Div from TblMain Inner Join TblDiv on TblMain.Client=TblDiv.Client) but that doesn't seem to work, probably because I'm not referencing the Client value of the active row.
(I should add I'm not talking about Forms or Reports. Just the Table object)
Are you trying to add a look-up field to a table? This is almost never a good idea. Are you trying to filter a combobox on a continuous form? You cannot sensibly do this - any change will affect the appearance of every row, which is confusing to the user. There are work-arounds. For example, you can show a textbox for the Reference and a "Change reference" combo. This will avoid confusing users because the bound textbox will not update. You can set various properties of the change combo with conditional formatting to make it all prettier. Alternatively, you can use two subforms or a pop-up form to edit data.

Calculated control does not recalc automatically

Firstly, a bit about my setup.
I have a primitive database of three tables:
A. Table that lists various locations: [location_code], [location_name]
B. Table that describes items: [item_code], [item_name], [item_price]
and finally a table that ties the roo^H^H^H whole database together
C. Table says which items are stored at each locations and in what quantities: [location_code], [item_code], [item_quantity]. This table can have multiple entries with the same [location_code], since different items can be stored at the same location. Basically, this is a schoolbook implementation of one-to-many relationship from locations to items, with a extra attribute (quantity) attached to each location-item link.
Now, all I need to do is to create a form that would list all items stored at certain location. This is a basic use-case for "subform" feature in Access. The main form simply navigates through different locations, while the subform lists the items.
I use
SELECT C.location_code, B.item_name, B.item_code, B.item_price, C.item_quantity
FROM B INNER JOIN C ON B.item_code=C.item_code
as a record source for the subform. The main form is linked to subform by [location_code]. The subform is set up with list layout (not table layout), i.e. each database field is given its own control element.
So far everything works perfectly. I select the location in the main form, and the subform gives me a list of editable [item_name]-[item_price]-[item_quantity] triplets for the current location.
As the next step, I want to add a calculated control to each of the above triplets. I want to know the total price for each kind of item (i.e. simply the [item_price] * [item_quantity] in each line). Easy, I add a calculated control to the "repeatable" area of the subform and specify
= [item_price] * [item_quantity]
as the formula for the value. Again, everything works perfectly. Now instead of the above triplets, my list has four entries per line: [item_name]-[item_price]-[item_quantity]-[total_item_price]. And, what is important, when I edit [item_price] or [item_quantity], the [total_item_price] gets automatically reevaluated once I finish editing.
And as the final step, I want to add another calculated control that would display the total price of all items stored at the current location (let's call it "grand total"). A also place that control into the subform (into the "footnote" area this time) and specify the following formula as its value
= SUM([item_price] * [item_quantity])
Now, this works. The total value is calculated correctly each time I change the location in the main form. Also, when I change [item_price] for any item at the current location, the grand total is also updated automatically. However, when I change [item_quantity], the grand total does not update (???). Hitting F9 will make it update. Changing the current location back and forth will update it. But, unfortunately, a mere change to [item_quantity] does not trigger an automatic update.
Does anyone know, what could be wrong here? Why do changes in [item_price] trigger the automatic update of the grand total, while changes in [item_quantity] do not? Intuitively, these fields seem to have the same status (except that the former comes from table B, while the latter comes from table C). Why is the behavior different? How do I make it update automatically?
In your subform's after update event, explicitly recalculate the total price control.
Me.txtTotalPrice.Requery
If you tab through the record and advance to the next record does it still not update. I am thinking that the price is the last field in tab order so when you change it, you tab on to the next record and the change is committed. If I am right then when you edit the quantity, your tab advances you to the price field which is still in the current record so the change is not committed to the table yet. If you advance further through, that should complete the processing.