I have a table tblConsentQuestion with questions
intID nvcText bitActive
17 Question1 True
18 Question2 True
19 Question3 False
and a table tblConsentData with the questions for every customer
intID intCustomerID bitConsent intIDQuestion
14 1 False 19
15 1 True 18
WHERE tblConsentQuestion.intID = tblConsentData.intIDQuestion
I would like to retrieve in a VB.net dataset:
all tblConsentData for a specific customer i.e, two records with intID = 14 and 15
all active (bitActive = true) records in tblConsentQuestion WHERE
tblConsentData.intIDQuestion <> tblConsentQuestion.intID, in this case only intID = 17 record (in addition to the two records)
The output should be:
Question3 False
Question2 True
Question1 Null
I tried something like:
str = "Select tblConsentQuestion.intID, bitConsent, nvcText" & fungGetLangId() & " AS nvcqText " _
& " From tblConsentData " _
& " Left OUTER JOIN tblConsentQuestion " _
& " On tblConsentData.intIDQuestion = tblConsentQuestion.intID " _
& " where tblConsentData.intCustomerID = " & intCustomerID & " " _
& " UNION ALL " _
& " Select tblConsentQuestion.intID, -1, nvcText" & fungGetLangId() & " " _
& " From tblConsentQuestion " _
& " Left OUTER JOIN tblConsentData " _
& " On tblConsentData.intIDQuestion = tblConsentQuestion.intID " _
& " WHERE(tblConsentQuestion.bitActive = 'True') "
and I received all active records in tblConsentQuestion, whereas I should not receive records with intID = 18, which exist in tblConsentData.
What is the data type of bitActive? Is it a text field with two possible strings: 'True' and 'False'? Or is it an Access Yes/No field?
If the latter, then your SQL shouldn't check for the string values, but rather for the True / False constants (let's say that `fungGetLangId:
WHERE tblConsentQuestion.bitActive = True
Or, better yet, you can check the yes/no field directly:
WHERE tblConsentQuestion.bitActive
Related
Hi I have a datagrid control(not datagridview control) placed in a windows form(Vb) it have 10 columns. I am trying to input decimal value in one of the column but it is resetting its value. For ex:
I have 31 in a cell and trying to edit it to 20.5 as soon as i change the cell it resets back to 31. If i input any integer value like 21 it accepts the value.
_da = New OleDbDataAdapter("SELECT EMPDETAILPERSONAL.EMPCODE, EMPDETAILPERSONAL.EMPNAME, EMPDETAILPERSONAL.EMPDEPT, EMPDETAILPERSONAL.EMPDOB, 0 AS AGE, " & _
" EMPDETAILPERSONAL.EMPDOJ, EMPDETAILPERSONAL.EMPPANNP, " & Date.DaysInMonth(selYear, selMonth) & " AS NOD, " & Date.DaysInMonth(selYear, selMonth) & " AS LD, CSDEPT.CSDEPTNAME, EMPDETAILPERSONAL.EMPDESG, " & _
" EMPDETAILPERSONAL.EMPSALACC, EMPDETAILPERSONAL.EMPPFACC, EMPDETAILPERSONAL.EMPPPFACC, EMPDETAILPAYROLL.EMPBASIC, EMPDETAILPAYROLL.EMPGPA, CDbl(0) AS CONS, " & _
" EMPDETAILPAYROLL.EMPDA, EMPDETAILPAYROLL.EMPHRA, EMPDETAILPAYROLL.EMPTA, EMPDETAILPAYROLL.EMPMISCADD, EMPDETAILPAYROLL.EMPGRSAL, " & _
" EMPDETAILPAYROLL.EMPPFMEM, EMPDETAILPAYROLL.EMPITAX, EMPDETAILPAYROLL.EMPMISCDED, EMPDETAILPAYROLL.EMPNETSAL, " & _
" IIf(EMPLOAN.LOANAMTINST Is Null,0,EMPLOAN.LOANAMTINST) AS LOAN, CSDESIGNATION.CSDESGNAME, EMPDETAILPAYROLL.EMPINCDATE, EMPDETAILPAYROLL.EMPINCAPP, " & _
" EMPDETAILPAYROLL.EMPBASIC AS o_basic, EMPDETAILPAYROLL.EMPGPA AS o_gpa, EMPDETAILPAYROLL.EMPDA AS o_da, " & _
" EMPDETAILPAYROLL.EMPHRA AS o_hra, EMPDETAILPAYROLL.EMPTA AS o_ta, EMPDETAILPAYROLL.EMPPFMEM AS o_pf, EMPDETAILPAYROLL.EMPPFEMPL AS o_pf_e, " & _
" EMPDETAILPAYROLL.EMPPPFEMPL AS o_ppf_e, EMPDETAILPAYROLL.EMPPFEMPL, EMPDETAILPAYROLL.EMPPPFEMPL, " & _
" EMPDETAILPAYROLL.EMPMISCADD AS o_add, EMPDETAILPAYROLL.EMPITAX AS o_tax, EMPDETAILPAYROLL.EMPMISCDED AS o_less, " & _
" IIf(EMPLOAN.LOANAMTINST Is Null,0,EMPLOAN.LOANAMTINST) AS o_loan, CDbl(0) AS EMPCONTRI,EMPDETAILPAYROLL.EMPCCA AS CCA,EMPDETAILPAYROLL.EMPMEDALL AS MEDALL,EMPDETAILPAYROLL.EMPOTHERALL AS OTHERALL,EMPDETAILPAYROLL.EMPESI AS ESI,EMPDETAILPAYROLL.EMPGPF AS GPF,EMPDETAILPAYROLL.EMPPAYSCALE AS PAYSCALE " & _
" FROM EMPLOAN RIGHT JOIN (((EMPDETAILPERSONAL INNER JOIN CSDEPT ON EMPDETAILPERSONAL.EMPDEPT = CSDEPT.CSDEPTID) " & _
" INNER JOIN EMPDETAILPAYROLL ON (EMPDETAILPERSONAL.EMPDESG = EMPDETAILPAYROLL.EMPDESG) AND (EMPDETAILPERSONAL.EMPDEPT = EMPDETAILPAYROLL.EMPDEPT) " & _
" AND (EMPDETAILPERSONAL.EMPCODE = EMPDETAILPAYROLL.EMPCODE)) INNER JOIN CSDESIGNATION ON EMPDETAILPERSONAL.EMPDESG = CSDESIGNATION.CSDESGID) " & _
" ON EMPLOAN.EMPCODE = EMPDETAILPERSONAL.EMPCODE " & _
" WHERE EMPDETAILPERSONAL.EMPDOL Is Null ORDER BY IIF(EMPDETAILPERSONAL.EMPDESG = 1, '10','20') + EMPDETAILPERSONAL.EMPCODE", _con)
_da.Fill(_dtEmp)
dgEmp.DataSource = _dtEmp
There is nothing written in cellchanged event. Even value is resetting before triggering cellchanged event. Please help. Thanks
You should make sure that the corresponding column of your datatable is not of an integer type. If the given column is some kind of integer this condition is then reflected in the datagrid column and when you enter values with decimals they are casted back to integer.
Hi all below you see a screenshot of my database:
But now I want to be able to make a table that calculates every players last 5 games. As I'm totaly new to access db I really have no clue how to do this.
Can you guys help me a hand with this one?
When I use the 2nd snippet in the answer below I get these:
Below are SQL routes according to your data. To use in MS Access simply create a new query under Create Tab on Ribbon and place the below SQL in the SQL view of a new created query. You may need to adjust query according to your actual table names and/or fields.
SAME GAMES FOR ALL PLAYERS
Assuming every player shares the same last five games, you could run an aggregate query across all players, using a subquery in INNER JOIN clause to calculate last five game dates. Do note: subquery, LastFiveDates can be saved as its own query and used directly in INNER JOIN.
SELECT [LookUp to Players],
Sum(GamesWon) As SumOfGamesWon, Sum(GamesLost) As SumOfGamesLost,
Sum(OwnOdds) As SumOfOwnOdds, Sum(OppOdds) As SumOfOppOdds,
Sum(GamesPlayed) As SumOfGamesPlayed
FROM GamesTable
INNER JOIN
(
SELECT DISTINCT TOP 5 [Date]
FROM GamesTable
ORDER BY [Date] DESC
) As LastFiveDates
ON GamesTable.[Date] = LastFiveDates.[Date]
GROUP BY [LookUp to Players];
DIFFERING GAMES FOR EACH PLAYER
SIMPLE SELECT APPROACH
Now, if players differ in their last five games, you have to join on different queries or union queries. Again, the below uses a subquery in an inner join but you can save that LastFiveGames as its own stored query and join in INNER JOIN line.
SELECT GamesTable.[LookUp to Players],
Sum(GamesWon) As SumOfGamesWon, Sum(GamesLost) As SumOfGamesLost,
Sum(OwnOdds) As SumOfOwnOdds, Sum(OppOdds) As SumOfOppOdds,
Sum(GamesPlayed) As SumOfGamesPlayed
FROM GamesTable
INNER JOIN
(
SELECT [Lookup to Players], [Date],
(SELECT Count(*)
FROM GamesTable t2
WHERE GamesTable.[Date] <= t2.[Date]
AND GamesTable.[Lookup to Players] = t2.[Lookup to Players]) AS GameOrder
FROM GamesTable
) As LastFiveDates
ON GamesTable.[Date] = LastFiveDates.[Date]
AND GamesTable.[Lookup to Players] = LastFiveDates.[Lookup to Players]
WHERE LastFiveDates.GameOrder <= 5
GROUP BY GamesTable.[LookUp to Players];
DIFFERING GAMES FOR EACH PLAYER
VBA CREATE TABLE APPROACH
Due to performance issues of Access running the query as a stored query, VBA can re-create the GamesStats iteratively looping through all distinct players using the very first query condition for player.
Public Function GameTableStats()
Dim db As Database
Dim tbldef As TableDef, rst As Recordset
Dim strSQL As String, i As Integer
Set db = CurrentDb
Set rst = db.OpenRecordset("SELECT DISTINCT PlayerName FROM GamesTable", dbOpenDynaset)
For Each tbldef In db.TableDefs
If tbldef.Name = "GamesStats" Then
db.Execute "DROP TABLE [GamesStats]", dbFailOnError
End If
Next tbldef
rst.MoveLast
rst.MoveFirst
i = 1
Do While Not rst.EOF
If i = 1 Then
' FIRST PLAYER (MAKE-TABLE QUERY) '
strSQL = "SELECT GamesTable.[PlayerName]," _
& " Sum(GamesWon) As SumOfGamesWon, Sum(GamesLost) As SumOfGamesLost," _
& " Sum(OwnOdds) As SumOfOwnOdds, Sum(OppOdds) As SumOfOppOdds," _
& " Sum(GamePlayed) As SumOfGamePlayed" _
& " INTO GamesStats" _
& " FROM GamesTable" _
& " INNER JOIN" _
& " (" _
& " SELECT DISTINCT TOP 5 [Date], [PlayerName]" _
& " FROM GamesTable" _
& " WHERE [PlayerName]=""" & rst!PlayerName & """" _
& " ORDER BY [Date] DESC" _
& " ) As LastFiveDates" _
& " ON GamesTable.[Date] = LastFiveDates.[Date]" _
& " WHERE GamesTable.[PlayerName]= """ & rst!PlayerName & """" _
& " GROUP BY GamesTable.[PlayerName];"
Else
' ALL OTHER PLAYERS (INSERT APPEND QUERIES) '
strSQL = "INSERT INTO GamesStats ([PlayerName], [SumOfGamesWon], [SumOfGamesLost]," _
& " [SumOfOwnOdds], [SumOfOppOdds], [SumOfGamePlayed])" _
& " SELECT GamesTable.[PlayerName], " _
& " Sum(GamesWon) As SumOfGamesWon, Sum(GamesLost) As SumOfGamesLost, " _
& " Sum(OwnOdds) As SumOfOwnOdds, Sum(OppOdds) As SumOfOppOdds, " _
& " Sum(GamePlayed) As SumOfGamePlayed " _
& " FROM GamesTable " _
& " INNER JOIN " _
& " ( " _
& " SELECT DISTINCT TOP 5 [Date], [PlayerName] " _
& " FROM GamesTable " _
& " WHERE [PlayerName]=""" & rst!PlayerName & """" _
& " ORDER BY [Date] DESC" _
& " ) As LastFiveDates " _
& " ON GamesTable.[Date] = LastFiveDates.[Date]" _
& " WHERE GamesTable.[PlayerName]= """ & rst!PlayerName & """" _
& " GROUP BY GamesTable.[PlayerName];"
End If
db.Execute strSQL, dbFailOnError
i = i + 1
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set db = Nothing
MsgBox "Successfully created GamesStats table!", vbInformation
End Function
Good day. I'm a little stumped about what is happening in my code. I have a userform which collects txtQntyRecd and cboSupplySource. I calculate the lookupValue. And it works just fine. It successfully places the txtQntyRecd in the correct tblWarehouseLocations.WQuantity location. The code is:
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = '" & Me.txtQntyRecd & "'" & _
"WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError
What I want to do is add the next quantity to the same location. I get weird results if I change the SET statement to the following:
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + '" & Me.txtQntyRecd & "'"
If I put 200 in the first statement, I get 200 in my WQuantity field. When I change to the second statement and I try to add 1 to the 200 I get a result of 211. If I add 1 again, the result is 223. Add 1 again, the result is 236.
Could someone explain what is happening and why the results aren't 201, 202 and 203? In the future I will need to subtract quantities from WQuantity as well.
Thanks
You're adding quotes around an integer and appending it as a string. Change it to:
".....
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & val(Me!txtQntyRecd) & "....
...."
I've changed the . to a ! as I think it's still a nice distinction between objects properties and controls, and used the val function as it converts the string number value to the integer value.
This is your query in full:
' When I use values from controls, I like to store them in vars
Dim quantityReceived As integer
quantityReceived = val(Me!txtQntyRecd)
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
I solved the problem. I created a SELECT query to get the present amount in WQuantity. Now quantityReceived = Me!txtQntyRecd + the present amount. With SET tblWarehouseLocations.WQuantity = " & quantityReceived it works fine. However, if just seems so cumbersome.
' lookupValue gives the index into the tblWarehouseLocations where WQuantity resides
Dim lookupValue As Integer
lookupValue = DLookup("[WLocation_ID]", "[tblWarehouseLocations]", "[Location_Name] = '" & Me.cboWLocation & "'")
'Define SQL Query
strSQL = "select tblWarehouseLocations.WQuantity FROM tblWarehouseLocations WHERE (((tblWarehouseLocations.WLocation_ID)= " & lookupValue & "))"
Set rs = db.OpenRecordset(strSQL)
If IsNull(rs!WQuantity) Then
dbvalue = 0
Else
dbvalue = rs!WQuantity
End If
Dim quantityReceived As Integer
quantityReceived = Val(Me!txtQntyRecd) + dbvalue
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError
I have a vehicle database and would like to show "related" vehicles when a user clicks to view a vehicle. For instance, the user views a '2013 Chevy Tahoe' that is listed by dealership 'ABC Dealers'.
I need to create a SQL statement to grab 4 vehicles that are similar to the vehicle they are viewing. Here is the order of importance for now:
1) Dealer Listings (d_id)(Show vehicles also listed by that dealer)
2) Vehicle Category (vc_id)(Vehicle category such as Car, Truck, SUV, etc.)
3) Vehicle Make (vm_id)(Vehicle make such as Ford, Chevy, Lexus, etc.)
I have created a SQL statement, but it does not seem to do what I am looking for it to do. Can anyone offer any suggestions on how to properly build a SQL statement to grab the most relevant records in the order defined above?
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id
If Not CheckBlank(d_id) Then
strSQL = strSQL & " OR v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " OR v.vm_id = " & vm_id
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " OR v.vc_id = " & vc_id
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
I have a couple of thoughts for you.
Your current query has some ANDs and some ORs. You may need brackets to indicate your preferred order of operations, for example:
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
strSQL = strSQL & "("
End If
If Not CheckBlank(d_id) Then
strSQL = strSQL & " OR v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " OR v.vm_id = " & vm_id
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " OR v.vc_id = " & vc_id
End If
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
strSQL = strSQL & ")"
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
But based on what you wrote in your question, you may be better with a query that uses the ORDER BY clause to get the most appropriate records based on the criteria you specified.
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id & " ORDER BY"
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
If Not CheckBlank(d_id) Then
strSQL = strSQL & " CASE WHEN v.d_id = " & d_id & " THEN 0 ELSE 1 END,"
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " CASE WHEN v.vm_id = " & vm_id & " THEN 0 ELSE 1 END,"
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " CASE WHEN v.vc_id = " & vc_id & " THEN 0 ELSE 1 END,"
End If
strSQL = Left(strSQL, Len(strSQL) - 1)
Else
strSQL = strSQL & "v.d_id, v.vc_id, v.vm_id"
End If
This query will still give you results even if there are no vehicles for that dealer, make or category, so you will always have related vehicles (assuming you have at least 5 records).
It looks like the OR clauses you're using are not going to bring you you want. Assuming I'm understanding the snippet and the unseen db correctly, you need to create a subclause of the OR statements that is "ANDED" in. Try the following, after the initial strSQL assignment:
...
dim strSubClause
strSubClause = ""
If Not CheckBlank(d_id)) Then
strSubClause = "v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
If len(strSubClause) > 0 then
strSubClause = strSubClause & " OR v.vm_id = " & vm_id
Else
strSubClause = "v.vm_id = " & vm_id
End If
End If
If Not CheckBlank(vc_id) Then
If len(strSubClause) > 0 then
strSubClause = strSubClause & " OR v.vc_id = " & vc_id
Else
strSubClause = "v.vc_id = " & vc_id
End if
End If
If len(strSubClause) > 0 then
strSQL = " AND (" & strSubClause & ")"
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
So, assuming all of your checks came back with values, you'd have a where clause that looks like:
...WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> NNN AND (v.d_id = XXX OR v.vm_id = YYY OR v.vc_id = ZZZ) ORDER BY v.d_id, v.vc_id, v.vm_id
Does that make sense and/or get you closer or all the way to where you're wanting to go?
With the below SQL statement I get all information about a student as needed except for one problem which is duplicate records when in fact last entered record for each student needed only.
Student ID Year level Semester
20012-000001 20012-20013 1
20012-000001 20012-20013 2
20012-000001 20012-20013 3
20012-000001 20012-20013 4
20012-000001 20012-20013 5
sqlSTR = "SELECT tblStudent.StudentID AS '??? ??????' , (tblStudent.FirstName + ' ' + tblStudent.MiddleName + ' ' + tblStudent.GrandFatherName + ' ' + tblStudent.LastName) as '?????' ," & _
"tblStudent.Gender as '?????', tblStudent.Citizenship as '???????', tblStudent.Type as '??? ?????'," & _
"tblDepartment.DepartmentTitle as '?????', tblEnrolment.SchoolYear as '????? ????????',tblYearLevel.YearLevelTitle as '????? ???????', " & _
"'????'= CASE WHEN Len(tblGraduate.StudentID)<>12 THEN '???' ELSE ''End , " & _
"'???? ???'= CASE WHEN Len(tblDropped.StudentID)<>12 THEN '???' ELSE ''End , " & _
"'??????'= CASE WHEN tblStudent.Transferee ='True' THEN '???' ELSE ''End" & _
" FROM tblDropped RIGHT JOIN " & _
"(tblGraduate RIGHT JOIN " & _
"(tblDepartment RIGHT JOIN " & _
"(tblYearLevel RIGHT JOIN " & _
"(tblSection RIGHT JOIN " & _
"(tblStudent LEFT JOIN tblEnrolment " & _
"ON tblStudent.StudentID = tblEnrolment.StudentID) " & _
"ON tblSection.SectionID = tblEnrolment.SectionOfferingID) " & _
"ON tblYearLevel.YearLevelID = tblEnrolment.YearLevelID) " & _
"ON tblDepartment.DepartmentID = tblSection.DepartmentID) " & _
"ON tblGraduate.StudentID = tblStudent.StudentID) " & _
"ON tblDropped.StudentID = tblStudent.StudentID" & _
" " & sFilter & _
" ORDER BY tblStudent.StudentID DESC , tblYearLevel.YearLevelTitle ASC"
Add a Date Field to your table containing the records and filter by most recent. IF the table already has one include a WHERE clause by date?
If I understand your table correctly the last record is always in the last semester, if you know the semester just do a UNIQUE keyword for the Student_ID