vba error number 9 subscript out of range - vba

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

Related

MS Access: Trying to create an error if there is a duplicate record but code flags everything

I have a form that if a duplicate record is entered, the form creates an error message and prevents the record from being entered. However, my code is popping up the error message no matter what I'm putting in. My code is this...
Private Sub cmdSave_Click()
' ToDo fix the labels in this function so they match the function name. Just cosmetic.
On Error GoTo Add_CmdSave_Click_Err
On Error Resume Next
' ToDo fix the labels in this function so they match the function name. Just cosmetic.
On Error GoTo Add_CmdSave_Click_Err
On Error Resume Next
Me.cbCompletedTrainingID = Me.IntermediateID
'
Dim OKToSave As Boolean
OKToSave = True
If Not SomethingIn(Me.[fIntermediate FacultyID]) Then ' Null
Beep
MsgBox "A faculty member is required", vbOKOnly, "Missing Information"
OKToSave = False
End If
If Not SomethingIn(Me.[fIntermediate TrainingID]) Then
Beep
MsgBox "A training is required", vbOKOnly, "Missing Information"
OKToSave = False
Else
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
If Not rs.EOF Then
Beep
MsgBox "This person has already completed this training", vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
End If
If OKToSave Then
' If we get this far, all data is valid and it's time to save
Me.Dirty = False
DoCmd.GoToRecord , "", acNewRec
End If
Add_CmdSave_Click_Exit:
Exit Sub
Add_CmdSave_Click_Err:
Resume Add_CmdSave_Click_Exit
End Sub
The issue, from my standpoint, lies in this part...
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
If Not rs.EOF Then
Beep
MsgBox "This person has already completed this training", vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
What am I doing wrong?
Have a look at How to debug dynamic SQL in VBA.
This line makes no sense as it is:
rs.FindFirst "[IntermediateID] = " & Me.[fIntermediate FacultyID] And Me.[fIntermediate TrainingID]
You probably want something like
S = "[IntermediateID] = " & Me.[fIntermediate FacultyID] & " And [TrainingID] = " & Me.[fIntermediate TrainingID]
Debug.Print S ' Ctrl+G shows the output
rs.FindFirst S
Also, remove all these On Error Resume Next - this will happily ignore any errors, making debugging nearly impossible.
Also useful: Debugging VBA Code
And there is more: If Recordset.FindFirst doesn't find a match, it doesn't trigger .EOF. It sets the .NoMatch property.
rs.FindFirst S
If rs.NoMatch Then
' all is good, proceed to save
Else
' record exists
End If
This should work as intended:
Dim rs As DAO.Recordset
Dim Criteria As String
Set rs = Me.RecordsetClone
Criteria = "[IntermediateID] = " & Me![fIntermediate FacultyID].Value & " And [TrainingID] = " & Me![fIntermediate TrainingID].Value & ""
Debug.Print OKToSave, Criteria
rs.FindFirst Criteria
If Not rs.NoMatch Then
Beep
MsgBox "This person has already completed this training", vbInformation + vbOKOnly, "Duplicate Training Completion"
OKToSave = False
End If
rs.Close
Debug.Print OKToSave

Method ‘FindFirst’ of object ‘Recordset2’ failed. After not saving new record

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.

Code that checks if an excel file is open works on one computer (user), but will it work with more computers (users)?

The following code checks if file is open, if not, it opens it and copies something into it. It works fine on my computer. Will it work, when the file is shared and another user opens the file? Will my code detect it?
Sub copy_to_boss()
On Error Resume Next
team = "boss.xlsm"
Set fileBoss = Workbooks(team)
fileIsOpen = Not fileBoss Is Nothing
If fileIsOpen = True Then
MsgBox "The following file is open " & team & " - close it."
Else
MsgBox "I will open the following file " & team
Workbooks.Open Filename:=team
ActiveWorkbook.Worksheets("List1").Cells(1, 1).Value = "10"
End If
End Sub
Try this:
Sub test_LockFile()
Dim sFile As String
Dim sLockFile As String
Dim objFSO As Object
'Trick: Each Excel file in use has a temporary file companion with prefix "~$"
' (e.g. "test.xlsm" ... "$~test.xlsm")
'Define sLockFile
sFile = ThisWorkbook.Name
sLockFile = ThisWorkbook.Path & "\~$" & sFile
'FileSystemObject, late Binding ohne Nutzung von IntelliSense und autom. Konstanten
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Show message if file is locked
If objFSO.FileExists(sLockFile) Then
MsgBox "The file " & sLockFile & " is locked by some user.", vbInformation, sFile & " is locked"
Else
MsgBox "The file is available", vbInformation, sFile
End If
End Sub
You can use something like this to check if the file is in use:
Public Function IsFileLocked(PathName As String) As Boolean
On Error GoTo ErrHandler
Dim i As Integer
If Len(Dir$(PathName)) Then
i = FreeFile()
Open PathName For Random Access Read Write Lock Read Write As #i
Lock i 'Redundant but let's be 100% sure
Unlock i
Close i
Else
Err.Raise 53
End If
ExitProc:
On Error GoTo 0
Exit Function
ErrHandler:
Select Case Err.Number
Case 70 'Unable to acquire exclusive lock
IsFileOpen = True
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ")"
End Select
Resume ExitProc
Resume
End Function

Export specific information from Access 2016 to a Word document that is already created

I am trying to export data from a Access 2016 Form to a Word document. Here is the code I'm using.
Public Function doWordAutomation()
On Error GoTo doWordAutomationErr
Dim objWordDoc As Word.Document
Dim objWord As Word.Application
Dim sDocument As String
sDocument = Application.CurrentProject.Path & "C:Desktop\No Notary Legal Dispatch Affidavit Fill.doc"
Set objWord = CreateObject("Word.Application")
Set objWordDoc = objWord.Documents.Open(Application.CurrentProject.Path & "\C:\Desktop\No Notary Legal Dispatch Affidavit Fill.doc")
If (sDocument) Then
Kill sDocument
End If
objWordDoc.SaveAs sDocument
With objWordDoc.Bookmarks
If .Exists("Cause") Then
.Item("Cause").Range.Text = "Cause"
If .Exists("Plaintiff") Then
.Item("Plaintiff").Range.Text = "Plaintiff"
If .Exists("Court") Then
.Item("Court").Range.Text = "Court"
If .Exists("County") Then
.Item("County").Range.Text = "County"
If .Exists("State") Then
.Item("State").Range.Text = "State"
If .Exists("Defendant") Then
.Item("Defendant").Range.Text = "Defendant"
If .Exists("Documents") Then
.Item("Documents").Range.Text = "Documents"
If .Exists("NameforService") Then
.Item("NameforService").Range.Text = "NameforService"
If .Exists("ServiceAddress") Then
.Item("ServiceAddress").Range.Text = "ServiceAddress"
If .Exists("ResultTime") Then
.Item("ResultTime").Range.Text = "ResultTime"
If .Exists("ResultDate") Then
.Item("ResultDate").Range.Text = "ResultDate"
End If
End
objWordDoc.Save
objWordDoc.Close
doWordAutomationExit:
Exit Function
doWordAutomationErr:
MsgBox Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
Resume doWordAutomationExit
End Function
I have created a button in my form and attached this code to it but when I try to use it nothing happens. Any help that you can give will be greatly appreciated.
Private Sub cmdPrint_Click()
'Print customer slip for current customer.
Dim appWord As Word.Application
Dim doc As Word.Document
'Avoid error 429, when Word isn’t open.
On Error Resume Next
Err.Clear
'Set appWord object variable to running instance of Word.
Set appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn’t open, create a new instance of Word.
Set appWord = New Word.Application
End If
Set doc = appWord.Documents.Open("C:C:Desktop\No Notary Legal Dispatch Affidavit Fill.doc", , True)
With doc
.FormFields("Cause").Result = Me!Cause
.FormFields("Plaintiff").Result = Me!Plaintiff
.FormFields("Court").Result = Me!Court
.FormFields("County").Result = Me!County
.FormFields("State").Result = Me!State
.FormFields("Defendant").Result = Me!Defendant
.FormFields("Documents").Result = Me!Documents
.FormFields("NameforService").Result = Me!NameforService
.FormFields("ServiceAddress").Result = Me!ServiceAddress
.FormFields("ResultTime").Result = Me!ResultTime
.FormFields("ResultDate").Result = Me!ResultDate
.Visible = True
.Activate
End With
Set doc = Nothing
Set appWord = Nothing
Exit Sub
errHandler:
MsgBox Err.Number & ": " & Err.Description
End Sub
I have created bookmarks in a Word document that I'm wanting to export the form information into. Neither code I used worked for me so any help would be greatly appreciated.
For some reason, it is still not working. I don't know if it is the button that I have put in the form, which is a command76 button. I know that's not the exact right button I need to export but it's the closest one I see that I'm able to use. I have attached the access document and word document that I'm trying to use. The Word form with bookmarks Word Document and the Access Form Access Document have been linked here. Thanks again in advance for your help. Attached are two of the documents I'm trying to use.
Now that you have shared the document and names, I changed the code to use the data from your form. You may need to tweak the document spacing or the data you insert. Let me know how it goes.
Also, I suggest you clean up this thread by deleting the unnecessary descriptions and comments.
Option Compare Database
Option Explicit
Private Sub Command75_Click()
Export_Form_Data_To_Word
End Sub
Public Function Export_Form_Data_To_Word()
Dim objWordDoc As Word.Document
Dim objWord As Word.Application
Dim objRange As Word.Range
Dim sPath As String
Dim sFileName As String
Dim sSaveAs As String
Dim sDocument As String
Dim i As Integer
On Error GoTo Error_Trap
' For my testing....
'sPath = "C:\temp\" '
'sFileName = "NoNotaryLegalDispatchAffidavitFill.docx" '
sPath = "C:\Users\Josh Panger\Desktop" '
sFileName = "No Notary Legal Dispatch Affidavit Fill.docx" '
i = InStrRev(sFileName, ".doc") '
' Create a new file name
sSaveAs = Left(sFileName, i - 1) & "_" & Format(Now(), "YYYYMMDD_HHMMSS") & Mid(sFileName, i)
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objWordDoc = objWord.Documents.Open(sPath & sFileName)
With objWordDoc.Bookmarks
If .Exists("Cause") Then
objWordDoc.Bookmarks("Cause").Range.InsertAfter Me.Cause
Else
MsgBox "Bookmark: 'Cause' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Plaintiff") Then
objWordDoc.Bookmarks("Plaintiff").Range.InsertAfter Me.Plaintiff & ", Plaintiff"
Else
MsgBox "Bookmark: 'Plaintiff' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Defendant") Then
objWordDoc.Bookmarks("Defendant").Range.InsertAfter Me.Defendant & ", Defendant"
Else
MsgBox "Bookmark: 'Defendant' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Court") Then
objWordDoc.Bookmarks("Court").Range.InsertAfter Me.Count
Else
MsgBox "Bookmark: 'Court' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("County") Then
objWordDoc.Bookmarks("County").Range.InsertAfter Me.County
Else
MsgBox "Bookmark: 'County' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("State") Then
objWordDoc.Bookmarks("State").Range.InsertAfter "My State"
Else
MsgBox "Bookmark: 'State' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("Documents") Then
objWordDoc.Bookmarks("Documents").Range.InsertAfter Me.Documents
Else
MsgBox "Bookmark: 'Documents' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("NameforService") Then
objWordDoc.Bookmarks("NameforService").Range.InsertAfter Me.NameforService
Else
MsgBox "Bookmark: 'NameforService' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ServiceAddress") Then
objWordDoc.Bookmarks("ServiceAddress").Range.InsertAfter Me.ServiceAddress
Else
MsgBox "Bookmark: 'ServiceAddress' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ResultTime") Then
objWordDoc.Bookmarks("ResultTime").Range.InsertAfter Me.ResultTime
Else
MsgBox "Bookmark: 'ResultTime' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
If .Exists("ResultDate") Then
objWordDoc.Bookmarks("ResultDate").Range.InsertAfter Me.ResultDate
Else
MsgBox "Bookmark: 'ResultDate' does not exist in this Word Document!", vbOKOnly, "Missing Bookmark"
End If
End With
objWordDoc.SaveAs2 sPath & sSaveAs, 16
objWordDoc.Close
Exit_Code:
Exit Function
Error_Trap:
Debug.Print Err.Number & vbTab & Err.Description
If Err.Number = 5174 Then
MsgBox "The Word document can't be found at location: '" & sDocument & "'", vbOKOnly, "Missing File"
Else
MsgBox Err.Number & vbTab & Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
End If
Resume Exit_Code
Resume
End Function

VBA Excel Stop On Error Goto

I have written On Error GoTo ErrorMessage somewhere in a subroutine. I want to stop this command after End if command as shown below.
On Error GoTo ErrorMessage
Sheet2.Range("A1").Font.Bold = True
Sheet2.Range("B1").Font.Bold = True
If LastRow_Sh2 >= First_Row_Sheet2 Then
Sheet2.Range(FromCol & First_Row_Sheet2 & ":" & ToCol & LastRow_Sh2).ClearContents
Exit Sub
End If
' Stop here
' I have some codes here
ErrorMessage:
MsgBox ("Error message: The input values are invalid")
Take a look at the example below that shows both - error handling manually and allow VBA to catch a runtime error:
Sub Test()
On Error GoTo ErrorHandler
Dim Divisor As Integer
Dim Num As Integer
Dim Answer As Double
Num = 100
Divisor = 0
' ================================
' throw an error here forcefully
' and allow ErrorHandler to handle
' the error
' ================================
Answer = Num / Divisor
MsgBox "Answer is " & Answer, vbOKOnly + vbInformation, "Answer"
' stop error handling
On Error GoTo 0
' ================================
' throw an error here forcefully
' and allow VBA to handle the error
' ================================
Answer = Num / Divisor
MsgBox "Answer is " & Answer, vbOKOnly + vbInformation, "Answer"
Exit Sub
ErrorHandler:
MsgBox "Handling the error here", vbOKOnly + vbInformation, "ErrorHandler"
Resume Next
End Sub
Based on this, you can modify your code slightly to allow VBA to handle the error on runtime.
On Error GoTo ErrorMessage
Sheet2.Range("A1").Font.Bold = True
Sheet2.Range("B1").Font.Bold = True
If LastRow_Sh2 >= First_Row_Sheet2 Then
Sheet2.Range(FromCol & First_Row_Sheet2 & ":" & ToCol & LastRow_Sh2).ClearContents
Exit Sub
End If
' Stop here
' The statement below will disable error handling that was
' done by ErrorMessage
On Error GoTo 0
' I have some codes here
' If this block of code has errors, VBA will handle it and
' allow debugging
ErrorMessage:
MsgBox ("Error message: The input values are invalid")
try this
On Error Resume Next '".. GoTo ErrorMessage" replaced by "...resume next"
Sheet2.Range("A1").Font.Bold = True
Sheet2.Range("B1").Font.Bold = True
If LastRow_Sh2 >= First_Row_Sheet2 Then
Sheet2.Range(FromCol & First_Row_Sheet2 & ":" & ToCol & LastRow_Sh2).ClearContents
Exit Sub
End If
If Err.Number > 0 Then GoTo ErrorMessage ' Stop here
' I have some codes here
ErrorMessage:
MsgBox ("Error message: The input values are invalid")