How do I search forms in Access using values from another table that is being referenced? - forms

The management staff in my department has been asked to record any and all errors committed by our team. I created a database to store them and a simple form for the management team to use to record each error. Several fields are referencing other tables such as Staff, issue category, root cause, etc...
We need to be able to search the forms for specific records to either update or review, and I have found the best way for us to search is by filtering the forms based on the individual who committed the error. Here is the code that I am using for the search button:
Private Sub SearchRecord_Click()
Dim Search As String
Search = InputBox("Please enter who committed the error", "Name", ErrorMadeBy)
If Search = "" Then Exit Sub
Me.Filter = "ErrorMadeBy = """" & Search & """
Me.FilterOn = True
End Sub
The filter works great, but instead of filling out the name, you have to use the ID number in the Staff table when filling out the Input Box. I'd like to be able to input the name (or part of the name) instead of having to have everyone memorize the ID numbers from the staff table.

What I do in these cases?
Fire up the query builder - left join in those extra tables (with the text parts in place of the id).
So be it a part number, quote number for a project etc? Just left join in those tables in the query builder and save that query.
Now, your search box and code can be somthing like:
dim rst as DAO.RecordSet
strSQL = "Select * from MyCoolQuery where PartName like '" & txtPartName & "*'"
set rst = currentdb.OpenRecordSet(strSQL)
if rst.EOF = false then
me.RecordSet.FindFirst "PartID = " & rst!PartID
end if
In fact, you can even often left join in those extra tables right into the current form, and even use ctrl-f to search if the said text boxes are place on the given form. However, I tend to separate out the search process from the actual form. So I might build a search form, say like this:
So in above, they can search say by a Hotel name, or project name or whatever. Becuase the one query has the text parts, then they can be searched. But I put the query results into a grid and each row of course has the PK ID, and thus a search could result in 10 matches, they are now free to click on any row - and i jump to the form to display the one records.
eg: the row click button does this:
docmd.OpenForm "frmTourBooking",,,"ID = " & me!ID
So, this makes for a great work flow. Users search, see, pick and then jump to the form with the one record, and then close and return back to search form - and often it has the several "hits" from that search that you want to work on anyway.

Related

MSAccess dynamic search form with multiple searchable fields and NULL values

I have a form in my MSAccess application that searches the master database across 4 fields. You can fill in as little into 1 field or as much into all 4 fields or anywhere in between that you desire.
The database fields to be searched are:
rmanbr - Integer
custNbr - Integer
customername - Text
invcmnbr - Text (as it will store either invoice numbers (######) or credit memo numbers (CM-####)
The form has 4 fields in which to sort by respective of the above:
SrchRMANbr
SrchCustNbr
SrchCoName
SrchInvCMNbr
I have a query that selects all of the data to be displayed. The 4 fields to be filtered are filled with Like "*" & [forms]![RMA Search]![FieldName] & "*" into the Criteria section of the Query Builder for that specific query
The rmanbr and customername fields in the database will never be NULL, they're not allowed to be. But, the invcmnbr and custnbr can be and frequently are NULL with no values.
So, my search form is the 4 Srch fields listed above where users can enter in the stuff they want to filter by. There is a listbox that is designed to start filtering the results based on the "On Change" of the text boxes that the user will use to filter results. The user then selects the record and goes on his merry way.
However, the ListBox is filtering out all NULL Values from the two fields that can be NULL, whether or not the corresponding Srch box is blank, so the rows with NULL either in the custnbr or invcmnbr fields is not showing up in the listbox.
I've tried stuffing a Is Null into the "Or" Criteria of the query I'm using to populate the listbox. I tried it in the second line of the Query Builder Criteria section "Is Null" and this showed all the rows if they had NULL values even if I entered in a number into SrchRMANbr field. Ideally entering in an RMANbr would filter by RMANbr whether or not NULL values existed, since this is a unique value (there can only be 1 of any RMANbr in the master table). If I put after the Like "*" & [forms]![RMA Search]![FieldName] & "*" in the criteria (on the same line) Or Is Null it would get me closer, but any search into the SrchCustNbr or SrchInvCMNbr fields would produce the filtered result as well as all the NULL values for that field.
So, in short, I require a way to:
1) Show all of the values, NULL or not, in the listbox before a user starts to enter data in any field.
2) Filter away the NULL values when a user starts to enter data into the SrchCustNbr or SrchInvCMNbr field.
3) Keep the NULL Values up but filter by RMA Nbr correctly when the user starts to enter an number into the SrchRMANbr (as this is the master record, this is as specific as it can get)
I hope I'm conveying the issue correctly. Let me know if you need any additional information to assist me in solving my issue.
Using the solution posted here: MS Access: Ignoring query criteria if blank and pointed out by Andre
I've simply added Or ([forms]![RMA Search]![SrchCustNbr] Is Null) after the original Like "*" & [forms]![RMA Search]![FieldName] & "*" in both the CustNbr and InvCMNbr fields and this has worked.
As you are finding out, putting forms! expression in queries can get really messy real fast.
Even worse, is now that the query is now "married" and attached to that ONE form. Often, I have a nice query that I could use MANY times for different reports, and often even that same query could be used for reports...but then someone comes along and puts in a expression that means the query is ONLY good when that form is opened.
Worse, is very hard to control things like having 5 combo boxes, but the user only selects restrictions in 3 of the combo boxes...and wants the other 2 to be ignore.
I could probably write another 10 or pages as to why putting forms expressions in queries is bad (besides...it makes the queries real ugly, and hard to read. and, the sql then is not standard anymore (it will not work with server based systems either).
So, the solution is to simply to take the values from the form, and build your own where clause in code. That way, you simply design the reports (or forms), and attached them to the query, BUT NO FORMS! conditions are placed in the query.
To "send" the conditions to the report (or form), you simply use the "where" clause. This is exactly why ms-access has this feature…and it solves a zillion problems…and will reduce your development costs by a substantial amount.
Take a look at the following screen shots to see what I mean:
http://www.kallal.ca/ridesrpt/ridesrpt.html
The code to make those above screens work and launch the report with the selected restrictions when you hit the "print" button is easy:
dim strWhere as string
' select sales rep combo
if isnull(cboSalesRep) = false then
strWhere = "SalesRep = " & cboSalesRep & ""
end if
' select what City for the report
if isnull(cboCity) = false then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "City = " & cobCity & ""
end if
Note how the 2nd combo test is setup. You can add as "many" more conditions you want. Lets say we have a check box to only include Special Customers. We can add to our very nice prompt screen a check box to
[x] Show Only Special customers
The code we add would be:
if chkSpeicalOnly = True then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "SpecialCust = true"
end if
For sure, each combo and control we add to the nice report screen takes a bit of code, but no more messy then the query builder..and this way, each query is nice and clean, and free of a bunch of HIGHLY un-maintainable forms! expressions.
Further, it means you can re-use the same query for different reports, and have no worries about some form that is supposed to be open. So, a tiny bit more code eliminates the messy query problem.. For me, this is very worth while trade.

How can a free tagging field be created in a Microsoft access form?

Setup
Access 2007
This is a simplified scenario. It is nearly identical to my actual use case just easier to explain. I have a many to many relationship between movies and genres the table structure is below.
Table: movies
id autonumber
name text
Table: genres
id autonumber
name text
Table: movie_genres
movie_id number
genre_id number
I would like a form that allows me to list all genre's for a given movie. But also allows me to create new genre's without opening a separate form. Similar to the way free tagging works in a cms website like Drupal or Wordpress.
My Attempt 1
I have successfully created a form that allows me to display all tags using a sub-form pointing to the movie_genres table and a combo box pointing to the genre table. This form setup also allows me to select existing values as new genres. It does not however allow me to create new genre's.
In this form if I type a value not present I get the warning "The text you entered isn't an item in the list."
If I attempt to change the combo box to "Limit To List: No" I get the warning: "The first visible column... isn't equal to the bound column." If I make the first visible column the bound column the combo box simply displays numbers and not names, which is silly because the information is there either way.
The form for this simplified case looks like:
My attempt 2
I can also create a subform that points to both the movie_genres and genres tables with a regular textbox pointing to genre name. This allows me to create new values but it does not let me select from existing values. No pic of this one.
Creating a combo box on this form act identical to the second form.
The question again
How can I create a movie form item that supports both creation and listing existing genres?
You can easily add new values to the list of genres using 'NotInList' event. Leave Limit To List: Yes and use code similar to code below:
Private Sub GenreName_NotInList(NewData As String, Response As Integer)
' Prompt user to verify they wish to add new value.
If MsgBox("Genre '" & NewData & "' is not in list. Add it?", _
vbOKCancel) = vbOK Then
' Set Response argument to indicate that data
' is being added.
Response = acDataErrAdded
' Add string in NewData argument to row source.
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO Genres (GenreName) SELECT '" & NewData & "';"
DoCmd.SetWarnings True
Else
' If user chooses Cancel, suppress error message
' and undo changes.
Response = acDataErrContinue
Me.GenreName.Undo
End If
End Sub

How to add a multiple values field to an MS Access form

I have a database which records and tracks the training records for each employee within our group of companies.
One of the forms on the database is 'add training record' and currently this is done per person ID, adding the course id, date, certificate, etc. What I would love to do is be able to add multiple person IDs, as a number of people can attend the same course/ date, so I have to add the course details in many times, which is very time consuming and annoying.
You're going to need extensive VBA behind the scenes to do this, as well as a couple of controls to make your life easier (multi-select combo or list boxes). You could do it in a text box if you want, using the semi-colon between User IDs.
Since the text box is easier, let's look at that. What you would do is have something like this behind the Submit button:
Dim db as Database
Dim rec as Recordset
Dim str as String
Set db = CurrentDB
Set rec = db.OpenRecordSet("SELECT * FROM tblMyTable")
'Throw the User IDs into an array
Dim var As Variant
Dim i As Long
str = me.txtUserIDs
var = Split(str, ";")
'For every User ID, add a new record to the database
For i = 0 To UBound(var)
rec.AddNew
rec("UserID") = var(i)
rec("CourseID") = Me.txtCourseID
rec("CourseDate") = Me.txtCourseDate
'ETC... adding fields as needed
rec.Update
Next i
This is completely off-the-cuff and (of course) requires you to change the appropriate variable names, but it should give you a solid outline for how to solve the problem.

Sub-Forms in MS Acess

Background: I have two tables. One has a list of clients and some basic client attributes (tblClient). The second has a list of products. Each client can have multiple products so I have a one to many relationship here where the primary key (client name) is the foreign key in the product table.
What I'm looking to do: I'm looking to create two forms. The main form will have a snapshot of clients and have a small nested table to provide a summary of all the products. This I have completed successfully. I have also made a second form in which all the details associated with products can be put in (matching the products data table). What I want to do is to have a button on the main client form that when clicked opens up the product form ONLY to the products currently used by the client. If there are no product, it opens to a blank form with some pre-filled information (i.e. client name). For example, if I'm reviewing customer John Doe and he currently has product A, B, and C, I want to click a button to have the product details specific to John Doe pull up. If he has no products, I'd like Access to open up a new entry product form for me with John Doe's name filled in already to avoid confusion.
I'm very new to access, any help would be very much appreciated.
thanks,
Z
I'm assuming your 2nd form is linked to a table? If so, just filter the recordset when you open it.
For instance, the OnClick event of your button will look at the current ClientID and open the form based on that ClientID.
Dim stDocName As String
Dim stOpenArg As String
'Make stDocName the name of the form you're going to open
stDocName = "frmAssignProject"
'Make stOpenArg your variable to filter on
stOpenArg = Me.ClientID
DoCmd.OpenForm stDocName, , , , , , stOpenArg
Then, in the OnLoad event of your second form, filter based on your OpenArg:
private sub form_load()
Dim rs as DAO.Recordset
Me.RecordSource = "Select * From tblProducts Where ClientID = " & OpenArgs & ""
Set rs = Me.RecordsetClone
'This is where it determines if it should pull in the data from the previous form
If rs.RecordCount > 0 Then
else
Me.ClientID = Forms!frmClients.ClientID
Me.ClientName = Forms!frmClients.ClientName
etc...
end if
end sub
The above is entirely "air code", it will probably need some tweaking but the concept is sound.

Access 2010 Form Button Problems

I am currently at a loss for what to do in my current project. I am creating a form that will pull up a customer’s data. It is possible the customer could have more than record, and I have three different distinct fields to help narrow to that exact customer. We have an ID field which would be primary key, their SSN which only relates to them, and their account # which also only relates to them. I am curious if there is a way for the form to not be populated when I start it, and either be able to type in a text box one of these 3 and have them linked to a query that will search for that record and fill the form with the data, or have it pull up a parameter box(can do, but cant get the data to populate in form view) I am not having any luck with using the command buttons, either they don’t work the way I want them to, or the data gets pulled up in a datasheet, instead of my form.
I can manually filter on the ID numbers to find the record, but I’d rather make this user friendly for future users.
Also the form currently houses 95 fields of data, but they fit very comfortably in the form.
Access 2010
You can certainly have the form not populated. Create your three textboxes and a "go" button.
The code for the go button would be something like:
If Not IsNull(Me.txtID) Then
sWhere = sWhere & " Or ID=" & Me.txtID
End If
If Not IsNull(Me.txtSSN) Then
''If SSN is text, you need quotes
sWhere = sWhere & " Or SSN='" & Me.txtSSN & "'"
End If
If Not IsNull(Me.txtAccountNo) Then
sWhere = sWhere & " Or AccountNo=" & Me.txtAccountNo
End If
sWhere = "WHERE 1=1 " & sWhere
sSQL = "SELECT Each, Field, Name FROM TableName " & sWhere
Me.RecordSource = sSQL
The above is typed, not tested, and is only one approach. You could also use comboboxes built with the wizard to select a customer on your form, you could have a previous form where you fill in a customer and open your form from that, you could just filter your form based on what is filled in and so on.
As far as I know, there are rules about storing SSNs, so you will need to be careful.