MS Access Forms: Control Default Values and DLookup - forms

I've tried searching on here for my answer but have had no luck. I've tried many things to get this to work but haven't been successful so I thought I would post my question. I may repeat myself several times but I'm trying to be as specific/detailed as I can.
I have a form which has an append query to transfer all fields on the form into a table. On this form, I have an invisible control (textbox) which pulls the users Windows login ID and uses that as its default value. I have another field (textbox) for the user's full name.
I have ran a query to pull employee data from my tables to have the employee ID (same as their Window's login ID, first name, and last name. I have also ran an expression to concatenate the two name fields into one to show their full name.
What I've been trying to do is have it so that when someone opens up the form, their full name is already pre-loaded. As I stated above, this is pre-loaded based on a comparison of their Window's login ID with their employee ID that we have on record as they're the same. It's essentially Excel's version of vlookup() that I'm trying to do. I've tried dlookup() but was unsuccessful.
Does anyone know how to make the default value of the employee name control on the form to be determined by employee ID control which has its default value based on the user's Window login ID?
Example: Let's say that I have an employee called Fred Flintstone. In the database there's a table with fields for his first name and last name. There's also a field for his employee ID which is A111111.
When opening up the form, there's an invisible textbox control which has its default value derived from the Windows login ID that the employee used to sign onto the computer with. This Windows login ID happens to be A111111 which is the same as the employee's employee ID.
A query was created that has fields for the employee ID, First Name, Last Name, and an expression to concatenate the two name fields. So the first row would be: | A111111 | Fred | Flintstone | Fred Flintstone |. I don't know how to make tables on here yet so bear with me.
Going back to the form, there's a field for Employee Name. How would I get it to show Fred Flintstone as the default value upon opening the form?
Note: The employee name field will eventually be locked so that it cannot be changed by the employee. I don't know if that would have any impact but I thought that I would mention it.

In the onload event of your form (really rough code, will require some tweaking..):
dim db as dao.database
Dim rs as dao.recordset
Dim username as string
dim SQL as string
username = Environ("USERNAME") 'There are better ways to get username, but this is just a quick example.
SQL = "SELECT * FROM Your_Query WHERE username = '" & username & "'"
set db = currentdb
set rs = db.openrecordset(SQL,dbopensnapshot)
if rs.recordcount > 0
rs.movefirst
me.UserNameField = rs!username
else
msg "User Not Found"
End If
set rs = nothing
set db = nothing

Related

MS Access 2016: how to enter a concatenated field into a table from a form

TblEmployees has Fname, Lname and EmployeeName fields. EmployeeName should be Fname + Lname (i.e. John Doe). I want to enter Fname and Lname in a form FrmEmployeeData, and update TblEmployees with Fname, Lname and EmployeeName.
If FrmEmployeeData has as Data Source TblEmployees, how do I get the concatenated [Fname]&" "&[Lname] into the EmployeeName field of the table?
I also tried changing the DataSource of FrmEmployeeData to a query QryConcatenateFname&Lname where EmployeeName:[Fname]&" "&[Lname]. This gave the correct "John Doe" in the query result but I could not get it to update the TblEmployees.
What am I doing wrong? Thx.
It looks like you are learning access as this question is really too simple for stack overflow. Instead consult an Access book at your library or start finding Youtube vidoes and tutorials on the internet. Having said that here is a start:
Access gives you the ability to add a calculated field to a table in the design tab by treating it as a DataType. You can also add lookups and some data validation. Never do any of that!! Use forms to enter and search the data, and use reports to print the data.
A simple yet quite incomplete explanation is that as your database expands into multiple related tables you will find that entering the data directly into the tables is error prone for the database designer yet alone the clients. Because any observation will be distributed across multiple tables it becomes easier and easier to forget one or make a mistake as you add more and more tables.
Access is designed for quickly making simple forms for the tables in your database. If your relationships are already entered using the Relationships tool Access even generates starter forms that handle 1 to many relationships. Just click on a table and under home then forms group on the ribbon choose either form or form wizard and start playing with your new forms properties:
if you don't see the properties (hit f4 in most cases). Seriously every control has properties you can play with. In particular look at the control sources and for the form itself (hit the top left corner to select the form) check out the default view property.
I happened to include EmployeeName as a string in tblEmployees but there was no need other than having access put the EmployeeName textbox on the form. I would have to go back and delete EmployeeName from the table which is about the same effort as adding the textbox to the form myself. Below I show how to set the control source for EmployeeName to the usual FullName calculation
=[Fname] & " " & [Lname]
Access forms by default have both data entry and search capabilities. Play with the record selector highlighted at the bottom of the beautified form below. You can edit any record you see and the changes will appear in the table. If you go past the last record you can add a new record.

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

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.

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

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.

Password Protect a form in MS Access 2003

I am trying to create a login for my database and I don't want to use the Microsoft way of doing so. I want to have the users login with a username and password then have that information verified in the "tblUsers" table.
UserID LoginID Level LevelID
jpurk jack23 admin 3
krimes kitty editor 2
lwalms low34 reader 1
I got as far as verifying the "UserID" and "LoginID" using dlookup
Nz(DLookup("[LoginID]", "tblUsers", "[UserID] = '" & Me.txtUserID & "'"), "")
=Me.txtPassword
The problem I have now is that I want certain items on the menu unavailable to users without the proper Level; If they are only an "editor" or a "reader", then I don't want them to have access to the "administrative" button where I have placed all admin forms.
After I use dLookup to verify the username and password, how do I now find out their "Level" and assign rights to different menu items? Thank you.
Assuming your DLookup has found an existing LoginID value, you can use another to retrieve that user's LevelID. Then enable/disable the administrative command button based on their LevelID.
I'll suggest something like this in Form Load:
Dim lngLevelID As Long
lngLevelID = DLookup("[LevelID]", "tblUsers", "[LoginID] = " & Me.txtLoginID)
Me.cmdAdmin.Enabled = (lngLevelID = 3)
Notes: That assumes you've previously loaded the user's LoginID number into a text box named txtLoginID. txtLoginID could be hidden if you don't want the users to see it. Or you can grab the LoginID value by some other method.
If you have one-to-one matches between Level and LevelID, you shouldn't need to store both values in tblUsers. You can create a UserLevels lookup table to hold both, and store just the LevelID in tblUsers as a foreign key to the appropriate row in UserLevels.
Finally, the strategy you're using can work, but the security is shaky. As "guidance" to users willing to follow the rules, it's OK. But it can be easily circumvented by even unsophisticated users. Look for a different approach if your security needs are stringent.