How does the DLookup work in this instance? - ms-access

New user here :)
I got a question about DLookup in the below code. The code is suppose to only allow a selected user to open a form. The user is in the tbl and with the On Error Resume Next the code is working, allowing the user to access the application, however when I comment out the On Error I get the Run-time error '13': Type Mismatch. I was hoping for someone to explain why does it fail with On Error commented out. I understand that If statement requires a condition to evaluate, so how does getting the username allow the application to open the form?
Private Sub Form_Open(Cancel As Integer)
On Error Resume Next
If DLookup("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") Then
Else
MsgBox "You do not have permission to access the application"
DoCmd.Close
End If
End Sub

That's really not the way to do this, but I'll explain what it does.
DLookUp looks up a value from a table. In your case, it's looking up CitrixID from the table CitrixID where CitrixID is equal to the username. It then returns that username as the condition for that If statement.
An If statement, however, expects the condition to be either True, False, Null, or a numeric value (0 = falsy, all other numerals are truthy) which counts as false, not a Windows username, that's why the error occurs.
If you use On Error Resume Next, you're actually jumping into that If statement if the DLookup returns a string, because that's the next thing. However, if it returns Null, because it can't find that username, that doesn't trigger an error, because Null is a valid value which is cast to false.
Some sample code to help you understand this:
Public Sub TestIfResumeNext()
If Null Then
Debug.Print Null
End If
On Error Resume Next
If "A" Then
Debug.Print "A"
End If
If 1 Then
Debug.Print 1
End If
If 0 Then
Debug.Print 0
End If
If -1 Then
Debug.Print -1
End If
End Sub
This will return "A" because of error capturing, 1 and -1 because they're truthy, but not Null because that's a valid falsy value, and not 0 for that same reason.
If you don't want to rely on this error trapping behavior, but want to keep the rest of the logic, you could simply replace DLookUp with DCount. Since 0 is falsy, you don't even need to check if it's 0 (but doing so is a good practice imho).
If DCount("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") Then
Or, with the comparison
If DCount("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") <> 0 Then
Note that you can now shorten it using If Not or If DCount = 0 and remove the Else

DLookup returns Null for "not found" so all you need is to check for this:
Private Sub Form_Open(Cancel As Integer)
If IsNull(DLookup("[CitrixID]", "tbl_UserAccess", "[CitrixID] = '" & Environ("username") & "'")) Then
MsgBox "You do not have permission to access the application."
DoCmd.Close
End If
End Sub

Related

MS Access Choosing Filter with ComboBox

I have returned with yet another Question regarding MS Access and its VBA environment.
I'm currently constructing a database in MS Access 2016.
The main View headview has a combobox viewcombo and a subform listview.
What I need: I want the combobox to filter the listview depending on the chosen entry of it.
What I did:
Private Sub ViewCombo_AfterUpdate()
On Error GoTo Proc_Error
If IsNull(Me.ViewCombo) Then
Me.ListView.Form.Filter = ""
Me.ListView.Form.FilterOn = False
Else
Dim selectedOption As AccessObject
selectedOption = Me.ViewCombo
Select Case selectedOption
Case selectedOption = "open"
Me.ListView.Form.Filter = "Column1='" & "'"
End Select
End If
Proc_Exit:
Exit Sub
Proc_Error:
MsgBox "Error " & Err.Number & " Setting Filter:" & vbCrLf & Err.Description
Resume Proc_Exit
End Sub
Note: The Me.ListView.form.Filter = "Column1='" & "'" is supposed to be empty if the chosen entry of viewCombo is open, the available entries are Open, Closed, ovedue, cancel and "as seleced
However, it seems that Access doesnt work this way. How do I properly write the select case statements?
Edit 1:
The Values of the ComboBox ViewCombo are manualy written in it. Depending on the selection of a value, different Filters are to be set on the ListView
Example:
The selected value is open
The Listview is filtered with the statement: Column1 is empty
The selected value is closed
The Listview is filtered with the statement Column 1 is not empty, Column 2 contains the value 10 (10 is an ID for a status, these are given to me by the employees I work with, those are internal and have no meaning for the database)
Hope that helps to clarify the situation.
You will use the value of the combobox, not the combobox as an object, similar to:
If IsNull(Me.ViewCombo.Value) Then
Me.ListView.Form.Filter = ""
Me.ListView.Form.FilterOn = False
Else
Select Case Me.ViewCombo.Value
Case Is "open"
Me.ListView.Form.Filter = "[SomeFieldName] = 'open'" ' or other filter value.
End Select
Me.ListView.Form.FilterOn = True
End If
I solved it with the Input you guys gave me:
Private Sub AuswahlFilter_AfterUpdate()
On Error GoTo Proc_Error
If Me.ViewCombo.Value = "All" Then
Me.ListView.Form.Filter = ""
Me.ListView.Form.FilterOn = False
Else
Select Case Me.ViewCombo.Value
Case Is = "Open"
Me.ListView.Form.Filter = "FlagOpenClosed='1'"
Me.ListView.Form.FilterOn = True
End Select
End If
Proc_Exit:
Exit Sub
Proc_Error:
MsgBox "Error " & Err.Number & " when creating Filter:" & vbCrLf & Err.Description
Resume Proc_Exit
End Sub
I created some additional Columns on the ListView. The Table listviewis based on now has additional columns filled with values from statements like When(IsNull(Column1);1;0). Then I set the filter for those values.
I guess there is a better way to do it, however, I am a noob in VBA, so that is the best solution I came up with. If there is a better way to do it, please dont hesitate to write it as an answer here, I am glad to learn new things, and love to hear from you guys.
-Ninsa

my for next loop is not working and gives error94

Cannot understand why my for and next loop is not working. What I am trying to do is to print a report for the same number of records details depending on the number value of a particular field called [nts].
If the field is empty it tells me I have error: 94. If the field has a value it goes to errorhandler mention in the program. Can any body be so kind and help me please? Thank you in advance :)** I am using ACCESS2007
Option Compare Database
Option Explicit
Private Sub Report_Close()
' Delete previous data from tabMeal
DoCmd.SetWarnings False
DoCmd.RunSQL "Delete from tabAmeal"
End Sub
Private Sub Report_Load()
Dim intNOM As Integer
'NOM means number of nights meals
Dim mTimes As Integer
On Error GoTo errorhandler
intNOM = 1
mTimes = 0
mTimes = DLookup("nz([nts],0)", "tabAmeal", "[nts] > 0")
'mTimes means number of meals
If mTimes = 0 Then
MsgBox "File is empty GO to Query" & vbCrLf & "Error - Run the Query", vbQuestion
Else
'now print the information found in table "tabmeal" number of times depending on the value field "nts"
For intNOM = 1 To mTimes
DoCmd.OpenReport "repAmeal?", acViewPreview
Next intNOM
End If
errorhandler:
MsgBox "Error #:- " & Err.Number & vbCrLf & "LOOP not working" & vbCrLf & "Must find why this error" & vbCrLf & Err.Description
End Sub
Private Sub Report_NoData(Cancel As Integer)
MsgBox "Please note that you have no records to report." & vbCrLf & "You have to run the QUERY to get the required informatio."
End Sub
The first problem:
Nz() must be used outside of DLookup, not inside:
mTimes = Nz(DLookup("[nts]", "tabAmeal", "[nts] > 0"), 0)
The second problem, I'm not sure. You can't open a report multiple times in acViewPreview (it will open only once), but it shouldn't give an error.
What is the exact error message you get when nts > 0 ?
Oops. You need Exit Sub befor your errorhandler: line - the code simply enters the error handler, without there being an error. :)

DLookup Function - returning wrong value

I am trying to run the following code, but I'm getting a Run-time error '2471' on DLookUp. "The expression you entered as a query parameter produced this error: 'dkim'".
DLookUp returns a value, but it's returning the wrong value. This code is supposed to compare Text7 to a dlookup 'Password' value. Am I missing something?
Private Sub btn_enter_Click()
If Me.Text7.Value = DLookup("Password", "tbl_ref_users", _
"[ID]=" & Me.Text5.Value) Then
ID = Me.Text5.Value
'Close logon form and open splash screen
DoCmd.Close acForm, "form_Login", acSaveNo
DoCmd.OpenForm "form_Menu"
Else
MsgBox "Password Invalid. Please Try Again", vbOKOnly, _
"Invalid Entry!"
Me.Text7.SetFocus
End If
'If User Enters incorrect password 3 times database will shutdown
intLogonAttempts = intLogonAttempts + 1
If intLogonAttempts > 3 Then
MsgBox "You do not have access to this database.Please contact admin.", _
vbCritical, "Restricted Access!"
Application.Quit
End If
End Sub
I'm getting a Run-time error '2471' on DLookUp. "The expression you
entered as a query parameter produced this error: 'dkim'".
Since the DLookup expression is DLookup("Password", "tbl_ref_users", "[ID]=" & Me.Text5.Value), perhaps the .Value of Me.Text5 is dkim.
In that case, quote the text box value in the DLookup criteria:
DLookup("[Password]", "tbl_ref_users", "[ID]='" & Me.Text5.Value & "'")
However the datatype of tbl_ref_users.ID must be text in order for that to work. If it's numeric, you need to compare it to a number instead of a text string such as "dkim".
Also note I bracketed the field name Password because it's a reserved word.

Microsoft Access 2003 VBA - Login Form

This is my first attempt to create a login form. I've read up a few forums about it and tried them myself. However, I've encountered the error when trying out the form.
"Run time error '2001': You canceled the previous operation."
Here's my code! The error highlighted is the DLOOKUP statement. When I move my cursor to LanID, it appears to be 0. (I guess it got something to do with it?)
Option Compare Database
Option Explicit
Private intLoginAttempts As Integer
Private Sub cmdLogin_Click()
'Check mandatory fields
If IsNull(Me.txtLanID) Or Me.txtLanID = "" Then
MsgBox "Lan ID is required.", vbOKOnly, "Required Data"
Me.txtLanID.SetFocus
Exit Sub
End If
If IsNull(Me.txtPassword) Or Me.txtPassword = "" Then
MsgBox "Password is required.", vbOKOnly, "Required Data"
Me.txtPassword.SetFocus
Exit Sub
End If
'Compare input password and database password
If Me.txtLanID <> "" Then
If Me.txtPassword = DLookup("Password", "tblUser", "[LanID]=" & Me.txtLanID) Then
LanID = Me.txtLanID
'Close Login Page
DoCmd.Close acForm, "frmUserLogin", acSaveNo
'Check whether user is an admin
If Me.txtAdmin = DLookup("Administrator", "tblUser", "[LanID]=" & Me.txtLanID) Then
If Me.txtAdmin = -1 Then
DoCmd.OpenForm "frmMenu"
Else
DoCmd.OpenForm "frmBack"
End If
End If
Else
MsgBox "Invalid Password. Try again.", vbOKOnly, "Invalid Entry!"
Me.txtPassword.SetFocus
End If
End If
'If user enters incorrect password 3 times
intLoginAttempts = intLoginAttempts + 1
If intLoginAttempts = 3 Then
MsgBox "You do not have access to the database. Please contact system administrator.", vbCritical, "Restricted Access!"
Application.Quit
End If
End Sub
If tblUser.LanID is text data type, enclose Me.txtLanID in quotes to avoid an error with your DLookup() expression. (You don't need .Value there because it's the default property.)
DLookup("Password", "tblUser", "[LanID]='" & Me.txtLanID & "'")
If that was not the explanation, test your DLookup() expression in the Immediate window (go there with Ctrl+g) to see whether it throws an error or what value it does return.
Note, when you test DLookup() in the Immediate window, use the current value of Me.txtLanID. For example, if Me.txtLanID contains the text "foo", test it like this ...
? DLookup("Password", "tblUser", "[LanID]='foo'")

Access VBA throwing unlisted error code

I'm seeing an error code like this in my Access 2000 VBA:
-2147352567-Record in '[SomeTable]' was deleted by another user.
So, 2 questions:
1) How do I handle/avoid an error code like this?
2) Can anyone explain why I'm getting an error code that doesn't seem to exist in MS documentation? And is there some way to decipher this code? Is it a combination of several codes? Any guidance on this topic would be appreciated.
Public Sub Form_Open(Cancel As Integer)
' Check for unposted record / regardless of Date / Shift
' If there is an unposeted record goto it
Dim lCheck
Dim sPress As String
On Error GoTo Form_Open_Err
GotoRecord:
If bPressConsumptionOpenRan = True Then
lCheck = DLookup("PressConsumptionID", "spI_GetUnPostedRecord")
If Not IsNothing(lCheck) Then
Me.txtPressConsumptionID.SetFocus
DoCmd.FindRecord lCheck
Else
DoCmd.SetWarnings False
DoCmd.OpenQuery ("spI_InsertNewPressConsumption")
Me.Requery
DoCmd.SetWarnings True
End If
End If
Form_Open_Exit:
Exit Sub
Form_Open_Err:
sErrMsg = Err.Number & "-" & Err.Description
MsgBox sErrMsg, vbCritical + vbOKOnly + vbInformation, "Program Error"
So I just commented out the
On Error GoTo
lines in Form_Open(), Form_Load(), and Form_Activate(), and still no debugger call. This error is shown when the db is opened, so I have no idea where else the error could be in the code.
And here is the code for IsNothing:
Public Function IsNothing(vCheck As Variant) As Boolean
On Error GoTo IsNothing_Err
If IsNull(vCheck) Then IsNothing = True: Exit Function
If IsEmpty(vCheck) Then IsNothing = True: Exit Function
If Trim(vCheck) = "" Then IsNothing = True: Exit Function
IsNothing_Err:
IsNothing = False
End Function
Now I'm getting a similar error in Form_Current():
Private Sub Form_Current()
Dim sUser As String
On Error GoTo Form_Current_Err
If IsNothing(Me.dtpUsageDate) Then
Me.dtpUsageDate = Date 'This line throws error.
End If
...Ommitted to save space. Not relevant...
Form_Current_Err:
sErrMsg = Err.Number & "-" & Err.Description
MsgBox sErrMsg, vbCritical + vbOKOnly + vbInformation, "Program Error"
Resume Form_Current_Log
Form_Current_Log:
On Error Resume Next
Call LogError(sErrMsg, "PressConsumptions_Form_Current")
GoTo Form_Current_Exit
End Sub
Error Message:
-2417352567-There is no object in this control.
Is this message related to the other one we've been seeing? Any thoughts on correcting?
The error number and message suggest to me that this is a problem from outside of Access. The fact that you're executing a saved query that has a name suggesting that it runs an SPROC on a database server suggests to me that the back end is SQL Server or some other back end.
It's a very common error in Access when you don't have both a primary key and a timestamp field in your back end table. It's caused by the fact that Access can't tell exactly which record is involved and can't refresh the display appropriately. Having a PK and a timestamp field usually gets rid of the problem.
But it may be caused by something else, of course.