Display Multiple Values in Text Boxes based on a Combo Box Value - sql

I have one table - tblMAIN
I have 4 ID Fields - mainID, FatherID, MotherID and FullName
1 Form - frmMAIN
1 Combo Box - cboMAIN
2 Text Boxes - txtFATHER, txtMOTHER
I am trying to write a SQL statement in VBA that will select a record in the combo box cboMAIN and by doing that selection, two text boxes are populated.
Robert is selected in the cboMAIN, Robert has a MainID of 20
Robert mother is Ruth, she has a MainID of 30
Robert's father's MainID is 40
So in txtFather it will display record 40 / FullName and in txtMother it will display FullName for record MainID30.
I would like to add text fields and show Ruth's mother and Robert's father's father.
Here is an idea I have, but not sure what to do next.
Dim sqlME As String
Dim sqlFATHER As String
Dim db As Database
Dim rs As DAO.Recordset
sqlFATHER = "SELECT * FROM tblMAIN WHERE MainID = " & Forms![MAIN]![cboMAIN] & ";"
'AND NOT SURE WHAT I NEED TO DO HERE!
Set db = CurrentDb
Set rs = db.OpenRecordset(sqlFATHER)
Me.txtFather.Value = rs!FullName
Set rs = Nothing
Set db = Nothing

VBA setting value of UNBOUND textbox will show same value for every record.
This data is recursive in nature and Access SQL doesn't easily manipulate data of recursive nature. Other database platforms have utility to better deal with.
Build a self-join query object named qryAncestors:
SELECT tblMain.mainID, tblMain.FullName, tblMain_1.FullName AS Father,
tblMain_2.FullName AS Mother, tblMain_3.FullName AS PGFather,
tblMain_4.FullName AS PGMother, tblMain_5.FullName AS MGFather, tblMain_6.FullName AS MGMother
FROM tblMain AS tblMain_6
RIGHT JOIN (tblMain AS tblMain_5
RIGHT JOIN (tblMain AS tblMain_4
RIGHT JOIN (tblMain AS tblMain_3
RIGHT JOIN (tblMain AS tblMain_2
RIGHT JOIN (tblMain AS tblMain_1
RIGHT JOIN tblMain
ON tblMain_1.mainID = tblMain.FatherID)
ON tblMain_2.mainID = tblMain.MotherID)
ON tblMain_3.mainID = tblMain_1.FatherID)
ON tblMain_4.mainID = tblMain_1.MotherID)
ON tblMain_5.mainID = tblMain_2.FatherID)
ON tblMain_6.mainID = tblMain_2.MotherID;
Then options to use that query:
reference query as combobobox RowSource then textbox ControlSource references combobox columns by index
=[cboMain].Column(2)
textbox ControlSource uses DLookup() expression, such as:
=DLookUp("Father", "qryAncestors", "mainID=" & mainID)
textbox ControlSource calls VBA custom function to return a value, like:
=GetAncestor(mainID, "Father")
Function GetAncestor(intID As Integer, strAnc As String)
GetAncestor = DLookUp(strAnc, "qryAncestors", "mainID=" & intID)
End Function
If you want to go beyond grandparents to any level, approach would have to be quite different. Recursive procedure is tricky. A function to return FullName of ancestor could be like:
Function GetAncestor(intID As Integer, intGen As Integer, strParent As String)
Dim x As Integer
GetAncestor = intID
For x = 1 To intGen
GetAncestor = DLookup(strParent, "tblMain", "mainID=" & Nz(GetAncestor,0))
Next
GetAncestor = DLookup("FullName", "tblMain", "mainID=" & Nz(GetAncestor,0))
End Function
To get ancestor of specific generation, call function: GetAncestor(mainID, 1, "MotherID")

Related

How to update text box based on combo box value

Beginner on Using MS access 2016 and VBA. I am trying to show information on how many items have been reserved or is in the reserve table based on what the user selects as the tool.
The tool combo box(cmbo_Tool) selects a tool from Table A. I need to count the amount of times this tool appears in Table B and then display it in textBox A.
I have made a query involving both tables, but i'm unsure on how to apply it to the label.
Instead I have used the AfterUpdate event on cmbo_tool and using the DCount option.
Another way I thought about is taking the Tool Id (in this case, say 5) from Table A, and searching for it in a column table B, and counting.
'using Dcount'
Private Sub cmbo_Tool_AfterUpdate()
Me.Text1404 = DCount("cmbo_Tool", "tbl_Booking", "Tool")
End Sub
'Using Table id'
Private Sub cmbo_Tool_AfterUpdate()
Dim T_var as integer
Dim FinalOut as integer
T_var = Me.cmbo_Tool.Column(0) 'This gives 5'
'I need to make T_Var link to Table b and count'
Me.Text1404 = FinalOut
End Sub
Using Dcount method, it gives a number im unsure of. I'm not even sure if im using dcount correctly.
Using the table id method, Im unsure how to take the value 5 and count it in table B, then display in the textbox.
I guess it could be something like this:
Private Sub cmbo_Tool_AfterUpdate()
Me!Text1404.Value = DCount("*", "tbl_Booking", "Tool = " & cmbo_Tool & "")
' If Tool is text, then use quotes:
' Me!Text1404.Value = DCount("*", "tbl_Booking", "Tool = '" & cmbo_Tool & "'")
End Sub
And do rename your controls to something meaningful.

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.)

Prepopulating Access Form

I have a form that we use for data entry, to make it easier I would like to have some of the fields prepopulate based on the EmployeeID field, for example once I put in my employee id then the EmployeeName field would be Auto populate with John Doe, and Gender would be Male and EEOC would be White, etc. Is this at all possible to do? It would be based of the data in another table title EmpData.
In the AfterUpdate event of EmployeeID, you could put something like (untested code, so it needs to be tweaked a bit):
Dim db as DAO.Database
Dim rec as DAO.Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("Select * from EmpData where EmployeeID = " & Me.EmployeeID & "")
Me.EmployeeName = rec("EmployeeName")
Me.Gender = rec("Gender")
Me.EEOC = rec("EEOC")
etc...
Set rec = Nothing
Set db = Nothing
If EmployeeID is a Text field, it will need to be surrounded by single quotes in the "Set rec" line. Like this:
Set rec = db.OpenRecordset("Select * from EmpData where EmployeeID = '" & Me.EmployeeID & "'")
If you create a query that joins the two tables, then Access will do it all for you automatically. Then you should use that query as the DataSource for the form.
SELECT MyDataTable.*, EmpData.*
FROM MyDataTable LEFT JOIN EmpData
ON MyDataTable.EmployeeID = EmpData.EmployeeID;
Doing this, you might want to lock the columns coming from EmpData from being possible to edit.
In your form, you show the fields from the MyDataTable and the relevant fields from EmpData. Any fields in MyDataTable that should be filled in from EmpData should not be shown to the user.
I.e. you show the EmployeeName from EmpData and not from MyTableData.
In the AfterUpdate event on EmployeeID you copy the data from EmpData to MyTableData
Me.RecordSet!MyTableData.EmployeeName = Me.RecordSet!EmpData.EmployeeName

Populate listbox with alias values using SQL select statment

I have two columns in MS SQL table (ID, and Name) that I want to use to populate a list box with. I would like to show the Name values (as alias?) in the list box, however when the user selects the item I want the ID value to be returned not the Name value. My code below just adds the values into the list box from the Name column.
Me.listName.Items.Clear()
Dim strName As String = "select SetName from " & tb
Dim con As String = sConnectionString
Dim com As New SqlCommand(strServiceType, New SqlConnection(con))
com.Connection.Open()
Dim dr As SqlDataReader
Dim ColumnValue As String = Nothing
dr = com.ExecuteReader
While dr.Read
ColumnValue = (dr.GetValue(0)).ToString
listName.Items.Add(ColumnValue)
listName.Sorted = True
End While
com.Connection.Close()
I'm not sure how to apply the logic above to get the associated ID value besides running another select statement on the list box SelectedIndexChanged event.
Thank you
If I'm not mistaken, you simply need to edit your sql to pull both ID and Name, then edit your addition of an item to your list box to add a new list item instead.
i.e.
listName.Items.Add(New ListItem("TEXT","VALUE"))

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().