onLost focus Event is not working -ms access - ms-access

This code is not working. Can anyone help me out?
Private Sub txtErrorComment_5_LostFocus()
If IsEmpty(Me.txtErrorComment_5) Then
MsgBox "Eh..! It cannot be Empty."
End If
End Sub

txtErrorComment_5 is probably Null - which evaluates to False when run through IsEmpty() - yes, this is un-intuitive, but whenever you compare to Null, the result is false.
Try the following:
Private Sub txtErrorComment_5_LostFocus()
If IsEmpty(Me.txtErrorComment_5) or IsNull(Me.txtErrorComment_5) Then
MsgBox "Eh..! It cannot be Empty."
End If
End Sub
Or just:
Private Sub txtErrorComment_5_LostFocus()
If IsNull(Me.txtErrorComment_5) Then
MsgBox "Eh..! It cannot be Empty."
End If
End Sub
IsNull can handle Null's
Edit:
#David-W-Fenton is correct. The better way to do this BeforeUpdate (not LostFocus)
Private Sub txtErrorComment_5_BeforeUpdate(Cancel As Integer)
If IsNull(Me.txtErrorComment_5) Then
MsgBox "Eh..! It cannot be Empty."
Cancel=true
End If
End Sub

To detect whether txtErrorComment_5 is blank, concatenate a Null string to its value and see whether the character length of the combined expression is zero.
Private Sub txtErrorComment_5_LostFocus()
If Len(Me.txtErrorComment_5 & vbNullString) = 0 Then
MsgBox "Eh..! It cannot be Empty."
End If
End Sub
If you want txtErrorComment_5 treated as blank when it contains only one or more space characters, include the Trim() function.
Private Sub txtErrorComment_5_LostFocus()
If Len(Trim(Me.txtErrorComment_5) & vbNullString) = 0 Then
MsgBox "Eh..! It cannot be Empty."
End If
End Sub

Related

Making a form read-only for a certain user type

I have created a login form with a combo box for the user type (Admin, User) and a text box for the password. The code for the form is as follows.
Private Sub txtPassword_AfterUpdate()
If IsNull(Me.cboUser) Then
MsgBox "You need to select a user!", vbCritical
Me.cboUser.SetFocus
Else
If Me.txtPassword = Me.cboUser.Column(2) Then
If Me.cboUser.Column(3) = True Then
MsgBox "Password does not match, please re-enter!", vboOkOnly
Me.txtPassword = Null
Me.txtPassword.SetFocus
End If
DoCmd.OpenForm "FE1"
Me.Visible = False
Else
MsgBox "Password does not match, please re-enter!", vboOkOnly
Me.txtPassword = Null
Me.txtPassword.SetFocus
End If
End If
End Sub
Private Sub cboUser_AfterUpdate()
Forms!frmLogin!cboUser.Column (2)
End Sub
If the log in is as a User, when they get to the FE1 form, I want them just to be able to read the form, and not make any changes. The code I've been trying to use for this is as follows:
Private Sub Form_Open()
If Forms!frmLogin!cboUser.Column(2) = 2 Then
Me.AllowEdits = False
Me.AllowAdditions = False
Me.AllowDeletes = False
Else
Me.AllowEdits = True
Me.AllowAdditions = True
Me.AllowDeletes = True
End If
End Sub
But I keep getting the error:
The expression On Open you entered as the event property setting
produced the following error: Procedure declaration does not
match description of event or procedure having the same name.
*The expression may not result in the name of a macro, the name of a user-defined function, or [Event Procedure].
*There may have been an error evaluating the function, event, or macro.
It's possible I've just been looking at this for too long, but I can't figure out where I've gone wrong!?
Your Form_Open procedure has the wrong signature, missing the Cancel parameter.
It must be:
Private Sub Form_Open(Cancel As Integer)
Don't write event procedures by hand, let Access create them.
Edit
I suggest you completely remove the Form_Open sub. Then let Access create it from the property sheet.
And you can simplify your code by using a variable like this:
Private Sub Form_Open(Cancel As Integer)
Dim AllowWriting As Boolean
AllowWriting = Not (Forms!frmLogin!cboUser.Column(2) = 2)
Me.AllowEdits = AllowWriting
Me.AllowAdditions = AllowWriting
Me.AllowDeletes = AllowWriting
End Sub
or even shorter with the RecordsetType Property:
Private Sub Form_Open(Cancel As Integer)
If Forms!frmLogin!cboUser.Column(2) = 2 Then
Me.RecordsetType = 2 ' Snapshot = read-only
Else
Me.RecordsetType = 0 ' Dynaset = read-write
End If
End Sub

The IF....then statement in Access VBA

I am testing my understanding on the if then statement, I wrote a little thing down below but when I hit run, nothing happened. I was expecting a msgbox will appear asking me if I want to quit or not and giving me choices to choose. Did I miss anything please. Thanks
Sub testifthenelse(bQuit As Boolean)
Dim s As String
s = "Do you want to quit?"
If MsgBox(s, vbYesNo, "Quite?") = vbYes Then
bQuit = True
Else
bQuit = False
End If
End Sub
you must call it from another sub:
Sub main()
Dim bQuit As Boolean
testifthenelse bQuit
End Sub
while, if you want to run and test it "by itself" then make the argument optional
Sub testifthenelse(Optional bQuit As Variant)
Dim s As String
s = "Do you want to quit?"
If MsgBox(s, vbYesNo, "Quite?") = vbYes Then
bQuit = True
Else
bQuit = False
End If
End Sub

Automatically Close Form After Certain Idle Time

I am having a little bit problem on my access form.
I have 2 forms:
menu-form
input-form
After input-form has been idle for one minute, I want to close it and go back to the menu-form.
This is my code that isn't working.
Public ExpireTime As Date 'expiration time-date value
Sub ResetExpiration()
If ExpireTime <> 0 And ExpireTime > Now Then
Application.OnTime ExpireTime, "FormExpire", schedule:=False
End If
ExpireTime = Now + 1 / 1440#
Application.OnTime ExpireTime, "FormExpire", schedule:=True
End Sub
I also created a macro with this in it.
Sub FormExpire()
Unload input-form
End Sub
You need to set the form.Timer to 60000 (that is 1 minute) then use on OnTimer event to check if some properties have changed. Below I quickly wrote something to give you an idea, but it is not complete nor tested.
Option Compare Database
Option Explicit
Dim isIdle As Boolean
Private Sub Form_LostFocus()
'you can use this event also
End Sub
Private Sub Form_Timer()
Dim ctlName As String, wasDirty As Boolean
If ctlName = vbNullString Then ctlName = Me.ActiveControl.Name
If Me.ActiveControl <> ctlName Then isIdle = False
If wasDirty <> Me.Dirty Then isIdle = False
'more checks....
If isIdle Then DoCmd.Close acForm, Me.Name
End Sub
You've got a couple of potential issues here.
First and foremost, that's not how you close a form.
This:
Sub FormExpire()
Unload input-form
End Sub
Should look something more like this:
Sub FormExpire()
DoCmd.Close acform, Me.Name
DoCmd.OpenForm "menu-form"
End Sub
Your second issue is that I don't believe the Application.Ontime method is available from Access. MSDN says it's an Excel function, and I can't find it in the Access Documentation. I'd personally be interested in seeing you make your method work with the Access form Timer Event.
I'm not sure it matters, but I think this is what you were trying to do.
Public ExpireTime As Date 'expiration time-date value
Private Sub InputForm_Timer()
If ExpireTime <> 0 And ExpireTime > Now Then
Call FormExpired
Else
' reset timer
ExpireTime = Now + 1 / 1440#
End If
End Sub
I'm not sure this method would work without also including #iDevelop's answer. I just wanted to help clarify where you were going wrong.
I realize that this thread is aged but I recently experienced a need to close forms from a timer event and came across the answers here. My situation was slightly different as I had several forms to close so here is my solution.
Private Sub Form_Timer()
Dim daysRemaining As Integer
Dim endDate As Date
endDate = "4/15/2021"
daysRemaining = DateDiff("d", Now, endDate)
MsgBox ("This is an evaluation version of the application. You have " & Str(daysRemaining) & " days of use remaining")
If daysRemaining < 1 Then
Close_All
End If
End Sub
Private Sub Close_All()
For Each myForm In CurrentProject.AllForms
strFormName = myForm.name
DoCmd.Close acForm, strFormName
Next
End Sub

Check Access Form Field for Null, if Not Null then Call the Add Feature

I have this simple Access Form that when you fill out the form and forget to fill out the Business Unit field, a msgBox will pop up telling you so and setFocus to that very Combo box. If it is Not null, I want to call the next feature. The first part of this code works, but the when it is notNull it wil not carry on.
Private Sub Image_AddNon_RPS_Button_Click()
If IsNull(Me.BU_Selected_Add) Then
MsgBox "Please Select a Business Unit!", vbOKOnly
Exit Sub
End If
Me.Combo_BU_Selector.SetFocus
Exit Sub
If Not IsNull(Me.BU_Selected_Add) Then
Call Add_RPS_LINE
End If
End Sub
Does anybody see where I am totally out in left field?
You've got an extra Exit Sub (the one after the first MsgBox) that stops your code from doing what you want. Also, your first End If is in the wrong location.
Try something like this instead:
Private Sub Image_AddNon_RPS_Button_Click()
If IsNull(Me.BU_Selected_Add) Then ' No business unit
MsgBox "Please Select a Business Unit!", vbOKOnly ' Tell user
Me.Combo_BU_Selector.SetFocus ' Focus the control
Exit Sub ' Exit the method
End If ' End the IsNull test
Call Add_RPS_LINE ' You only get here if the above doesn't execute
End Sub
It helps if you learn to properly indent your code to match If and End If visually, so you can see where they line up (match) and where they don't. :-)
If you correct the indentation of your code to:
Private Sub Image_AddNon_RPS_Button_Click()
If IsNull(Me.BU_Selected_Add) Then
MsgBox "Please Select a Business Unit!", vbOKOnly
Exit Sub
End If
Me.Combo_BU_Selector.SetFocus
Exit Sub
If Not IsNull(Me.BU_Selected_Add) Then
Call Add_RPS_LINE
End If
End Sub
You can clearly see that the Exit Sub in the middle will terminate the function before it gets to Call Add_RPS_LINE.
If you look at the two If statements you have, you can see that they are almost the same and so an Else is in order, resulting in this simpler and more readable code.
Private Sub Image_AddNon_RPS_Button_Click()
If IsNull(Me.BU_Selected_Add) Then
MsgBox "Please Select a Business Unit!", vbOKOnly
Me.Combo_BU_Selector.SetFocus
Else
Call Add_RPS_LINE
End If
End Sub

Why is my .setfocus ignored?

I have an Access form with a textbox that is meant to allow for repeatedly typing a number, hitting enter, and letting a script do stuff. For speed, the field should keep the focus after DoStuff() is done.
However, while I'm sure that DoStuff() is run, the focus always goes to the next field in the tab order. It's like Me.MyFld.SetFocus is being ignored.
How do I keep the focus on this field after DoStuff() is done?
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Me.MyFld.SetFocus
End If
End Sub
If you look at the order of events for a keypress that would change focus, you can see that it always follows this pattern:
KeyDown → BeforeUpdate → AfterUpdate → Exit → LostFocus
You can re-set the focus anywhere in there and it will still keep following the pattern. So we need to tell it to stop following the pattern. Replace your Me.MyFld.SetFocus with DoCmd.CancelEvent and it should fix your problem. Basically, this just kicks you out of the above pattern, so the Exit and LostFocus events never fire...
A workaround is moving the focus to another control and then back to the first control. Like this:
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Me.anotherControl.SetFocus
Me.MyFld.SetFocus
End If
End Sub
click on access options
select Advanced
select Don't move from Move after enter
click ok
It will work 100%
Try removing the whole line for variable_name.SetFocus and simply add:
Cancel = True
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Cancel = True
End If
End Sub
Another solution to the problem that I use in Excel.
Let there exist UserForm1 with the TextBox1 and CommandButton1 controls.
Code in the form module:
Option Explicit
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = vbKeyReturn Then
'Call DoStuff
Application.OnTime Now, "'Control_SetFocus """ & Me.Name & """, """ & Me.ActiveControl.Name & """ '"
' The concatenation returns a string: 'Control_SetFocus "UserForm1", "TextBox1"'
End If
End Sub
And code in the standard module:
Option Explicit
Sub Control_SetFocus(FormName As String, ControlName As String)
Dim oUserForm As Object
Set oUserForm = GetFormByName(FormName)
If Not oUserForm Is Nothing Then
oUserForm.Controls(ControlName).SetFocus
End If
End Sub
Function GetFormByName(FormName As String) As Object
Dim oUserForm As Object
On Error GoTo ErrHandle
For Each oUserForm In VBA.UserForms
If StrComp(oUserForm.Name, FormName, vbTextCompare) = 0 Then
Exit For
End If
Next oUserForm
If oUserForm Is Nothing Then
Set oUserForm = UserForms.Add(FormName)
End If
Set GetFormByName = oUserForm
Exit Function
ErrHandle:
Select Case Err.Number
Case 424:
MsgBox "Userform " & FormName & " not exists.", vbExclamation, "Get userform by name"
Case Else:
MsgBox Err.Number & ": " & Err.Description, vbCritical, "Get userform by name"
End Select
End Function
Artik
An easy solution that works in Excel is to set the KeyCode to 0. If DoStuff steals the focus then you should also set the focus back:
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
KeyCode = 0
Me.MyFld.SetFocus
End If
End Sub