Dlookup returning number as text - ms-access

The DLookup is returning number values as text. Thoughts on what's either wrong with my code or reasons why that would happen? I'm hoping it's something simple.
Sort: DLookUp("Sort","contacts_rank_CurrentRank","ContactID = " & [ID])
I've tried to Format as "General Number" but that doesn't transform the value back to a number
I've tried the below formula but that results in "Error"
Sort: DLookUp("Sort","contacts_rank_CurrentRank","ContactID = '" & [ID] & " ' ")
Visual of the data in the query I'm looking up the data from. Sort Column in Contacts_Rank_CurrentRank
Value that is being returned with the dlookup

You don't really need a dlookup here - a sql left join against that table will run at least 100x times faster.
But, you can do this if performance is not a issue:
clng(DLookUp("Sort","contacts_rank_CurrentRank","ContactID = '" & [ID] & " ' "))

Related

Dlookup with multiple criteria return the same result

When I run the following query,
Dlookup("[Service Description]","[Roster_QC]","[ID]=" & [ID]-1 AND "'[Person]= '" & [Person]&"'")
It showed the same result every time.
What I try to achieve is to let the Dlookup return for the previous service description when the person is the same.
Appreciate your insights or solution to this. Thanks.
Have an extraneous apostrophe and incorrect concatenation.
Dlookup("[Service Description]", "[Roster_QC]", "[ID]=" & [ID]-1 & " AND [Person]= '" & [Person] & "'")
That approach assumes there are no gaps in ID sequence. If there are gaps, expect incorrect results. Alternative query where gaps are irrelevant:
SELECT Roster_QC.*, (SELECT TOP 1 Dupe.[Service Description] FROM Roster_QC AS Dupe
WHERE Dupe.Person = Roster_QC.Person AND Dupe.ID<Roster_QC.ID
ORDER BY Dupe.ID DESC) AS Prev
FROM Roster_QC;

How to link a field from a different table in a form in MS Access

Bear with me; I have very little MS Access experience, by plenty of SQL experience.
This is the basic data structure:
I have an Employee table, a Training table, and a joining Employee_Training table (many-to-many relationship). There is a list of employees, and a list of possible training that those employees can do. Any employee may have attended several training sessions, where each entry has a recorded attendance date.
I am trying to make a form that performs in the following way:
You select an employee from a combobox at the top of the page
The form contains a list of all possible training sessions, each with a label and a textbox. If the employee has attended a training session, the corresponding textbox has the attendance date in it, otherwise the text box is blank.
I want to be able to enter a date in a blank textbox, or change the date in a non-blank textbox.
I can't use a DataSheet view because there are about 150 training types, and this needs to be converted into a printable form, so the information is compressed in columns on the form, like below:
Rough Layout:
Select Employee: [ John Smith | v ]
Training type 1: [ ] Training type 25: [ ]
Training type 2: [ ] Training type 26: [ 05/06/15 ]
Training type 3: [ ] Training type 27: [ ]
... ...
The form was originally created by hand, but now is created by a VBA script, though I don't think that will be too relevant here.
How do I structure the form's record source and the control source of the text boxes to allow me to see what I want to see, and edit what I need to edit?
you have to drop out the databinded forms.
if you use Recordset objects, you yan use a query binded to comboboxes and
some small vba code to save your data to tables.
I think the printing in access more flexible if u use the reports instead of the forms :)
First, for printing out data, you will create a report. So drop the idea that because of repeating data you have some problem or issue here. You can format your report like an invoice or whatever. The idea that you have “many” choices effects this choice is simply a non-issue. You form/report likely not to include all 150 choices, and makes it hard to read. And if you really must, then you can include all 150 choices along with the “only” ones chosen showing a date.
Next up: Attempting to display 150 choices on the form is going to be REALLY hard – you run out of room fast on the form. And even your above mock-up shows a datasheet like repeating data display – if it goes on for 150 rows, you not likely to fit all that on a screen without using some kind of repeating data display anyway.
Think of ANY existing software you used – VERY rare to see 150 choices all at once – you have to “choose” from a list. Think of an invoice form in an accounting package – you can display all the choices – you have to scroll or “search” a bit to narrow down choices.
The most easy would be to have the main form based on the employee (so name, phone and all that jazz). The sub form would then display a combo box to select the training/course, and then a date box to enter the date. (The date could even automatic be defaulted to today, or the course start date or whatever).
The result is you point + shoot, point + shoot – much like a click, click click type of process.
Here is an example of an invoice form in Access. To make this animation I did not touch the keyboard – it was just mouse click, mouse click etc. However the combo box DOES allow partial matching and search to narrow down the list presented (again with your long list you don’t want to torture users!). So you can type in a “few” characters into the combo box to narrow down the list of choices.
I mean, either way you going to force the user to pick from 150 choices. However, having to “scroll” through 150 choices ALWAYS to JUST view the courses the person has taken is going to be torture to the user.
So display JUST the courses selected – that way when you bring up a student, you can EASY see what courses they have, and as this follow animation shows, it would be a snap to add additional courses.
As noted, the droop down list could “remove” existing choices, or display the date if any course has already been selected. Simple logic to prevent duplicates would be added to the combo box before update event.
There are a ton of possible solutions for this question. I'm gonna try to stay close to your rough layout. I imagine a database with 3 tables like this :
* table: Employee (EmpID, EmpName)* table: Training (TraID, TraName)* table: Employee_Training (EmpTraID, ET_EmpID, ET_TraID, ET_Date)
Create a continuous form based on a query like:
SELECT Training.TraID, Training.TraName, Employee_Training.EmpTraID, Employee_Training.ET_EmpID, Employee_Training.ET_Date
FROM Training LEFT JOIN Employee_Training ON Training.TraID = Employee_Training.ET_TraID;
In the header-section of the main form, place a combobox called "ChosenEmpoyee". As recordsource for this combobox
"SELECT EmpID, EmpName FROM Employee", so 2 columns, and the ColumnWidths set to "0;5" to hide the first column. The column with EmpID is needed to filter the records.
When selecting an employee from the combobox, the afterupdate event will change the recordsource of the form to a query like this example:
SELECT Training.TraID, Training.TraName, A.EmpTraID, A.ET_EmpID, A.ET_Date
FROM ( SELECT Employee_Training.EmpTraID, Employee_Training.ET_EmpID, Employee_Training.ET_TraID, Employee_Training.ET_DateFROM Employee_Training WHERE Employee_Training.ET_EmpID = 3 ) As ARIGHT JOIN Training ON Training.TraID = A.ET_TraID
The code to perform this :
Private Sub ChosenEmployee_AfterUpdate()
Dim SQL As String
SQL = "" & _
" SELECT Training.TraID, Training.TraName, A.EmpTraID, A.ET_EmpID, A.ET_Date " & _
" FROM (SELECT EmpTraID, ET_EmpID, ET_TraID, ET_Date " & _
" FROM Employee_Training WHERE ET_EmpID = " & ChosenEmployee & _
" ) As A " & _
" RIGHT JOIN Training ON Training.TraID = A.ET_TraID"
Me.RecordSource = SQL
Me.Requery
End Sub
A second part of the question; having a contineous form with 5 columns, presenting the information in 5 textboxes with the same name:
TraID / TraName / EmpTraID / ET_EmpID / ET_Date
The employee is chosen by selecting in the combobox in the header.
The training will be chosen by double clicking on the textbox in the
desired row. If there was already a date, the EmpTraID will
have a value greater then 0.
The code to perform this :
Private Sub AT_Date_DblClick(Cancel As Integer)
Dim S As String
Dim D As Date
Dim SQL As String
Dim EmpTraID As Long
S = "Please give the date of attendance."
S = InputBox(S)
If Not IsDate(S) Then
S = "I'm sorry, the entered value > is not recognised as a date."
MsgBox S, vbExclamation
'Cancel = True
Else
D = CDate(S)
S = "Are you sure to enter the following date of attendance ?" & vbCrLf & Format(D, "dddd, dd mmmm yyyy")
If MsgBox(S, vbYesNo + vbDefaultButton2 + vbQuestion) = vbYes Then
'
' the following 2 lines will result into troubles ...
' Ms Access is not able to alter values
' in a recordset based on a query with a JOIN-statement
'
'Me.AT_Date = CDate(S)
'Me.Refresh
'
' if there was already a date then
' change the date by using AttTraiID
' else
' insert a record in AttTrai_T
' end if
'
EmpTraID = Nz(Me.EmpTraID.Value, 0)
If EmpTraID <> 0 Then
SQL = ""
SQL = SQL & "UPDATE Employee_Training "
SQL = SQL & " SET ET_Date = "
SQL = SQL & " #" & Format(D, "mm/dd/yyyy") & "# " ' US-date-format needed when using '#' in a query in MsAccess
SQL = SQL & " WHERE EmpTraID = " & EmpTraID
Else
SQL = ""
SQL = SQL & "INSERT INTO Employee_Training "
SQL = SQL & " (ET_EmpID, AT_TraID, ET_Date) "
SQL = SQL & " VALUES "
SQL = SQL & " (" & ChosenEmployee
SQL = SQL & " ," & Nz(Me.TraID.Value, 0)
SQL = SQL & " , #" & Format(D, "mm/dd/yyyy") & "# " ' US-date-format needed when using '#' in a query in MsAccess
SQL = SQL & " )"
End If
CurrentDb.Execute SQL
DoEvents: DoEvents: DoEvents
Me.Requery
End If
End If
End Sub

How to search and find and filter in Access vba

In my Access database, I'm trying to perform a search and find routine which is quite complicated. Basically, I have 4 criteria to look for in these four tables: Date, Service, Code and Function.
With this information I go into a table, and search in a field and for one criteria. After I've found the rows which correspond to one of the 4 criteria, I save the value of the neighboring field for all the rows which matched correctly. After this, I wanted to save the values of all the neighboring fields as an array. Then repeating these steps, I was going to save all 4 searches as 4 individual arrays.
The relationships of my tables are as follows:
I receive a "Demande" which is a request, and in that request are the four criteria: Date, Service, Code and Function.
In the table "Services_YES" I look for the Service that corresponds to the demand.
In the table "Pool_Personnel" I look for the Fonction that corresponds to the demand.
In the table "Days_Available" I look for both the Date and the Code (called Code_Horaire) which corresponds to the demand.
From there, I was hoping to record each Code_Personal for all of the results found, and then find which Code_Personal's matched in all of the 3 tables.
So My question:
How I can do a search and find function which creates an array of for all of the Code's which correspond to the criteria rows?
I have created psuedo code to help explain, and incase someone can translate this into real VBA:
While demandeTable.functionField.Value = poolpersonnelTable.Fonction1Field.Value
get all poolpersonnelTable.codepersonalField.Value for all rows that match
save fonctionArray = codepersonalField.Values
Loop
I'm very stuck on how to complete this 'filtering', and would strongly appreciate all help.
Using VBA is not the answer.
I ended up creating a Query, and using user-inputed text to fill in the variable parts of the query:
comboService = Chr(34) & Me.Combo8.Value & Chr(34)
txtDate = Chr(34) & Me.Text15.Value & Chr(34)
comboCodeHoraire = Chr(34) & Me.Combo17.Value & Chr(34)
"SELECT tblPoolPersonnel.LName, tblPoolPersonnel.FName, tblPoolPersonnel.[Tel Natel], tblPoolPersonnel.[Tel Home], tblPoolPersonnel.Email" & vbCrLf
"FROM ((tblPoolPersonnel INNER JOIN tblFonction ON tblPoolPersonnel.Code_Personal = tblFonction.Code_Personel) INNER JOIN tblDayAvailable ON tblPoolPersonnel.Code_Personal = tblDayAvailable.Code_Personal) INNER JOIN tblServiceYES ON tblPoolPersonnel.Code_Personal = tblServiceYES.Code_Personal" & vbCrLf
"WHERE (((tblServiceYES.Service)=" & comboService & ") AND " + _
"((tblDayAvailable.Availability)=True) AND " + _
"((tblDayAvailable.Date)=" & txtDate & ") AND " + _
"((tblDayAvailable.CodeHoraire1)=" & comboCodeHoraire & "))"

SQL UPDATE based on condition

We need to update a table with the users id (NBK). The table with NBK also has the user status (0 - 1) and only one user will have 1 at a time. The challenage is to #1 capture the active user #2 update the other table with the user NBK. I hope the code below just has a simple syntex error that I cannot find?
Dim nb As String
Dim NBK As String
nb = [Employees]![NBK] & "' WHERE "
nb = nb & " " & [Employees]![Status] = '1'
NBK = " Update tbl_DateTracking SET NBK = "
NBK = NBK & "'" & nb & "' WHERE "
NBK = NBK & "CaseId = '" & CaseId & "' AND OCC_Scenario = '" & OCC_Scenario & "' ;"
DoCmd.RunSQL nb
DoCmd.RunSQL NBK
Several pointers of note here:
You should use parameterized queries instead of string concatenation. This prevents/contains SQL injections and other issues regarding malformed input.
Ideally, you should normalize the database so that "active user" is not a field on the user table. What happens when there are two users set as "active" in the database?
With this given schema however, you're going to want to use a sub-select query. Ex:
UPDATE tbl_DateTracking SET NBK=(SELECT NBK FROM Employees WHERE Status=1 LIMIT 1) WHERE CaseID=? AND OOC_Scenario=? and then pass in CaseId and OOC_Scenario as the parameters.
Note, I'm not familiar with VB or how it interacts with SQL; The above is just an example, you'll have to apply it to your application and alter it to make it work. The way you're building and running the nested queries also looks like it won't work, since your first query doesn't contain a command (You probably want SELECT, I think. Does VB do that automatically with []![] syntax?), and when you nest it inside the second query, it's not surrounded with (). Running the first query by itself also has no effect if you're including it as a sub-query in the second one.

MS-Access 2003 - Expression in a Text Box on a form

just wondering when using an expression on a form in a text box, to return a value from a table, can the expression have multiple tables in the expression to return the value?
the tables are linked and I can return the value in a query, so I figured that Access would be able to do it with this method as well????
=DSum("[tblMain]![Revenue]","tblMain","[tblMain]![Quarter]=3 AND [tblMain]![Region]='NorthEast'" AND [tblOffice]![Location]='NewYork'")
this is the expression that I entered into my text box, without the reference to the 2nd table it works fine, but once I had it, I get the flickering error message in the text box (just as on a report)......
I know this method is probably used more in reports than forms, but I am novice, and trying to come up with a dashboard solution that returns lots of facts quickly per department. I am using this in the "Control Source" field of the data tab of the properties window, not VB. Mainly because I do not know how to get it to work with VB.
Thanks for the help as always!
As far as I know, you cannot refer to more than one table or query in a domain aggregate function. As grazird says, how are these tables related? Let us say it is on tblMain ID, you can build a query called, say, qryMainOffice, the SQL (SQL View, Query Design window) would look something like:
SELECT [tblMain].[Revenue],[tblMain]![Quarter],[tblMain]![Region],
[tblOffice]![Location]
FROM tblMain
INNER JOIN tblOffice
ON tblMain.ID = tblOffice.MainID
DSum would then be (remove line break):
=NZ(DSum("[Revenue]","qryMainOffice",
"[Quarter]=3 AND [Region]='NorthEast' AND [Location]='NewYork'"),"Not found")
You could also use a recordset or query in VBA to return the value.
EDIT re COMMENT
To use the above in VBA, you either need to add parameters or use a string:
''Reference: Microsoft DAO 3.x Object Library
Dim rs As DAO.Recordset
Dim db As Database
Dim strSQL as String
Set db= CurrentDB
strSQL = "SELECT Sum(t.[Revenue]) As TotalNY" _
& "FROM tblMain t " _
& "INNER JOIN tblOffice o " _
& "ON t.ID = o.MainID " _
& "WHERE t.[Quarter]=3 AND t.[Region]='NorthEast' " _
& "AND o.[Location]='NewYork' " _
'' I have use aliases for simplicity, t-tblMain, o-tblOffice
'' If you wish to reference a control, use the value, like so:
'' & " AND [Location]='" & Me.txtCity & "'"
'' Dates should be formated to year, month, day
'' For joins, see http://www.devshed.com/c/a/MySQL/Understanding-SQL-Joins/
Set rs = db.OpenRecordset strSQL
If Not rs.EOF Then
Me.txtAnswer = rs!TotNY
Else
Me.txtAnswer = "N/A"
End If
You can also use different queries to return several results that can be shown with a list box or a subform:
strSQL = "SELECT TOP 5 o.[Location]," _
& "Sum(t.[Revenue]) AS TotRevenue" _
& "FROM tblMain t " _
& "INNER JOIN tblOffice o " _
& "ON t.ID = o.MainID " _
& "WHERE t.[Quarter]=3 AND t.[Region]='NorthEast' " _
& "GROUP BY o.[Location]"
The above would return revenue for quarter 3 for all locations in NorthEast region. If you want the top values of each group, you are looking at a more complicated query, which I will leave for now.
How are these tables related? Can you describe the relationship and any primary/foreign keys?
Also, referencing the table name is not necessary in the first parameter of this function (since it is already taken care of in the second one).
For example, your code could be:
=DSum("Revenue","tblMain","Quarter=3 AND Region='NorthEast'" AND [tblOffice]![Location]='NewYork'")
Just trying to save you some keystrokes and increase its readability. :)