I am using the following vba code in my form.
Private Sub imgCustomer_Click()
On Error GoTo Err_Handler
DoCmd.Close acForm, "frmCustomer", acSaveYes
DoCmd.OpenForm "frmSplashScreen"
Exit_This_Sub:
Exit Sub
Err_Handler:
MsgBox "Error #: " & Err.Number & " " & Err.Description
Resume Exit_This_Sub
End Sub
My problem is that the form contains textbox which must not left empty. If for example Surname and Name fields must have a value and the user only fill the Surname and press the imgCustomer_Click, the database will continue without showing a error to fill up the empty fields. Any ideas?
ps: Can I use a vba so it will automatically fill the field with a value, instead?
You can write a function to validate the required fields and proceed when validation is successful.
Private Function FormValidated() As Boolean
With Me
If IsNull(.FirstControlName.Value) Then Exit Function
If IsNull(.SecondControlName.Value) Then Exit Function
'additional controls...
End With
FormValidated = True
End Function
You can then call it in your procedure:
Private Sub imgCustomer_Click()
On Error GoTo Err_Handler
If Not FormValidated Then
MsgBox "Validation failed.", vbExclamation
GoTo Exit_This_Sub
End If
DoCmd.Close acForm, "frmCustomer", acSaveYes
DoCmd.OpenForm "frmSplashScreen"
Exit_This_Sub:
Exit Sub
Err_Handler:
MsgBox "Error #: " & Err.Number & " " & Err.Description
Resume Exit_This_Sub
End Sub
Edit:
If this is a bound form, you need to cancel the auto-update and save the record only when validation is successful.
Option Explicit
'Set a flag for manual update
Private mIsUserUpdate As Boolean 'Flag
'Cancel auto-update
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not mIsUserUpdate Then Cancel = True
End Sub
'Save
Private Sub imgCustomer_Click()
On Error GoTo Err_Handler
If Not FormValidated Then
MsgBox "Validation failed.", vbExclamation
GoTo Exit_This_Sub
End If
mIsUserUpdate = True 'flag ON
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Close acForm, "frmCustomer", acSaveYes
DoCmd.OpenForm "frmSplashScreen"
Exit_This_Sub:
mIsUserUpdate = False 'Flag OFF
Exit Sub
Err_Handler:
MsgBox "Error #: " & Err.Number & " " & Err.Description
Resume Exit_This_Sub
End Sub
'Validation
Private Function FormValidated() As Boolean
With Me
If IsNull(.FirstControlName.Value) Then Exit Function
If IsNull(.SecondControlName.Value) Then Exit Function
'additional controls...
End With
FormValidated = True
End Function
Related
I have googled everywhere but I am unable to find out to do it without rewriting all the code, is there anyway to have this code check whether the file name matches table names and if it does then clear that table and re import or if not then create a new table?
Option Compare Database
Option Explicit
Private Sub btnBrowse_Click()
Dim diag As Office.FileDialog
Dim item As Variant
Set diag = Application.FileDialog(msoFileDialogFilePicker)
diag.AllowMultiSelect = False
diag.Title = "Please select an Excel Spreadsheet"
diag.Filters.Clear
diag.Filters.Add "Excel Spreadsheets", "*.xls, *.xlsx, *.xlsm"
If diag.Show Then
For Each item In diag.SelectedItems
Me.txtFileName = item
Next
End If
End Sub
Private Sub btnImportSpreadsheet_Click()
Dim FSO As New FileSystemObject
If FSO.FileExists(Nz(Me.txtFileName, "")) Then
ImportExcelSpreadsheet Me.txtFileName, FSO.GetFileName(Me.txtFileName)
ElseIf Nz(Me.txtFileName, "") = "" Then
MsgBox "Please select a file!", vbExclamation
Else
MsgBox "File not found!", vbExclamation
End If
End Sub
Public Sub ImportExcelSpreadsheet(Filename As String, TableName As String)
On Error Resume Next
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, TableName, Filename, True
If Err.Number = 3125 Then
If vbOK = MsgBox(Err.Description & vbNewLine & vbNewLine & "Skip column header and continue?", vbExclamation + vbOKCancel, "Error with Excel Column header") Then
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, TableName, Filename, False
MsgBox "Done", vbInformation
End If
Exit Sub
ElseIf Err.Number <> 0 Then
MsgBox Err.Number & ":" & Err.Description, vbCritical
Exit Sub
End If
MsgBox "Upload Complete", vbInformation
End Sub
Thank for any help
You'll have to rewrite some. Without looping through Tables collection and testing against each name, every method seems to involve handling an error. Here is one:
Function TableExists(strTableName As String) As Boolean
On Error Resume Next
TableExists = IsObject(CurrentDb.TableDefs(strTableName))
End Function
Call the function:
If TableExists("YourTableName") = True Then
More examples in How to check if a table exists in MS Access for vb macros
I have made a database in VBA access. I want to display login name on welcome form. Please guide me in this regard. I m trying to pass username from login form to welcome form through public variable but not working. My code is as under:-
Login Form Code
enter code here
Public strUserID As String
Private Sub cmdLogin_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
If IsNull(Me.txtLoginID) Or Me.txtLoginID = "" Then
MsgBox "Enter user Name.....", vbInformation, "Whiz Alert!"
Me.txtLoginID.SetFocus
Exit Sub
End If
If IsNull(Me.txtPassword) Or Me.txtPassword = "" Then
MsgBox "Enter Password.....", vbInformation, "Whiz Alert!"
Me.txtPassword.SetFocus
Exit Sub
End If
strSQL = "SELECT UserID FROM User WHERE LoginID = """ & Me.txtLoginID.Value & """ AND Password = """ & Me.txtPassword.Value & """"
Set db = CurrentDb
Set rst = db.OpenRecordset(strSQL)
If rst.EOF Then
MsgBox "Incorrect Username/Password.", vbCritical, "Login Error"
Me.txtLoginID.SetFocus
Else
DoCmd.Close acForm, "Index", acSaveYes
DoCmd.OpenForm "HomePage", acNormal, , , , acWindowNormal
DoCmd.Close acForm, "UserLoginForm", acSaveYes
End If
Set db = Nothing
Set rst = Nothing
End Sub
Private Sub txtLoginID_AfterUpdate()
strUserID = Me.txtLoginID
End Sub
Welcome form Code
Private Sub Form_Current()
Me.txtUser = UserLoginForm.strUserID
End Sub
I would move the login operation to a separate function and act according to the return value.
A simple login method which returns True if login was successful, or False if it wasn't. No need to open a recordset here, a simple DCount() will do.
Public Function TryToLogin(ByVal Username As Variant, ByVal Password As Variant) As Boolean
On Error GoTo Trap
'validation
Select Case True
Case IsNull(Username):
MsgBox "Enter user Name.....", vbInformation, "Whiz Alert!"
GoTo Leave
Case IsNull(Password):
MsgBox "Enter Password.....", vbInformation, "Whiz Alert!"
GoTo Leave
End Select
'credentials correct?
If DCount("UserID", "User", "LoginID='" & Username & "' AND Password='" & Password & "'") = 0 Then
MsgBox "Incorrect Username/Password.", vbExclamation, "Login Error"
GoTo Leave
End If
'login successful
TryToLogin = True
Leave:
On Error GoTo 0
Exit Function
Trap:
MsgBox Err.Description, vbCritical
Resume Leave
End Function
The method (I assume a button click event) to call the login function. Check the return value and act based on it. If successful, you can pass the Username using the form's OpenArgs parameter. I presume the welcome form is the homepage?
Private Sub Button_Click()
If Not TryToLogin(txtLoginID.Value, txtPassword.Value) Then Exit Sub
With DoCmd
.Close acForm, "Index", acSaveYes
.OpenForm "HomePage", acNormal, , , , acWindowNormal, txtLoginID.Value
.Close acForm, "UserLoginForm", acSaveYes
End With
End Sub
Lastly, handle the OpenArgs in the welcome form's Load() event.
Private Sub Form_Load()
If Not IsNull(OpenArgs) Then
'the OpenArgs now holds the username.
End If
End Sub
I have taken a macro that was embedded and converted it into vba so I can call it on different forms when needed. The form I am using is an employee list form and I am using it on the first name. I have tried calling the function by putting =MyFunction() and I get the object is closed or doesn't exist.
It works as an embedded macro; however, when I try to use it as a standalone I get an error and when I converted it I get the above error.
Function Copy_Of_CompID_Fields()
On Error GoTo Copy_Of_CompID_Fields_Err
With CodeContextObject
On Error Resume Next
If (Eval("[Forms].[Dirty]")) Then
DoCmd.RunCommand acCmdSaveRecord
End If
If (.MacroError.Number <> 0) Then
Beep
MsgBox .MacroError.Description, vbOKOnly, ""
Exit Function
End If
On Error GoTo 0
If (IsNull(.New_Id)) Then
Exit Function
End If
If (.CreatedDate < #5/1/2019#) Then
DoCmd.OpenForm "Employee Details", acNormal, "", "[ID]='" & .ID & "'", , acNormal
Else
DoCmd.OpenForm "Employee Details", acNormal, "", "[New_Id]=" & .ID, , acNormal
End If
TempVars.Add "CurrentID", .ID
DoCmd.Requery ""
DoCmd.SearchForRecord , "", acFirst, "[ID]='" & TempVars!CurrentID & "'"
TempVars.Remove "CurrentID"
End With
Copy_Of_CompID_Fields_Exit:
Exit Function
Copy_Of_CompID_Fields_Err:
MsgBox Error$
Resume Copy_Of_CompID_Fields_Exit
End Function
In a form, create a new record, edit some data but before saving it use a combo box on the form to select another record to navigate to. This triggers the cboSalePicker_AfterUpdate. Then during this sub Form_BeforeUpdate executes. The user clicks no on the MsgBox to not save the new record. Then the rest of cboSalePicker_AfterUpdate is executed however the following error message is displayed:
Error Message
Error number -2147417848: Method ‘FindFirst’ of object ‘Recordset2’ failed.
Associated with the line Me.Recordset.FindFirst "[SaleID] = " & Str(Nz(cboSalePicker.Value, 0))
However, if the new record is saved no error is produced and the code performs as expected.
Form_BeforeUpdate
Private Sub Form_BeforeUpdate(Cancel As Integer)
On Error GoTo ErrorHandler
Dim strMsg As String
Dim iResponse As Integer
'Specify the mesage to display
strMsg = "Do you wish to save the changes?" & Chr(10)
strMsg = strMsg & "Click Yes to Save or No to Discard changes."
'Display the msg box
iResponse = MsgBox(strMsg, vbQuestion + vbYesNo, "Save Record?")
'Check response
If iResponse = vbNo Then
'Undo the change.
DoCmd.RunCommand acCmdUndo
'Cancel the update
Cancel = True
End If
Exit Sub
ErrorHandler:
MsgBox "Error number " & Err.Number & ": " & Err.Description
End Sub
cboSalePicker_AfterUpdate
Private Sub cboSalePicker_AfterUpdate()
On Error GoTo ErrorHandler
Me.Recordset.FindFirst "[SaleID] = " & Str(Nz(cboSalePicker.Value, 0))
Exit Sub
ErrorHandler:
MsgBox "Error number " & Err.Number & ": " & Err.Description
End Sub
Thanks
You are converting Your SaleID into a String using this
Str(Nz(cboSalePicker.Value, 0))
But your find first is looking for a number. If SaleID is a number then remove the Str() function from your code around the combobox value.
To show the concatenation try this
Private Sub cboSalePicker_AfterUpdate()
On Error GoTo ErrorHandler
Dim sCriteria as String
sCriteria = "[SaleID] = " & Nz(Me.cboSalePicker, 0)
debug.print sCriteria
Me.Recordset.FindFirst sCriteria
Exit Sub
ErrorHandler:
MsgBox "Error number " & Err.Number & ": " & Err.Description
End Sub
Comment out the first error handler line whilst you are debugging things.
I'm trying to make a Excel 2007 vba code to select a sheet using userform. While testing, I'm getting 'Subscript out of range' Error if I input a sheetname which is not there in workbook. my code is below.
Private Sub Okbtn_Click()
sheetname = Me.ComboBox1.Value
If sheetname = "" Then
Unload Me
MsgBox "Sheet Name not enetered", vbExclamation, "Hey!"
Exit Sub
End If
ThisWorkbook.Sheets(sheetname).Activate 'Error points here!!
On Error GoTo errmsg
'If Error.Value = 9 Then GoTo errmsg
Unload Me
MsgBox "Now you are in sheet: " & sheetname & "!", vbInformation, "Sheet Changed"
errmsg:
MsgBox ("Sheet name not found in " & ThisWorkbook.Name & " !")
End Sub
The error is in ThisWorkbook.Sheets(sheetname).Activate . I tried to put some error handing tricks before and after the problem line, but Im getting the same error-9.
Im very new to coding. I think I explained the problem correctly. I want to avoid the error from popping up, but should show a customized message instead.
If you move your On Error GoTo errmsg code line above the worksheet activation, the error should be handled by the error trap routine. You just need to exit the sub before reaching the same routine if successful.
On Error GoTo errmsg
ThisWorkbook.Sheets(sheetname).Activate 'Error points here!!
Unload Me
MsgBox "Now you are in sheet: " & sheetname & "!", vbInformation, "Sheet Changed"
Exit Sub
errmsg:
MsgBox ("Sheet name not found in " & ThisWorkbook.Name & " !")
End Sub
You need to set the error handler before executing the instruction that might cause an error. Something like this
Private Sub Okbtn_Click()
sheetname = Me.ComboBox1.Value
If sheetname = "" Then
Unload Me
MsgBox "Sheet Name not enetered", vbExclamation, "Hey!"
Exit Sub
End If
On Error GoTo errmsg
ThisWorkbook.Sheets(sheetname).Activate 'Error points here!!
'If Error.Value = 9 Then GoTo errmsg
Unload Me
MsgBox "Now you are in sheet: " & sheetname & "!", vbInformation, "Sheet Changed"
Exit Sub ' Avoid executing handler code when ther is no error
errmsg:
MsgBox ("Sheet name not found in " & ThisWorkbook.Name & " !")
End Sub
put On Error GoTo errmsg above ThisWorkbook.Sheets(sheetname).Activate
'''''
On Error GoTo errmsg
ThisWorkbook.Sheets(sheetname).Activate
'''''
error handling always must be before the line where you can receive the error
It would be clearer if you error handling was wrapped around a single line testing if the worksheet existed
As an example your current code will flag any error - such as the sheet being hidden - as the sheet not existing.
Private Sub Okbtn_Click()
Dim strSht As String
Dim ws As Worksheet
strSht = Me.ComboBox1.Value
If Len(strSht) = 0 Then
Unload Me
MsgBox "Sheet Name not entered", vbExclamation, "Hey!"
Exit Sub
End If
On Error Resume Next
Set ws = ThisWorkbook.Sheets(strSht)
On Error GoTo 0
If Not ws Is Nothing Then
If ws.Visible Then
Application.Goto ws.[a1]
MsgBox "Now you are in sheet: " & strSht & "!", vbInformation, "Sheet Changed"
Else
MsgBox ("Sheet exists but is hidden")
End If
Else
MsgBox ("Sheet name not found in " & ThisWorkbook.Name & " !")
End If
End Sub