Passing values in Access Forms - ms-access

I have two tables and a form in a Microsoft Access Database. Lets the first table tblCUSTOMERS, and the second table tblINVOICES. tblCUSTOMERS contains fields called CustomerID (primary key), FirstName, and LastName. tblINVOICES contains fields called InvoiceID (primary key), CustomerID (foreign key), and Amount. The form is called frmInvoices and contains textboxes for the fields in tblINVOICES.
What I what to do is create functionality that allows me to search through my customers table, select a customer record from that table, and then return the CustomerID of that record to frmInvoices. Ideally the searching would be in a format like a data grid that allows searching by FirstName, LastName, and CustomerID.
Specifically can you advise me of the simplest way to:
1. Insert a form (lets call this new form frmCUSTOMERS) with something like a datagrid control to show customer records.
2. Update the datagrid on frmCUSTOMERS to display only records matching a query of tblCUSTOMER (such as only customers where firstname starts with 'B')
3. Pass the CustomerID from frmCUSTOMERS to frmINVOICES.
Many thanks,
Brett

You can pass a value as an opening argument to a form when you open it.
DoCmd.OpenForm "frmFormName", , , , , ,"B"
Or you can pass in a criteria statement:
DoCmd.OpenForm "frmFormName", , , "FirstName LIKE 'B*'"
If you go the first route you would do something like this:
Private Sub Form_Load()
Me.Filter = "FirstName LIKE '" & Nz(Me.OpenArgs, "") & "*'"
'or
Me.Subform1.Form.Filter = "FirstName LIKE '" & Nz(Me.OpenArgs, "") & "*'"
End Sub
To hand a value such as CustomerID back from the search form, there are numerous options. You could put the value in a global variable. Or you could have the search form give the value back to the calling form by using a Public Variable or Public Function on the calling form.
Arguably, a more correct and cleaner way of doing all this would be to design a Class that handles opening the search form and passing of the inbound and outbound values. Classes do take more knowledge and skill to write and it would probably be overkill for what you are trying to do. A class is certainly not required to make this work. It would only be a little cleaner. In reality, you would use many of the same techniques I listed above if you did write a class for this.

Related

Combine multiple queries using same fields and table

I have a Form for order information. It will populate the fields order date, product info, Customer ID... after selecting the Order number from a combo box on the form(Source for all this information is OrderInfo table). I have a separate table for CustomerInfo which has Customer ID, name, address... There are four Customer ID fields on the form. I want to automatically display the name, address... based on Customer ID field.
I did a query for the first customer to look for the customer ID value on the form and find the name & address. But I do not want to write four queries for the four customer ID fields. Is there any way to combine all four into one or is there a way better to do this process?
As June7 commented, eight lines of DLookup code might be the quickest solution.
I don't personally like to use DLookup, and I'm sure their is a more elegant solution than what I'm suggesting, but below is what I tried (and I assumed unbound textboxes).
Create a private subroutine on the form:
Private Sub PopulateNameAddress(CustomerID As Long, CustomerNameTextBox As TextBox, CustomerAddressTextBox As TextBox)
'CustomerNameTextBox is a variable for the names of the text boxes containing the customer's name
'CustomerAddressTextBox is a variable for the names of the text boxes containing the customer's address
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb()
Set rs = db.OpenRecordset("SELECT CustomerName, CustomerAddress FROM CustomerInfo WHERE CustomerID=" & CustomerID)
CustomerNameTextBox = rs!CustomerName
CustomerAddressTextBox = rs!CustomerAddress
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Sub
Then after whatever populates the CustomerID (as shown in the image you provided), call this subroutine, and give it the CustomerID, the name of textbox for the customer's name, and the name of the textbox for the customer's address. Could be better running a loop, but since you only have four records to fill, this might be the most straight forward:
'Send the PopulateNameAddress subroutine the name of each text box containing the CustomerID, CustomerName, and CustomerAddress
PopulateNameAddress Customer1IDTextBox, Customer1NameTextBox, Customer1AddressTextBox
PopulateNameAddress Customer2IDTextBox, Customer2NameTextBox, Customer2AddressTextBox
PopulateNameAddress Customer3IDTextBox, Customer3NameTextBox, Customer3AddressTextBox
PopulateNameAddress Customer4IDTextBox, Customer4NameTextBox, Customer4AddressTextBox
Unfortunately, I'm not sure how you have your database setup, so this may not necessarily work. Let me know.

Customize auto-complete functionality on Microsoft Access datasheet

I have a main form tied to a User record, with a subform tied to a number of Client objects the user "owns." So, there is a one-to-many relationship between User and Client.
As the subform exists, the user can add, remove, and edit entries in the Clients subform. When a user adds an entry to the subform datasheet, there is an autocomplete functionality that kicks in the user types part of a Client name that matches any names in the Client database, thus saving the user a few keystrokes and ensuring that the user enters a name that exactly matches one in the Client database.
One thing to note with the Clients table is that in addition to each Client having a unique numerical ID, each Client has a full company name (Test Agency, Inc.), a colloquial name (Test Agency) and an abbreviated name (TA).
I am trying to edit the subform so that the autocomplete functionality will match against any of the three fields listed above (full name, colloquial name, and abbreviated name). Right now, the autocomplete only works against the full name, as that is the field linked to the subform. I would like the user to be able to type in a part of a string, the subform to try and match it to any of the three fields (full name, colloquial name, abbreviated name) and return a list of potential matches to any of the three fields. When the user selects the correct potential match for the Client they are trying to search for, then then full company name would be entered into the datsheet. Basically, these additional fields just make it easier for the user to find the Client they are looking for (imagine typing in AMD instead of Advanced Micro Devices, Inc.)
My first question--is this possible to do with a simple datasheet? I've looked into using lookup fields and multi-value lookup fields, but I'm not sure this is the right method. Or will I need to build myself a custom control that does this matching on multiple fields?
Made a query like this
SELECT *
FROM Company
WHERE fullName LIKE '*' & pCompany & '*'
OR Colloquial LIKE '*' & pCompany & '*'
OR Abbr LIKE '*' & pCompany & '*'
and on my form I did this
Private Sub cboCompany_KeyUp(KeyCode As Integer, Shift As Integer)
ClearCombo cboCompany
Dim sql As String
Dim rs As DAO.Recordset
Dim companySearch As DAO.QueryDef
Set companySearch = CurrentDb.QueryDefs("CompanySearch")
companySearch.Parameters("pCompany") = cboCompany.Text
Set rs = companySearch.OpenRecordset
Do While Not rs.EOF
cboCompany.AddItem rs("ID") & ";" & rs("FullName") & ";" & rs("Colloquial") & ";" & rs("Abbr")
rs.MoveNext
Loop
End Sub
Private Sub ClearCombo(cbo)
For i = cbo.ListCount - 1 To 0 Step -1
cbo.RemoveItem i
Next i
End Sub
It's not super fast at all but it works. I think what would make it faster is not cuing off the KeyUp event and instead on a timer once users start typing in that field. Then turn the timer off when they stop typing or focus leaves the combobox.
So you are already able to search with partial string - probably by means of a query with a like condition.
The next step is very easy. Do the search for every field, combine them by UNION, and remove duplicates by means of a SELECT DISTINCT.
Hope this succinct answer will suffice?

MS Access 2007 Open Separate Form to Specific Record Using VBA

I have two forms, one which is a data entry form, the other is a summary form which lists all the records in the database. On the summary form there is a listbox which lists all the records. I want the user to be able to select a record from the listbox and using a command button, open the second form to the specific record. I've gotten this work with using a specific field, in one case "Name", using the code below:
DoCmd.OpenForm "frmEditAddPerson", acNormal, ,"[PersonName]='" & Me.listPeople.Value & "'"
but when I realized two people could have the same name, I decided it made sense to use the PersonID which is the primary key and its datatype is "AutoNumber". I can't seem to get this to work:
DoCmd.OpenForm "frmEditAddPerson", acNormal, "[PersonName] = " & SelectPersonID
Note, I am getting SelectedPersonID by pulling it from ListBox from a hidden column. I confirmed that I am infact getting correct the number value for the AutoNumber field by displaying it in a MessageBox while trying to debug.
For the WHERE argument of this method/command, I know you are supposed to contain String values in quotes, Integers without, and dates with "#" like in a SQL statement. I've tried delcaring SelectedPersonID as a string and as an integer and I still cannot get the above to work. I've even tried the below just to be sure:
DoCmd.OpenForm "frmEditAddPerson", acNormal, "[PersonName] = " & CInt(SelectPersonID)
Each time I get "Type mismatch". Is the AutoNumber field special in the sense that it cannot be used for something like this or does it need to be handled in a special way?
If PersonID is the autonumber primary key, reference it in the fourth OpenForm argument (WhereCondition). Your OpenForm examples still include PersonName instead of PersonID.
Also, in your last two examples, PersonID was referenced in the third OpenForm argument (FilterName).
DoCmd.OpenForm "frmEditAddPerson", acNormal, , "[PersonID] = " & SelectPersonID
It can be easier to keep track of which option is which by including the option names.
DoCmd.OpenForm FormName:="frmEditAddPerson", View:=acNormal, _
WhereCondition:="[PersonID] = " & SelectPersonID

master detail subforms in ms access 2010

I have a customers table in an MS Access 2010 database. I want to create a form with two subforms which together allow the users to select a customer and see more detail about the customer.
The customers table looks like:
CustomerID
FullName
Address
City
StateProvince
Other fields
The mainForm I created in design view by dragging CustomerListForm and CustomerDetailForm onto MainForm.
CustomerListForm is on left side and lets users filter customers from long list
Contains the following controls:
txtFilter textbox with embedded macro where = [LastName] Like [Forms]![CustomerListForm]![txtFilter] & "*"
FullName textbox and hidden CustomerID textbox which are bound to CustomersTable
CustomerDeatilForm located on right, with contents changing based on selection from CustomerListForm
If no customer selected from CustomerListForm, show default message
Else:
Show FullName, address, city, and stateprovince of customer selected from CustomerListForm
txtFullName set =[CustomersTable]![FullName], and so on for other fields
When I run my CustomerListForm separately, it does successfully allow a user to filter customer records by typing in a name. But that filtering ability goes away when I embed CustomerListForm in mainForm. Also, my filtered results in CustomerListForm do not contain any sort of links, which means that CustomerDetailForm does not seem to be able to identify which customer it should be outputting data about.
Can anyone show me how to set this up? I think if I get this much running, I will be able to fill in the blanks from other research that I am doing.
EDIT:
I see that the FullName textbox on CustomerListForm has an OnClick method. FullName is not editable in CustomerListForm. CustomerID is a hidden field alongside each record in CustomerListForm. I also see that there are multiple hyperlink settings in the format tab of the property sheet for the FullName textbox. Is there some way that the OnClick method of the FullName textbox can be used to send the CustomerID to CustomerDetailForm? Perhaps in a hyperlink?
The subforms are presumably linked to the parent form by CustomerID?
Remove this value from the LinkMasterID, LinkChildID properties of the subform control (in the parent form - as opposed to on the form properties of the subform itself)
Remove the macro, and create an AfterUpdate event for txtFilter, which finds the relevant data and displays it in the CustomerListForm; In addition to whatever other code is in this procedure, put
Dim CustID as Long: CustID = [get customerID from wherever it is]
... [your other code]
Me.Parent.LockCustomer CustID
In the outer form, add this in vba:
Public Sub LockCustomer(CustID as Long)
CustomerDetailForm.Form.RecordSource = _
"SELECT * FROM Customer WHERE CustomerID = " & CustID
End Sub
If you've customer details of any sort on the main form in addition to the subforms, and you want to show the details of the selected customer in the listform on both the main form and the detail subform, instead of setting CustomerDetailForm.Form.RecordSource, set Me.RecordSource & ensure that the LinkMasterID, LinkChildID properties of the Detail subform control are set to CustomerID.

Populating a form from a table

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