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 !!
Related
Good afternoon,
I have a form used to create a "toolbox talk". A toolbox talk is not always applicable to every employee but might be limited to a specific department, gender, or competency (or any combination of the three). I have created a subform which using unbound text boxes allows me to filter my list of employees based on the toolbox talk criteria - great!. See screenshot below:
However what I cant work out now is how I can then store the filtered results (list of employees) as recipients against the toolbox talk record.
I know that I could include a control to select employee ID/Names line by line as per the filtered results, however I was hoping that a quicker option could be created.
Can someone please suggest a possible solution?
Thank you in advance.
If you want to 'batch' create records, one approach is an INSERT SELECT action SQL that uses the same criteria selected by the form controls. If your code applies this criteria to the form Filter property, that property can be referenced to incorporate filter criteria for SQL. I prefer to use CurrentDb.Execute because then don't have to deal with RunSQL popup warnings.
Private Sub Command16_Click()
Dim mySql As String
mySql = "INSERT INTO tblEmployeeToolboxTalk (EmployeeID, ToolboxTalkID) " & _
"SELECT EmployeeID," & Me.ToolboxTalkID & " AS TTID FROM tblEmployees WHERE " & Me.Filter
CurrentDb.Execute mySql
End Sub
If you need guidance on conditionally building filter criteria in VBA, review http://allenbrowne.com/ser-62.html
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!
I am developing an Access database (using Office 2016) and have several tab controls which I want to display the number of records in the subform/subreport.
After a lot of searching etc I have it working for the subforms using a function which I call in the main forms current event (but in a seperate function so I can also call via a macro when I change the main forms record with a combo box, as it wasn't updating otherwise). The code I am using is:
Function ClientTotals()
Dim i As Integer
i = Form_sbfrm_ClientContacts.Recordset.RecordCount
Form_frm_Clients.ClientTabs.Pages("Contacts").Caption = "Contacts (" & i & ")"
End Function
This works perfectly for me and my tab name becomes "Contacts (No. of records)" but I can't get the syntax right to change this to work for a report, is it possible?
I have tried:
Function ClientTotals()
Dim i As Integer
i = Form_sbfrm_ClientContacts.Recordset.RecordCount
Form_frm_Clients.ClientTabs.Pages("Contacts").Caption = "Contacts (" & i & ")"
Dim j As Integer
j = Report_rpt_CurrentProjects.Recordset.RecordCount ' this line is highlighted with the debugger
Form_frm_Clients.ClientTabs.Pages("Current Projects").Caption = "Current Projects (" & j & ")"
End Function
As well as:
Dim j As Integer
j = rpt_CurrentProjects.Report.Recordset.RecordCount ' this line is highlighted with the debugger
Form_frm_Clients.ClientTabs.Pages("Current Projects").Caption = "Current Projects (" & j & ")"
and various others.
Another question I have is why is the syntax for the form "Form_sbfrm" etc and not using a "!". If I change to "!" it bugs out.
Thanks for your help, KAL
Thanks Delecron,
I think I will stick with the tabs for now as they are giving me exactly what I want, but remember what you have said for when I make future improvements if its a better way of doing it.
EDIT
Using what you have said I changed my VBA to a DCOUNT method:
Dim j As Integer
j = DCount("*", "qry_CurrentProjects", "FK_Project_Client_ID = Forms!Navigation!Navigationsubform.form!Client_ID")
Form_frm_Clients.ClientTabs.Pages("Current Projects").Caption = "Current Projects (" & j & ")"
This means my report tabs are now also working just how I wanted
I was getting in a muddle with the criteria/filter, hense the edit.
If Recordset is an old method I am assuming it would be best to replace my other code with the Dcount method?
Thanks again, KAL
Further EDIT
After doing this I could see that everytime the form was changed there was a slight flicker. Not bad but you could see there was a lot of calculation going on. Therefore I have changed my method to the following, and posted here for anyone looking at this in the future.
In the form footer a textbox with COUNT([Project_ID])
In my function
Dim j As Integer
j = Form_frm_Clients!rpt_CurrentProjects.Report!txt_CurrentProjectsCount.Value
Form_frm_Clients.ClientTabs.Pages("Current Projects").Caption = "Current Projects (" & j & ")"
Now I can see it is working quicker with no flicker.
Recordset if you need to return complex data, if you need one value, a total or a sum, Domain functions are the way to go. Don't overdue them though, having too many on a form or a report can start to bog down usability.
Glad I can help.
Recordset.Recordcount is a legacy feature that only worked in ADP files (Access front end's to a SQL database). Those are no longer supported.
If the report is based on 1 client only and there is no grouping then you can do this:
Click on the detail section and in Events create an event for On Paint. In there set
(Name of Page).Caption = DCount("*", "NAME OF QUERY/TABLE") or
(Name of Page).Caption = DCount("*", "NAME OF QUERY/TABLE", "Filter Expression") (Filter expression optional).
If the report is grouped where it will show a different page per client or date range or any other grouping this will not work since the Caption field is not data bound. You would have to add logic to the Dcount statement above to field by the current filter condition.
For example, say you have a database of 200 clients and you're running one big report on all of them, each page will get its own tab control per client, the syntax would be
(Name of Page).Caption = DCount("*", "ClientContacts, "ClientID = " & ClientID)
The better way to do it especially if you are grouping is get rid of the tab control and use databound controls. You could create a box around the information that would be in the tab page and put a textbox where the tab would go. Create a group header for however you are grouping the data. Create another invisible textbox in the group header and set the controlsource = Count([fieldname]) where fieldname is whatever you are grouping the data by (the inside brackets count).
Then in the textbox you created to simulate the tab, set the controlsource to the name of the invisible textbox.
Let me know if this helps.
I'm not sure if I used the right title for this question but I'll try to ask it. Be patient with me I'm new to Microsoft Access.
I'm making an MS-Access database for employee reviews at my company and I made the form and all of the data from the form is going to two seperate table. The tables are linked through the same rating ID for each time the form is filled.
I have a seperate form that when you select the name of the stakeholder reviewed it fills a listbox with the name of the leader who reviewed them, the date, and the rating ID. I used VB to make it to where if you select the rating ID then it will open the form in which the data was put into using DoCmd.OpenForm "FRM".
Now for the question I hope that was all understandable. I would like for the form that is brought up from selecting the rating ID to be repopulated with all of the information that was entered into the table for that specific ID. What do I need to do to do this?
Another option is to base the form on a table or query (its RecordSource) and use the Where clause argument when opening the form:
DoCmd.OpenForm "frmName", acNormal, , "[SomeID]=" & frmYours!ctlControlName
This has the advantage that the form can be opened separately, as it will just show all the data from its RecordSource, not producing an unwanted parameter request.
If SomeID is text then its value needs to be quoted with apostrophes:
DoCmd.OpenForm "frmName", acNormal, , "[SomeID]='" & frmYours!ctlControlName & "'"
There are various possible solutions to this.
The first one (and simplest) is to write a query in the RowSource property of your form with the appropriate data source, and include a filter field in that query that corresponds to the Id you are filtering:
select a.*
from [your table] as a
where a.[id] = forms!frmYourForm![theControlName]
That way, every time you open the form, it will show the appropriate data.
The second solution (a little more sophisticated) is to edit the RowSource property on run-time. In the code that opens the form, you can do something like this:
strSQL = "select a.* from [your table] as a where a.Id = " & theControlName.Value
DoCmd.OpenForm "theDetailedForm"
form_theDetailedForm.RowSource = strSQL
form_theDetailedForm.Requery
Hope this helps you
I have, what I think, is a pretty basic Access file, with a report. The report is based off a query. The query is:
SELECT * FROM dbo_NewPatient WHERE id=[Patient to view];
This works good, and prompts me for an id, I enter Id, and the results are the patient I want to see. Now I want to build a report that is based on this query, but I want to create a label on the report, that populates data from the results, so I've got this code:
Private Sub Report_Open(Cancel As Integer)
Label2.Caption = "Patient Name is " & PatientName & " his time in hospital is ... "
End Sub
I want that "PatientName" variable to be the data returned from the query. I've tried PatientName.Value, and PatientName.Text, but each time, i get an error message:
'The expression you entered has a field, control, or property name that Microsoft Office Access can't find'.
I'm assuming it doesn't know what "PatientName" is, perhaps because when I double click to open the report, I'm not yet prompted for the [Patient to view] variable, so the code doesn't yet know what PatientName is. How can I correct this, or is there a better way to go about this?
Thanks!
2 answers.
First, in your code:
Label2.Caption = "Patient Name is " & PatientName & " his time in hospital is ... "
Move it to the Private Sub Report_Load() procedure. Access will then know the value of PatientName.
Or, you can assign it in the report designer. However, you can't do this with labels, but you can with textboxes. Just lock the textbox control and it act just like a label. Put it in the Control Source property, preface it with an =, and put brackets around the fieldname. So...
="Patient Name is " & [PatientName] & " his time in hospital is ... "
It sounds like rather than doing this in VBA code, you just want to bind a column from your query (PatientName) to a label in your report. Don't do that in VBA code, do that in the report designer.
Your code could be tweaked to use Me to access the patient name field
Private Sub Report_Open(Cancel As Integer)
Label2.Caption = "Patient Name is " & Me!PatientName & " his time in hospital is ... "
End Sub
Edit:
It was pointed out that you can't do this on the open event. There is another event that you can hit that will work if you have more than one record to work with. You can use that group header paint event like this. (I even tested it...)
Private Sub GroupHeader0_Paint()
Label2.Caption = "Patient Name is " & Me!PatientName & " his time in hospital is ... "
End Sub