Access 2010 set variable to single field of a table - sql

I feel like this should be easy, but I haven't been able to come up with a clear answer for this after searching off and on all day.
I have a users table that has email addresses in it.
I have a combo box that references this table.
All I want to do, is set the email address field of the selected user to a string, so I can then do things with that.
just trying to get a string back from a sql query like :
"SELECT emailAddress FROM tblUsers WHERE id = " & Me.cmbUser.Value & ""
Can someone point me in the right direction here?

You can use Combo Box to return email address after user select user from list.
Assume your user tblUsershas User and Email fields
Set your combo box property:
1.Row Source = SELECT User, Email FROM tblusers
2.Column Count = 2
3.Bound Column = 0 (0 is the first column and 1 is the second column which is email)
4.Column width = x";0" (x is your combox box width)
You can get email address from me.combobox.column(1). Both me.combobox.value and me.comboxbox.column(0) is selected User

If you actually want to execute the query, you have multiple options:
You can use DLookup:
TL;DR:
DLookup("Column", "Table", "Col=Value") will execute SELECT Column FROM Table WHERE Col=Value and return the first row.
For the query from your question, you need to use DLookup like this:
Dim mail As String
mail = Nz(DLookup("emailAddress", "tblUsers", "id = " & Me.cmbUser.Value))
You can load your SQL query with a Recordset.
This makes more sense than DLookup if you need more user data from the table than just the email adress.
Dim mail As String
Dim phone As String
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset("SELECT emailAddress, phoneNumber FROM tblUsers WHERE id = " & Me.cmbUser.Value)
If Not RS.EOF Then
mail = Nz(RS("emailAddress"))
phone = Nz(RS("phoneNumber"))
End If
RS.Close
Set RS = Nothing
(in order for this to work, your Access database needs a reference to any version of the Microsoft DAO Object Library...this should already be the case in most newer Access versions)
Note the usage of Nz in both examples - this is necessary if the mail adress can be NULL. Without Nz, the code would crash because of setting a string variable to NULL.

Related

Return Query Value Using VBA function in Access

I'm currently working on a project and I've been having trouble trying to get a function that is able to return the value of a query, which I do need in order to display it on a textbox.
The current code is like this:
Public Function rubrieknaamSQL() As String
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT T_Train.trainPlate, T_Category.categoryName FROM T_Category INNER JOIN T_Train ON T_Category.id = T_Train.category_id WHERE (((T_Train.trainPlate)=[Forms]![F_Comboio]![Combo_Search_Comboio]));"
Set rst = CurrentDb.OpenRecordset(strSQL)
rubrieknaamSQL = rst!categoryName
rst.Close
End Function
I should say that the code is copied from other publisher and I do not own its rights. However, it still won't work when I try to run it and the error displayed goes like this:
Run-Time Error 3061 : Too few parameters. Expected 1
and it happens in Set rst command.
For a SELECT query to set a recordset object, concatenate variable:
" ... WHERE T_Train.trainPlate=" & [Forms]![F_Comboio]![Combo_Search_Comboio]
If trainPlate is a text field, need apostrophe delimiters (date/time field needs # delimiter):
" ... WHERE T_Train.trainPlate='" & [Forms]![F_Comboio]![Combo_Search_Comboio] & "'"
For more info about parameters in Access SQL constructed in VBA, review How do I use parameters in VBA in the different contexts in Microsoft Access?
There are ways to pull this single value without VBA.
make combobox RowSource an SQL that joins tables and textbox simply references combobox column by its index - index is 0 based so if categoryName field is in third column, its index is 2: =[Combo_Search_Comboio].Column(2)
include T_Category in form RecordSource and bind textbox to categoryName - set as Locked Yes and TabStop No
build a query object that joins tables without filter criteria and use DLookup() expression in textbox
=DLookup("categoryName", "queryname", "trainPlate='" & [Combo_Search_Comboio] & "'")

How to use a query as a control source for a textbox on a form?

I have a form myForm that's binded to a table tbl in my database. (I don't know if binded is the correct term, but It shows records from tbl on by one.)
In the form:
contact: textbox, binded to tbl.contact.
dailyCount: textbox, should show the amount of contacts entered today.
In the table:
contact
dateEntry
The query I want to use is:
SELECT count(*)
FROM tbl
WHERE contact = currentContact
AND month(dateEntry) = month(now)
AND day(dateEntry) = day(now)
AND ear (dateEntry) = year(now)
Where currentContact is the contact that is showing on the form now.
I tried putting the query in the dailyCount dataSource, but It's not working. When I click on the three dots on datasource to access the wizard, I get a window to build functions and not queries.
How do I get the currentContact showing on the form into the query?
There are multiple ways to do this. For a couple of reasons, I don't like to hardcode queries in the datasource of a specific field, and I mostly build/assign all my queries in VBA. So here's how I would do it.
In the load event of you form :
Private Sub Form_Load()
Dim SQL As String
Dim RST As Recordset
dim theCOntact as string ' Change accordingly
theCOntact = Me.currentContact ' I don't know how your fields are named, so change accordingly
SQL = "SELECT count(*) AS cnt FROM tbl WHERE contact = " & theContact & "' AND month(dateEntry) = month(now) AND day(dateEntry) = day(now) AND Year(dateEntry) = year(now)"
Set RST = CurrentDb.OpenRecordset(RST)
If RST.BOF Then
dailyCount.Value = RST!cnt
Else
dailyCount.Value = 0
End If
End Sub
Assuming your contact field is string, if its a number remove the quotes in the SQL
Probably the simplest approach is to use the DLookup function with an associated query:
Create and save a named query with your SQL code or equivalent. Let's call it "qryDailyCount". Note that it should be modified to look something like this (in particular, name the column and change the record reference to a GROUP BY for now):
SELECT count(*) as DailyCount
FROM tbl
WHERE month(dateEntry) = month(now)
AND day(dateEntry) = day(now)
AND year (dateEntry) = year(now)
GROUP BY contact
In the dailyCount textbox, set the Control Source to something like this:
=DLookUp("Count";"qryDailyCount";"contact = [contact]")
(Note that if the contact field is a text field, you must enclose it with single quotes.)

SQL Query to set date activated for single row

I have a registration form for users to submit and then when they click the activation link in their email, it activates their account (AccountActivated = true). This works fine, however, I also have a column called DateActivated set to smallinttime as the data type. I'm trying to find an SQL query that records the date that the account was activated.
This is the query I use to activate the account, so I'm guessing I need something similar to this:
Dim sqlQuery As String = "UPDATE RegisteredUsers SET AccountActivated=1 WHERE
UserId=#UserId AND UMaryEmail=#txtEmailAddress"
So maybe something like this?
Dim sqlQuery2 As String = "UPDATE RegisteredUsers SET DateActivated=?? WHERE
UserId=#UserId AND UMaryEmail=#txtEmailAddress"
If someone could weigh in on this and let me know what the command is to set current date to the field, I'd greatly appreciate it.
You can do it all in the same query:
Dim sqlQuery As String = "UPDATE RegisteredUsers SET AccountActivated=1,DateActivated=GetDate() WHERE UserId=#UserId AND UMaryEmail=#txtEmailAddress"

GUI using VBA in access. Recordset from query

Making GUI in Access with VBA (first time i saw it in this semester and it looks unusual for me). I got table Authors where i got columns author_id, last_name, first_name and table Books with columns author_id, book_name.
I got button on Form which on click should ask user to input author last name and then search and show all books of this author.
So I trying to find author id from Authors table and then from Books table show all books where author.author_id is equal to books.author_id.
I was thinking that i need to create temp query which contained author_id value and after that create record set with this query using SQLquery like "SELECT [Books].[book_name] AS [Bookname] FROM [Books] WHERE [Books].[author_id] = [test].[ID]" But i stucked here - I trying to just check if this thing working but it says there is an error 3061
Private Sub authorlist_Click()
Dim dbs As Database, authorsRS, booksRS As Recordset, queryStr, idbynameQuery, srchASurStr, strOutput, srId As String, qdf As QueryDef
Set dbs = CurrentDb()
srchASurStr = InputBox("Input author surname, please", , , 100, 100)
strQuery = "SELECT [Authors].[author_id] AS [ID] FROM [Authors] WHERE [Authors].[last_name] = " & srchASurStr & ""
Set authorsRS = dbs.OpenRecordset(strQuery, dbOpenSnapshot)
With dbs
Set qdf = .CreateQueryDef("test", strQuery)
DoCmd.OpenQuery "test"
.QueryDefs.Delete "test"
End With
End Sub
So could you help me please to understan what's wrong? And is there maybe more simple way to show all books of some author (maybe without using SQL querys)?
String values in an SQL statement need to be surrounded with single-quotes (') or double-quotes ("):
SELECT author_id FROM authors WHERE last_name = "Smith"
If written without the quotes:
SELECT author_id FROM authors WHERE last_name = Smith
Smith will be understood to be a field name and not a string value. So your code should look something like this:
'Chr returns a string from a character code. 34 is the code for "
strQuery = "SELECT author_id FROM authors WHERE last_name = " & Chr(34) & srchASurStr & Chr(34)
In VBA, you can escape double-quotes with a string by doubling them:
strQuery = "SELECT author_id FROM authors WHERE last_name = """ & srchASurStr & """"
SQL injection: Keep in mind that if the user inputs a string with " in it, there will probably be an error, as the resulting SQL statement has invalid syntax:
SELECT author_id FROM authors WHERE last_name = "Smi"th"
The right way to avoid this problem is to use parameters.
Some notes:
You can reference a form control within a query: [Forms]![FormName]![ControlName]. Thus, you can create a saved query that filters based on a form textbox, instead of using an inputbox.
Consider using a combobox to have the user select from a list, instead of having the user type free text. The combobox can have multiple columns, with the value of the combobox being the first column (author_id) and the displayed value being another expression (last_name or last_name & " " & first_name). If you set the ColumnWidths property to 0 (for the first column), the next column will be displayed
If you prefer to use a textbox, consider using the LIKE operator in your query, to display all authors whose last_name contains the user string:
SELECT author_id FROM authors WHERE last_name LIKE "%sm%"
will return Smith, Smythe, and Asmodeus.
I suggest you set up a form and subform. The form can contain author details and the subform can contain books by that author, you can further add a textbox that the user can fill in with part of the author name. You can then apply a filter to the main form to show all the authors with that name.
Me.Filter = "Author Like '*" & Me.Search & "*'"
Me.FilterOn = True
There are a number of variations on this, the user could select names from a combo or listbox. The form could be a continuous form with a filter / search in the header and so on.

MS access SELECT INTO in vba

I'm having some issues with some functionality of my application. There is a particular instance where I have an instance of a 'pending class' on a form for an administrator to review. The form is populated with students associated with this pending class. After their grades are finished, I have a button at the footer that will delete this class from my 'pending' table and add the grades to all of the students. This works.
However, I want to essentially copy this pending class, which just has the class name, date, and teacher to a completed class table before it's deleted from pending. Since no data about this class other than the primary key(class number) persists throughout this form, I can't populate the other fields(class name, date) of the row into my completed class table.
I am trying a "SELECT INTO" operation in VBA to get these values. It's going like this:
dim cname as String
dim classdate as Date
dim pid as integer
dim teacher as String
dim qry as String
pid = [Forms]![frmClasses]![txtID]
qry = "Select className INTO cname FROM tblPending WHERE tblPending.id = " & " ' " & pid & " ' " & ";"
db.execute qry
debug.print qry
debug.print cname
From here, I do the same operations for each other variable, build my INSERT query, and execute it. The problem is-- my select into's are not working. Debug.print shows that the local variables were never initialized from the SELECT INTO statement. Any thoughts?
First, having all classes in one table and just setting a "NotPending" or "Completed" column would be better.
Having two identical tables for classes and moving values from one into the other to indicate status changes is bad database design.
If you really need to do this by using two tables and copying rows, then you need an INSERT INTO query (and not SELECT INTO), as already mentioned by Remou in the comments, because SELECT INTO creates a new table (or overwrites an existing one with the same name, if already there).
The syntax for INSERT INTO looks like this:
INSERT INTO CompletedClassTable (ClassName, Teacher)
SELECT ClassName, Teacher FROM tblPending WHERE id = 123
And finally, you asked this in a comment:
So SELECT INTO is completely different in Access than Oracle? In Oracle and PL/SQL, you can select a row into a variable OR a table. In Access can you not select into a variable?
To load a row into a variable, you need to use a Recordset.
Example code to load your query into a Recordset and output the ClassName field:
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset("SELECT * FROM tblPending WHERE id = 123")
If Not RS.EOF Then
Debug.Print RS("classname")
End If
RS.Close
Set RS = Nothing
Seems you want to retrieve a text value, className, from tblPending where tblPending.id matches the value found in your text box, txtID, and store that text value in a string variable named cname.
If that interpretation is correct, you needn't bother with a query and recordset. Just use the DLookup Function to retrieve the value, similar to this untested code sample.
Dim cname As String
Dim pid As Integer
Dim strCriteria As String
pid = [Forms]![frmClasses]![txtID]
strCriteria = "id = " & pid
cname = Nz(DLookup("className", "tblPending", strCriteria), vbNullString)
Debug.Print "cname: '" & cname & "'"
Notes:
I assumed the data type of the id field in tblPending is numeric. If it is actually text data type, change strCriteria like this:
strCriteria = "id = '" & pid & "'"
DLookup() returns Null if no match found. Since we are assigning the function's return value to a string variable, I used Nz() to convert Null to an empty string. Alternatively, you could declare cname As Variant (so that it can accept a Null value) and get rid of Nz().