I am having trouble setting the row source of a certain combo box on my form (viewed as a continuous form, although I also seem to have some problems in single-form mode).
The combo-box is bound to a field called supplierID, and is meant to present the user with a list of all the possible suppliers for an item. The row-source I am using for the combo-box is:
SELECT DISTINCT Suppliers.name, Suppliers.supplierID
FROM Suppliers
INNER JOIN PartsSuppliers ON Suppliers.supplierID=PartsSuppliers.supplierID
WHERE PartsSuppliers.partID = partID;
When I view this query in the query designer (with a partID hard-coded), it works fine - it selects all the possible suppliers for the chosen item, and doesn't show any other items. But when I look at the items in the combo-box, it shows all the suppliers present in the PartsSuppliers table (which has just two columns, mapping the parts to the possible suppliers for them).
I have also tried to set the combo-box's RowSource using some VBA in the OnFocus event (hardcoding the partID value in), but it never seems to change the RowSource. The VBA code I am using is:
Private Sub supplierID_GotFocus()
Dim query As String
query = "SELECT DISTINCT Suppliers.name, PartsSuppliers.supplierID "
query = query & "FROM Suppliers INNER JOIN PartsSuppliers ON Suppliers.supplierID = PartsSuppliers.supplierID "
query = query & "WHERE (((PartsSuppliers.partID)=" & partID & "));"
supplierDropDown.RowSource = query
supplierDropDown.Requery
End Sub
I also tried opening that query in a RecordSet, and then using setting that RecordSet as the combo-box's RecordSet, but that didn't work either.
What am I doing wrong, or is there some other way that I should be looking at to make the correct drop down?
N.B. I have seen Custom row source for combo box in continuous form in Access, but that accepted solution didn't work for me either.
Use the OnEnter and OnExit events to change out your RowSource.
Private Sub supplierID_Enter()
supplierDropDown.RowSource = _
"SELECT DISTINCT Suppliers.name, PartsSuppliers.supplierID " & _
"FROM Suppliers INNER JOIN PartsSuppliers ON Suppliers.supplierID = PartsSuppliers.supplierID " & _
"WHERE PartsSuppliers.partID = " & partID & ";"
End Sub
Private Sub supplierID_Exit()
supplierDropDown.RowSource = _
"SELECT DISTINCT Suppliers.name, PartsSuppliers.supplierID " & _
"FROM Suppliers INNER JOIN PartsSuppliers ON Suppliers.supplierID = PartsSuppliers.supplierID;"
End Sub
I've been struggling with how to avoid the 'blanks' left behind in a datasheet once Combo items are restricted and couldn't find any straight forward option for a long time....until now!
Leaving all of the available options in the Combo box but adding a temporary validation rule, using OnCurrent, does the trick perfectly.
Hoping this prevents someone banging their head on the desk for as long as I have.
Related
I'm new to MS Access and have been developing a basic CRM system. All has gone well so far, but am banging my head against what I assume is a very simple problem... I can understand VBS and get my way around Access in general, but am by no means an expert in either realm.
How do I make an unbound combobox automatically set itself to a certain value based on other values in a table?
I have a form for users to edit employee information, and this includes comboboxes for inputting an employee's Division and Branch. There are about 10 divisions, each with around 5 branches.
The Branch combobox saves the BranchID to the tblEmployee table, with this acting as a key to the tblBranch table. The tblBranch table also has BranchName and DivisionID, with DivisionID as the key to the tblDivision table, which basically just has Division ID and DivisionName.
Right now the Division combobox is unbound, as this is merely there to allow the user to narrow down the Branches combobox. Cascading the menus down like this works fine once you click on the Division combobox, but when I open the form, the Division combobox shows up blank (and therefore the Branch combobox also shows up blank, as it has a criteria reference to the Division combobox).
How do I make the Division combobox look to see what the BranchID is for a specific employee, and then pre-set itself with the relevant Division?
I tried doing this both by setting a binding and also as an event, but I couldn't get either way to work properly... (likely just newb-ness on my part).
Thanks!
Thanks! Glad to see I was generally on the right path. It's still not working, however, and I think it's because I'm not understanding the YourEmployeeIDField.
My code is as follows:
Private Sub cboDivision_Enter()
Dim sql_ As String
sql_ = "SELECT d.Division " & _
"FROM tblDivision d INNER JOIN (tblBranch b INNER JOIN tblEmployee e ON b.BranchID = e.BranchID) ON d.DivisionID = b.DivisionID " & _
"WHERE e.EmployeeID=" & Me.txtEmployeeID
Me.cboDivision.RowSource = sql_
End Sub
I removed the selection criteria on the comboboxes to make sure that things weren't getting filtered out accidentally.
I tried using EmployeeID, e.EmployeeID, txtEmployeeID (the field on the form), and Me.txtEmployeeID, without much luck.
After investigating the RowSource approach a little bit more, I wonder if I may not have explained what exactly I want? (Or I'm just misunderstanding) The combobox cboDivision is populated with the tblDivision.Division, which is want I want. However, because it is unbound, when a record is loaded in my form, cboDivision is blank. I want it to display the Division associated with the bound cboBranch combobox (but when you click on cboDivision, it still has the full list of Divisions available to select).
The button code that I'm using is as follows (it's simplified SQL, but the same result happens with your code):
Private Sub Command240_Click()
'Me.cboDivision.Value = 8
Dim sqlStr As String
sqlStr = "SELECT d.DivisionID" & _
"FROM tblDivision d INNER JOIN tblBranch b ON b.DivisionID = d.DivisionID)" & _
"WHERE b.BranchID=" & BranchID
Me.cboDivision.Value = sqlStr
MsgBox ("You clicked me.")
End Sub
The commented out "Me.cboDivision.Value = 8" makes the cboDivision combobox show the division associated with DivisionID 8, which is effectively what I want; however, if I click the button with the current code, the combobox updates to: "SELECT d.DivisionIDFROM tblDivision d INNER JOIN tblBranch b ON b.DivisionID = d.DivisionID)WHERE b.BranchID=45"
(The 45 at the end is the correct BranchID for the record, so that part is working at the very least).
You need to change the RowSource property of the combobox to populate the correct Division information based on the EmployeeID selected.
You can do this on the control's Enter event:
Private Sub YourComboBoxName_Enter()
Dim sql_ As String
sql_ = "SELECT d.DivisionName " & _
"FROM tblDivision d INNER JOIN (tblBranch b INNER JOIN tblEmployee e ON b.BranchID = e.BranchID) ON d.DivisionID = b.DivisionID " & _
"WHERE e.EmployeeID=" & YourEmployeeIDField
Me.YourComboBoxName.RowSource = sql_
End Sub
The combobox control's RowSourceType must be set to Table/Query.
I figured out what I wanted to do... and it may have been that I didn't explain it properly. The code to do what I needed was as follows:
Private Sub Form_Current()
Me.cboDivision.Value = DLookup("DivisionID", "tblBranch", "BranchID=" & BranchID)
Me.cboMinistry.Value = DLookup("MinistryID", "tblDivision", "DivisionID=" & Me.cboDivision)
End Sub
So when I change the current record, it updates the unbound comboboxes based on the bound value of BranchID.
Thanks for your help, responders!
Good day.
I have an inventory application. When an item is moved into production a ticket is required to be printed with a customer name and the product name. I created the ticket as a report. I used the following query as the Record Source in the report and it works exactly as I want.
SELECT [PkgSize] & " " & [PkgUnit] AS Pkg, tblProducts.ProductID, tblProducts.ProductPrintName,
tblProducts.Grade, tblCustomers.CompanyName, tblOrderDetails.ODEPriority
FROM tblCustomers INNER JOIN (tblOrders INNER JOIN (tblProducts INNER JOIN tblOrderDetails
ON tblProducts.ProductID = tblOrderDetails.ODEProductFK)
ON tblOrders.ORDOrderID = tblOrderDetails.ODEOrderID)
ON tblCustomers.ID = tblOrders.ORDCustomerID
WHERE (((tblProducts.ProductID)=[Forms]![frmInventoryTransfers]![cboTransferProductID])
AND ((tblOrderDetails.ODEPriority)=1)
AND (([tblOrderDetails]![ODEQtyOrdered]-[tblOrderDetails]![ODEQtyProduced])>"0"));
The report is opened with the following:
DoCmd.OpenReport "rptProductPaperLabelTCTRlogo", acViewPreview
What I want to do is to move the query into my procedure because I need to change values of some items. For example, I will need to change the ODEPriority to a different number, such as 2 or 3 i.e. change it to a variable. This will trigger the ORDCustomerID to change but not the ProductID.
I have created a string from the query and tried
DoCmd.OpenReport "rptProductPaperLabelTCTRlogo", acViewPreview, , , , Qstring
but I get #Name? in all the text boxes. (I first removed the query from the record source in the report.)
I have tried to use a querydef but can't seem to get the syntax right.
Can someone help me with how to move the query into a procedure to make the report dynamic.
Thanks
The OpenArgs parameter is simply passed to the report. It isn't automatically used for anything, but available in the Report event procedures.
So in Report_Open(), you can do:
Me.RecordSource = Me.OpenArgs
and it should work.
Side note: in the last line, it should be >0 instead of >"0"
i have 2 tables : Salesagent and Client which are related by id, each sales agent have too many clients with the same id ,
i want to add combo box to display the salesagent, then another combo box that displays the clients of that salesagent
combosale is ok ..
comboclient , displays the 1'st field of client table(only one not all of them ) ,when choosing only 1'st salesagent
it displays nothing when i choose another salesagent even if it has clients related to it
:(
i used :
Me.combmoclient = DLookup("[cname]", "[client]", "[salesagent]= '" & Me.Combosale & "'")
Don't use Dlookup, it will just return the first value that matches your criteria, when really you need the whole set of clients for that sales agent. Instead you should use the AfterUpdate() event of the combosale field to do something like this:
Private Sub Combosale_AfterUpdate()
Me.comboclient.RowSource = "SELECT cname FROM client WHERE id = " & Me.Combosale.Column(1) & ";"
End Sub
In general, pure SQL queries are much faster than the Dlookup, Dsum, etc. functions. You will have a much more stable application if you stay away from them and write SQL code into your Access VBA.
this vba solved the problem :)
Private Sub Combosale_AfterUpdate()
Me.comboclient.RowSource = "SELECT cname FROM client WHERE id = " & Me.Combosale.Column(1) & ";"
End Sub
tooo many thanx for your help !!
Consider:
I have a form I need to display payment events for individual clients on. I do not want to display all columns in the payment table, I want user-friendly column names, and I want Access to display a popup form that displays information should the user click on a row of the form (a payment event).
Firstly, I am unsure whether Access 2002 and VBA will allow me to do this. Secondly, I am unsure how to make the individual payment events on the form clickable.
I assume I can do something like:
strSQL = "SELECT payment.payment_id, payment_amount AS Amount, payment_date AS Date" & _
"FROM contact_payment, payment " & _
"WHERE contact_payment.contact_id =" & forms([ContactForm].contact_id & _
"AND payment.payment_id = contact_payment.payment_id"
in order to get the data for the clickable form. Is this the correct way, or is there a better way to achieve this?
You could use the form's DblClick event (or Click event) to open a new form:
Private Sub Form_DblClick(Cancel As Integer)
DoCmd.OpenForm "frmMoreInfo", , , "ID = " & ID
End Sub
I have a database for a carpet company. I have a form which enables the user to make a quote, including choosing the customer, etc. There is a also subform dealing with the products and extras, with quantities and unit prices. To state whether the user requires fitting there is a checkbox. When ticked I would like fitting to be added in the subform as one of the products. Products are normally manually chosen using a dropdown.
Important properties are:
Form name: Orders
Subform name: Order Details Subform
Checkbox name: Fitting
Field name for products: Product ID
Subform linked to table: Order Details
Form linked to table: Orders
I'm assuming VBA is needed, or the macro builder.
Anyway thanks in advance!!
I think the easiest way is to use an append query.
If Me.Fitting Then
strSQL="INSERT INTO [Order Details] (ProductID,OtherTextField) Values ("
& Me.ProductID & ",'" & Me.OtherTextField & "')"
CurrentDB.Execute strSQL, dbFailOnError
Me.[Subform control name here].Form.Requery
End If
On the check box control, you are going to add an [Event Procedure] on the After Update event for the checkbox (see the properties window). This will stub out the VBA code, click on the ellipsis ("...") to get to the VBA code.
You can use Remou's code (after a fashion) to insert the new Product:
If Me.Fitting Then
strSQL="INSERT INTO [Order Details] (ProductID,OtherTextField) " & _
"Values (" & _
Me.ProductID & ",'" & Me.OtherTextField & "')"
CurrentDB.Execute strSQL, dbFailOnError
Me.[Subform control name here].Form.Requery
End If
'[code not tested]
However, you probably also want to check that the Product doesn't already exist in for the Order (does your business rules allow for multiple fittings to be scheduled), and you might also want to allow the Fitting product to be removed when it is unchecked - you could do that with an else condition on the if before the "end if":
if 'blah
'blah blah
else
strSQL="Delete [Order Details] " & _
"where ProductID = " & Me.ProductID & " " & _
"and OtherTextField = 'fitting' "
CurrentDB.Execute strSQL, dbFailOnError
Me.[Subform control name here].Form.Requery
end if
'[code not tested]
You will also have to hack your Products sub form so that if you delete the Fitting product from it, you update the check box (or so that you can't delete Fittings that way).
Then again maybe you don't want to use a check box, and just have the fitting as being another drop down option, as the other products are. You could always make sure it's auto-populated into [Order Details] whenever a new Order is created so it can't be forgotten. This would be more consistent with the rest of the product selection user interface.
This is the no code solution:
Get rid of the Fitting check box. Make fitting a product and add it like all the rest. If you want to know if an order requires a fitting (I'm guessing that's why you have the checkbox.), you can create a query to see if fitting is one of the products on your reports/invoices.