I have a simple database with two tables and one relationship between them:Employees, Managers, Relationship.
Each employee has exactly one manager, but each manager can manage multiple employees. For adding employees to the database, I have this form: Employee Form.
As it stands, the user must enter the ManagerID of the new employee's manager when adding an employee. What I would like is for the user to select the new employee's manager from a combo box. The drop down options should be the names of the managers (say, from the FullName column of the Managers table). However, once the user selects a name from the drop down, I would like the ManagerID corresponding to that name to be saved in ManagerID field of new employee's entry.
Can I solve this problem by basing the form off of a query, or will I need to customize the form/combo box with some VB code?
This will take basically just one line of VBA code; most of it is done through Access.
Point the combo box's data source to the table of managers. In the 'Row Source' property of the combo box under 'Data' in the Property Sheet, set the Row Source to a query for the first + last name of the managers. For example:
SELECT ManagerID, FirstName, LastName FROM tblManagers ORDER BY FirstName;
Then go to the ComboBox's Format tab and set the Column Count to 3. Set the column widths appropriately; to hide the first column with the ID field, set it to 0, and set the other column widths to whatever looks right. For example: 0";0.5"'0.5" will hide the first column, and set the other two to a half-inch width.
To have the TextBox automatically display the ID number of the manager in the ComboBox (which honestly, if you don't need to display it for some reason, why not just hide the ID field from the user altogether? Food for thought), you will need to add the VBA code to the ComboBox's AfterUpdate event. That way, whenever the combo box is updated, the textbox will change accordingly. You may need to first go into design mode and change the 'HasModule' property of the form to 'Yes'; after that, use the 'Events' tab of the ComboBox's Property Sheet to open up the code builder for the 'After Update' event. It should take you to the VBA builder, with an auto-generated Private Sub [combobox's name]_AfterUpdate()
Set the code to the following:
Private Sub ComboBox_AfterUpdate() 'Obviously, sub your combo boxs name for ComboBox
Me.TextBox = Me.ComboBox 'Obviously, sub your text boxs name and your combo boxs name here
End Sub
Since the default bound column for the ComboBox is the first, this sets the value of the text box to the value of the first column of the ComboBox.
Related
Good Evening,
I am working on a Combo Search Form that is designed to search for information by criteria. The form has a combo box containing field values and a text box beside it. The selection of a field value in the combo box will fill in the text box beside it with the relevant information for that record, all the relevant information is contained in the PetTable.
I have managed to get the combo box to display the fields from the PetTable by setting the rowSource to PetTable and the sourceType to Field List... however that's where I hit my dead end.
In the Text Box beside the combo-box I tried grabbing the value of the combo box and putting it into the textbox by making the Text box control source "=ComboBox", however this just created a textbox which has a literal text string to that of the combo box.
My next thought was to make the text box Control source "=PetTable.PetComboBox" my thought was that the PetTable references the table with my information and the "PetComboBox" becomes the field a need to get. This did not work either and gave a #Name error"
What should be happening is: In the Combo-box if I selected [Pet Name], I would hope that the textbox beside it becomes "Fido" but instead it also becomes [Pet Name].
Any and all help would be appreciated!
Thanks
Desired Effect
What you need to do is to change the Row Source Type of the Combo Box to "Table/Query". Then in the "Row Source" click on the "..." to open up the Query Builder. Select the table that you want. Add the columns that you want. I would suggest the table's primary key PetID, and then any other fields - in your case at least PetName. You may also want to sort by PetName to make it easier for the user to scroll through. Close the Query Builder and save the changes. Change the combo box's ColumnCount to 2, and set the Column Widths to be "0cm;6cm" (setting the first column to have a width of 0 means that it is not displayed to the user).
Now move to you TextBox, and set the Control Source to be:
=[Combo0].Column(1)
Note that columns in a combox box are 0-indexed, so the first column is column 0, the second (in your case containing PetName) is column 1.
As you actually want to show the field names, rather than the data in the combo box, then you will need to set the RowSourceType to be "Field List", and then select the table name as the RowSource.
You will then need a small piece of VBA to lookup the value of that field in the table for the current record:
Sub sListFieldData()
If Not IsNull(Me!Combo0) Then
Me!Text2 = DLookup(Me!Combo0, "tblPet", "PetID=" & Me!PetID)
Else
Me!Text2 = ""
End If
End Sub
And you will then need to call this procedure in the combo box's AfterUpdate event (to catch when it has been changed by the user) and also in the form's Current event (to catch when the user moves between records):
Private Sub Combo0_AfterUpdate()
Call sListFieldData
End Sub
Private Sub Form_Current()
Call sListFieldData
End Sub
Regards,
I am currently developing A quote sheet for work, I have 21 Combo boxes that are all populated by the same row source. The problems that I am having are When all my combo boxes are set to the same control source all the list values in the combo box are filtered and set to one value. For example combo box 1 is selected and prep is selected now the other 20 combo boxes are set to prep, and I can't select the other options. Now if I have no control source for my combo boxes than previous example works. If I select combo box 1 and set it to prep then I can select combo box 2,3,4... and put any value I want for each one. I want to be able to have each combo box with its own value.
The reason I am wanting the combo boxes to have the same control source is so when a combo box has a selected value it will add a new record to my table. So if 10 combo boxes have values selected then there will be 10 new rows added to my table when I click my add record button.
I am thinking a maybe having a loop do the work, but am not to familiar with with using vba to run sql??
You can't use the same control sources to generate multiple records on the same form. They must be unbound. At least, I don't know how to make that work the way you have it set up, but can still help.
Delete the control sources but keep the row sources.
You will need a query to save the values to your table:
INSERT INTO MyTableName ([MyFieldName]) VALUES ('[ComboboxValue]');
Copy this code and paste in query builder. Overwrite "MyTableName" and "MyFieldName" with the appropriate object names for where you want a single combobox value to be saved. It only adds one row at a time. [ComboboxValue] will be the parameter we use to pass each combo value to the query to execute.
Name the query whatever you want and save it. I will use the placeholder "MyQuery," make sure you update it!
Create a command button on your form, and in its On Click event, paste in this VBA code (you will need to update the combobox references where I use Me!ComboboxName):
Dim qdf As DAO.QueryDef
Dim combo As String
Set qdf = CurrentDb.QueryDefs("MyQuery")
combo = Me!Combobox1Name
qdf!ComboboxValue = combo
qdf.Execute
combo = Me!Combobox2Name
qdf!ComboboxValue = combo
qdf.Execute
'Copy those three lines for each combobox, adjust your combobox references accordingly,
'or use a loop
'End your procedure like this:
Set qdf = Nothing
If you are using a multi-column combobox, you may need to adjust the reference from Me!Combobox1Name to Me!Combobox1Name.Column(1).
I have set a combobox to be visible in column1 of my Datagridview. Now I'm trying to fill same row of Datagridview where Combobox appears, from Combobox_Key_Down event. This is my code for showing combobox:
Private Sub My_DGV_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles MY_DGV.CellMouseClick
If e.RowIndex >= 0 Then
With My_DGV
If .Columns(.Rows(e.RowIndex).Cells(e.ColumnIndex).ColumnIndex).Name = "Column1" Then
.CurrentCell = .Rows(.CurrentRow.Index).Cells(.CurrentCell.ColumnIndex)
Show_Combobox(.CurrentRow.Index, .CurrentCell.ColumnIndex) 'function that shows my Combobox in that cells
Combo.Visible = True
Else
Combo.Visible = False
End If
End With
End If
End Sub
I tried many things, but I don't know how to determine in which row Combobox appears and how give that Datagridview row my Combobox values. Someone please give me a clue of what should I do. Thanks in advance !
The first problem with your approach is that the DGV can have only one DataSource: it can either show the m:m association table or the related elements. If you include columns from one of the tables into the query for display, the table becomes non updatable and users can be confused why they cannot edit something they can see. It seems of little value they way you describe it, since they cannot see the detail data until after they make a selection.
Next, it requires another datatable to supply the details for CboColB. Since you want the DGV bound to a DataTable easy updates, you end up having to poke data into cells over and over.
Finally, consider what the user is confronted with. Using a Country table (200+ countries/locales with ISO code and name) and a list of flag colors, a table for CountryFlagColors will have hundreds and hundreds of rows (at just 2 colors per flag).
A better display might be to filter the m:m table (flagcolor) to a selected item so the user is only confronted with the data subset they are currently interested in:
The datatable used in the DGV is built from the m:m table:
The Country column is hidden.
When they choose from the CBO at the top, that is used as a RowFilter to limit the rows to the relevant ones.
In the RowValidating event, when the country cell is DBNull, copy the SelectedValue from the country combo to the DGV cell to fill in the blank
I would probably really make the user click a button and manually add a row so I could seed the country value then rather than depend on events.
It uses a DataAdapter and after adding X number of flag definitions, da.Update(dtFlagColors) applies/saves all the changes.
Ok, so that provides the core functionality to assign N color selections to define the flag colors for a country. The missing element is the 'details' for the Color item.
I added a meaningless int and string item to the Color table, one way to display these would be to create an alias in the SQL with the important details. Displaying them as discrete elements can either make the query non updatable or invites the user to edit things they cannot edit here. My silly SQL:
"SELECT Id, Name, Concat(Name , ' (' , intItem , ' ' , stritem,')') As Info from FColor"
Then use 'Info' as the display member on the CBO column in the dgv:
dc = DirectCast(dgvCF.Columns(0), DataGridViewComboBoxColumn)
dc.DataSource = dtFlagColors
dc.DisplayMember = "info"
dc.ValueMember = "id"
dgvCF.DataSource = dtSample
The combo column has its own datasource of course, in order to display one thing and use another for as the Value to give back to you. Result (the values are silly):
It is not exactly what you want, but comes close and is much simpler. It also requires almost no code for driving the associative entity. Another alternative would be to use a DGV as the second picker so you can show the extended data and manually add rows to a DGV:
If you set the dropdown style to Nothing, it looks like a text column.
I have a datasheet form ItemsForm based on table Items. Items is one-to-many related to table StatusHistory, between Items.ID and StatusHistory.ItemID. There is also a Status table, with the relationship between Status.ID and StatusHistory.StatusID.
I want to add a StatusBox combo box to ItemsForm so that when the user selects a Status value from the box and then moves out of the record, which should trigger the Form_BeforeUpdate() event, a new entry is added to StatusHistory with the Items.ID of the currently selected entry.
I've successfully added the StatusBox field to the form and populated its list by setting its RowSource with a query of Status. But there are two big problems:
I can scroll through the values in the box's list, but after I
select one, it doesn't show up in the field; the field stays blank.
When I select a value in StatusBox, and then click onto another
record, the Form_BeforeUpdate() isn't triggered. It seems that
Form_BeforeUpdate() is only triggered if I modify data in the
fields from Items that the form is based on. Is there a different event that I should be using here?
Solved it as follows:
The ID field for Status is actually named StatusID instead of
ID. Fixing this allowed me to enter values into the field.
I put the code into the BeforeUpdate() event for StatusBox, viz:
Private Sub StatusBox_BeforeUpdate(Cancel As Integer)
End Sub
This means it gets triggered whenever I select an item in the list, rather than when I move to a new record, but for now that's all I need.
I'm trying to bind multiple tables together and have a subform display data based on my combobox (ID name = CbproductName) selection in a form named Form2. I'm using Ms office Access.
This is the query
SELECT Employee.EmpName, Employee.EmpCode, Employee.CompanyID, Employee.DeptID,
Employee.ComputerID, Software.ProductName
FROM Software
INNER JOIN (
(
Computer INNER JOIN Employee ON Computer.CompID = Employee.ComputerID)
INNER JOIN Application ON Computer.ComputerName=Application.[A-ComputerID]
)
ON Software.ID = Application.SoftwareID
WHERE Application.SoftwareID = Form2.CbProductName;
However it keeps prompting me to enter the parameter value when i run the form, and it doesn't display the result of the entered value. it also doesn't change according to the combobox selection.
Can someone point me at a direction to get it done?
In a query, reference a form by its name as a member of the Forms collection. And then reference the value of a control on that form using the control name. It should look like this pattern:
Forms!FormName!ControlName
In your query, change the Where clause to this:
WHERE Application.SoftwareID = Forms!Form2!CbProductName;
Then make sure to refresh that query in after update event of CbProductName. You indicated the query is used as the record source for a subform, so assuming the subform control is on the same form as the combo box, try this as the after update procedure:
Private Sub CbProductName_AfterUpdate()
Me!SubformControlName.Form.Requery
End Sub
Beware, the subform control name may not be the same as the name of the form it contains. Make sure you use the name of the control.