Error 424 Object needed - Cant seem to find the error - vba

i am farly new to VBa and am trying to learn by building or replicating existing vba sheets.
In this one, i am getting an error in the following code:
Private Sub lstLookup_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
'declare the variables
Dim cPayroll As String
Dim I As Integer
Dim findvalue
'error block
On Error GoTo errHandler:
'get the select value from the listbox
For I = 0 To lstLookup.ListCount - 1
If lstLookup.Selected(I) = True Then
cPayroll = lstLookup.List(I, 1)
End If
Next I
'find the payroll number
Set findvalue = Sheet2.Range("F:F").Find(What:=cPayroll, LookIn:=xlValues).Offset(0, -3)
'add the database values to the userform
cNum = 21
For X = 1 To cNum
Me.Controls("Reg" & X).Value = findvalue
Set findvalue = findvalue.Offset(0, 1)
Next
'disable adding
Me.cmdAdd.Enabled = False
Me.cmdEdit.Enabled = True
'error block
On Error GoTo 0
Exit Sub
errHandler::
MsgBox "An Error has Occurred " & vbCrLf & "The error number is: " _
& Err.Number & vbCrLf & Err.Description & vbCrLf & _
"Please notify the administrator"
End Sub
It is giving me the error :" 424 Object required"
i cant seem to find the error
Can someone help me?
Thanks in advance.

Change
Me.cmdAdd.Enabled = False
Me.cmdEdit.Enabled = True
to
Me.Controls("cmdAdd").Enabled = False
Me.Controls("cmdEdit").Enabled = True

Related

VBA Array error

I have the following code which uses two for loops (Prod and Dev)
There are many values in the array but i have taken only two for the example
What it does is, it copies the value from one excel to the other.
Now, there is a probability that file NSA_103_B_Roles.xls doesnot exist
In that case, i dont want the code to take any action, so i have put on error resume next
But still it is printing the value in the excel which doesnot exist,
What is the reason?
Private Sub CommandButton1_Click()
Prod = Array("ZS7_656", "PCO_656")
Dev = Array("NSA_103", "DCA_656")
For lngCounter1 = LBound(Dev) To UBound(Dev)
For lngCounter = LBound(Prod) To UBound(Prod)
On Error Resume Next
Set Zz2 = Workbooks.Open("C:\Users\*****\Desktop\New folder\" &
Dev(lngCounter1) & "_B_Roles.xls")
Zz2.Sheets(Dev(lngCounter1) & "_B_Roles").Range("A1").Value = "anirudh"
ThisWorkbook.Sheets(Prod(lngCounter)).Range("A2").Value =
Zz2.Sheets(Dev(lngCounter1) & "_B_Roles").Range("A1").Value
On Error GoTo 0
Next lngCounter
Next lngCounter1
End Sub
Try the code below, explanation inside the code's comments :
Private Sub CommandButton1_Click()
Dim Zz2 As Workbook
Prod = Array("ZS7_656", "PCO_656")
Dev = Array("NSA_103", "DCA_656")
For lngCounter1 = LBound(Dev) To UBound(Dev)
For lngCounter = LBound(Prod) To UBound(Prod)
' ==== this section starts the error handling ===
On Error Resume Next
Set Zz2 = Workbooks.Open("C:\Users\*****\Desktop\New folder\" & _
Dev(lngCounter1) & "_B_Roles.xls")
On Error GoTo 0
If Zz2 Is Nothing Then ' <-- unable to find the file
MsgBox "unable to find the specified file", vbCritical
Exit Sub
End If
' === Up to Here ===
Zz2.Sheets(Dev(lngCounter1) & "_B_Roles").Range("A1").Value = "anirudh"
ThisWorkbook.Sheets(Prod(lngCounter)).Range("A2").Value = Zz2.Sheets(Dev(lngCounter1) & "_B_Roles").Range("A1").Value
Next lngCounter
Next lngCounter1
End Sub

Selecting multiple cells

I have this code that check if the attachment size of the attachment is greater than 10MB. Now, if the attachment is greater than 10MB, it displays the file names on a msgbox then I want to select or highlight the cells that has this attachment greater than 10 MB but dunno how to do it.
Here's what I've tried:
Function checkAttSize()
Application.ScreenUpdating = False
Dim attach As Object
Dim attSize() As String
Dim loc() As String
Dim num As Long
Dim rng As Range
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
Set main = ThisWorkbook.Sheets("Main")
lRow = Cells(Rows.count, 15).End(xlUp).Row
efCount = 0
num = 0
With objMail
If lRow > 22 Then
On Error GoTo errHandler
For i = 23 To lRow
'attach.Add main.Range("O" & i).value
'totalSize = totalSize +
If (FileLen(main.Cells(i, "O").value) / 1000000) > 10 Then
ReDim Preserve attSize(efCount)
ReDim Preserve loc(num)
'store file names
attSize(efCount) = Dir(main.Range("O" & i))
'store cell address
loc(num) = i
efCount = efCount + 1
num = num + 1
found = True
End If
Next i
End If
End With
If found = True Then
MsgBox "Following File(s) Exceeds 10MB Attachment Size Limit:" & vbCrLf & vbCrLf & Join(attSize, vbCrLf) _
& vbCrLf & vbCrLf & "Please try removing the file(s) and try again.", vbCritical, "File Size Exceed"
'trying to select the cell addresses
For i = 1 To num
rng = rng + main.Range("O" & loc(i)).Select ' Ive also tried &
Next i
checkAttSize = True
Exit Function
End If
Exit Function
errHandler:
MsgBox "Unexpected Error Occured.", vbCritical, "Error"
checkAttSize = True
End Function
Thanks for the help.
No need to select the range. A single miss click by the user take take the focus away from the range. Also using .Select recklessly may cause run time errors. Color them instead.
After this line
If (FileLen(main.Cells(i, "O").value) / 1000000) > 10 Then
Add this line
main.Cells(i, "O").Interior.ColorIndex = 3
The cells now will be colored in red.
And in the end, alert the user with the message
If found = True Then
MsgBox "File(s) Exceeding 10MB Attachment Size Limit has been colored in red:"
End If

Access VBA: Discard "can't append" message (Primary Key Violation)

I'm trying to create a macro in Access 2010 that opens an excel file, runs the macro in excel and then imports the given results. I have 2 problems with this process.
Application.DisplayAlerts = False in Excel
Nevertheless DisplayAlerts keep popping up. Do I need to do something special in the macro Access?
Alert "Can't append due to primary key violations" keeps popping up. I know what the problem is, but I want to ignore it. I can use On Error Resume? But I want a at the end a messagebox with the the table it hasn't append to. Is this possible and can you point me in the right direction. I already tried some errorhandeling but i don't know how to make the message popup at the end without interrupting the process.
code:
Private Sub Main_btn_Click()
Dim fileImport(0 To 3, 0 To 2) As String
fileImport(0, 0) = "Stock_CC"
fileImport(0, 1) = "F:\370\Hyperviseur\SITUATIE\Macro\Stock_getdata.xlsm"
fileImport(0, 2) = "GetStock"
fileImport(1, 0) = "Wips_CC"
fileImport(1, 1) = "F:\370\Hyperviseur\SITUATIE\Macro\Wips_getdata.xlsm"
fileImport(1, 2) = "Update"
fileImport(2, 0) = "CCA_cc"
fileImport(2, 1) = "F:\370\Hyperviseur\SITUATIE\Macro\SLAcc.xls"
fileImport(2, 2) = "Read_CCA"
fileImport(3, 0) = "Eps_cc"
fileImport(3, 1) = "F:\370\Hyperviseur\SITUATIE\Macro\eps.xlsm"
fileImport(3, 2) = "Update"
Dim i As Integer
For i = 0 To UBound(fileImport, 1)
RunMacroInxcel fileImport(i, 1), fileImport(i, 2)
transferSpreadsheetFunction fileImport(i, 0), fileImport(i, 1)
Next i
End Sub
Private Sub RunMacroInExcel(fName As String, macroName As String)
Dim Xl As Object
'Step 1: Start Excel, then open the target workbook.
Set Xl = CreateObject("Excel.Application")
Xl.Workbooks.Open (fName)
Xl.Visible = True
Xl.Run (macroName)
Xl.ActiveWorkbook.Close (True)
Xl.Quit
Set Xl = Nothing
End Sub
Private Sub transferSpreadsheetFunction(ByVal tableName As String, ByVal fileName As String)
If FileExist(fileName) Then
DoCmd.TransferSpreadsheet acImport, , tableName, fileName, True
Else
Dim Msg As String
Msg = "Bestand niet gevonden" & Str(Err.Number) & Err.Source & Err.Description
MsgBox (Msg)
End If
End Sub
Function FileExist(sTestFile As String) As Boolean
Dim lSize As Long
On Error Resume Next
lSize = -1
lSize = FileLen(sTestFile)
If lSize > -1 Then
FileExist = True
Else
FileExist = False
End If
End Function
Add error handling within the For Loop, concatenate to a string variable, then message box the string:
Dim i As integer, failedFiles as string
failedFiles = "List of failed tables: " & vbNewLine & vbNewLine
For i = 0 To UBound(fileImport, 1)
On Error Goto NextFile
Call RunMacroInxcel(fileImport(i, 1), fileImport(i, 2))
Call transferSpreadsheetFunction(fileImport(i, 0), fileImport(i, 1))
NextFile:
failedFiles = failedFiles & " " & fileImport(i,0) & vbNewLine
Resume NextFile2
NextFile2:
Next i
MsgBox failedFiles, vbInformation, "Failed Tables List"

VB - Subscript out of range, error 9

**I am new to VB and I received and error 9, subscript out of range. The error indicated it was in the below procedure. Please let me know what might be the issue. I appreciate your assistance
Private Sub RebuildGrid()
Const c_strProcedureName As String = "RebuildGrid"
Dim intIndex As Integer
On Error GoTo Error_Handler
For intIndex = 0 To g_intNumNucDataFields - 1
grdNuclides.Columns(intIndex).DataField = ga_strNucFieldName(intIndex)
grdNuclides.Columns(intIndex).Visible = False
If StrComp(ga_strNucFieldFormat(intIndex), "None", vbTextCompare) <> 0 Then
grdNuclides.Columns(intIndex).NumberFormat = ga_strNucFieldFormat(intIndex)
End If
grdNuclides.Columns(intIndex).Width = 1400
If StrComp(LCase$(ga_strNucFieldUnits(intIndex)), "none", vbTextCompare) = 0 Then
grdNuclides.Columns(intIndex).Caption = ga_strNucFieldTitle(intIndex)
Else
grdNuclides.Columns(intIndex).Caption = ga_strNucFieldTitle(intIndex) & _
" " & vbCr & "(" & ga_strNucFieldUnits(intIndex) & ") "
End If
grdNuclides.Columns(intIndex).FooterText = "Reference"
Next intIndex
Exit Sub
Error_Handler:
gud_PrgErr.Number = Err.Number
gud_PrgErr.Severity = 5
gud_PrgErr.Description = Err.Description
gud_PrgErr.Module = c_strModuleName
gud_PrgErr.Procedure = c_strProcedureName
Call Display_UI_Error
End Sub
Private Sub mnuFileExit_Click()
Unload Me
End Sub
Make sure g_intNumNucDataFields is not higher than the number of columns (eg grdNuclides.Columns.Count).
You could also try commenting out the error handling and then running it to see if you get a line number on the error.

vba error handling in loop

New to vba, trying an 'on error goto' but, I keep getting errors 'index out of range'.
I just want to make a combo box that is populated by the names of worksheets which contain a querytable.
For Each oSheet In ActiveWorkbook.Sheets
On Error GoTo NextSheet:
Set qry = oSheet.ListObjects(1).QueryTable
oCmbBox.AddItem oSheet.Name
NextSheet:
Next oSheet
I'm not sure whether the problem is related to nesting the On Error GoTo inside a loop, or how to avoid using the loop.
The problem is probably that you haven't resumed from the first error. You can't throw an error from within an error handler. You should add in a resume statement, something like the following, so VBA no longer thinks you are inside the error handler:
For Each oSheet In ActiveWorkbook.Sheets
On Error GoTo NextSheet:
Set qry = oSheet.ListObjects(1).QueryTable
oCmbBox.AddItem oSheet.Name
NextSheet:
Resume NextSheet2
NextSheet2:
Next oSheet
As a general way to handle error in a loop like your sample code, I would rather use:
on error resume next
for each...
'do something that might raise an error, then
if err.number <> 0 then
...
end if
next ....
How about:
For Each oSheet In ActiveWorkbook.Sheets
If oSheet.ListObjects.Count > 0 Then
oCmbBox.AddItem oSheet.Name
End If
Next oSheet
Actualy the Gabin Smith's answer needs to be changed a bit to work, because you can't resume with without an error.
Sub MyFunc()
...
For Each oSheet In ActiveWorkbook.Sheets
On Error GoTo errHandler:
Set qry = oSheet.ListObjects(1).QueryTable
oCmbBox.AddItem oSheet.name
...
NextSheet:
Next oSheet
...
Exit Sub
errHandler:
Resume NextSheet
End Sub
There is another way of controlling error handling that works well for loops. Create a string variable called here and use the variable to determine how a single error handler handles the error.
The code template is:
On error goto errhandler
Dim here as String
here = "in loop"
For i = 1 to 20
some code
Next i
afterloop:
here = "after loop"
more code
exitproc:
exit sub
errhandler:
If here = "in loop" Then
resume afterloop
elseif here = "after loop" Then
msgbox "An error has occurred" & err.desc
resume exitproc
End if
I do not want to craft special error handlers for every loop structure in my code so I have a way of finding problem loops using my standard error handler so that I can then write a special error handler for them.
If an error occurs in a loop, I normally want to know about what caused the error rather than just skip over it. To find out about these errors, I write error messages to a log file as many people do. However writing to a log file is dangerous if an error occurs in a loop as the error can be triggered for every time the loop iterates and in my case 80 000 iterations is not uncommon. I have therefore put some code into my error logging function that detects identical errors and skips writing them to the error log.
My standard error handler that is used on every procedure looks like this. It records the error type, procedure the error occurred in and any parameters the procedure received (FileType in this case).
procerr:
Call NewErrorLog(Err.number, Err.Description, "GetOutputFileType", FileType)
Resume exitproc
My error logging function which writes to a table (I am in ms-access) is as follows. It uses static variables to retain the previous values of error data and compare them to current versions. The first error is logged, then the second identical error pushes the application into debug mode if I am the user or if in other user mode, quits the application.
Public Function NewErrorLog(ErrCode As Variant, ErrDesc As Variant, Optional Source As Variant = "", Optional ErrData As Variant = Null) As Boolean
On Error GoTo errLogError
'Records errors from application code
Dim dbs As Database
Dim rst As Recordset
Dim ErrorLogID As Long
Dim StackInfo As String
Dim MustQuit As Boolean
Dim i As Long
Static ErrCodeOld As Long
Static SourceOld As String
Static ErrDataOld As String
'Detects errors that occur in loops and records only the first two.
If Nz(ErrCode, 0) = ErrCodeOld And Nz(Source, "") = SourceOld And Nz(ErrData, "") = ErrDataOld Then
NewErrorLog = True
MsgBox "Error has occured in a loop: " & Nz(ErrCode, 0) & Space(1) & Nz(ErrDesc, "") & ": " & Nz(Source, "") & "[" & Nz(ErrData, "") & "]", vbExclamation, Appname
If Not gDeveloping Then 'Allow debugging
Stop
Exit Function
Else
ErrDesc = "[loop]" & Nz(ErrDesc, "") 'Flag this error as coming from a loop
MsgBox "Error has been logged, now Quiting", vbInformation, Appname
MustQuit = True 'will Quit after error has been logged
End If
Else
'Save current values to static variables
ErrCodeOld = Nz(ErrCode, 0)
SourceOld = Nz(Source, "")
ErrDataOld = Nz(ErrData, "")
End If
'From FMS tools pushstack/popstack - tells me the names of the calling procedures
For i = 1 To UBound(mCallStack)
If Len(mCallStack(i)) > 0 Then StackInfo = StackInfo & "\" & mCallStack(i)
Next
'Open error table
Set dbs = CurrentDb()
Set rst = dbs.OpenRecordset("tbl_ErrLog", dbOpenTable)
'Write the error to the error table
With rst
.AddNew
!ErrSource = Source
!ErrTime = Now()
!ErrCode = ErrCode
!ErrDesc = ErrDesc
!ErrData = ErrData
!StackTrace = StackInfo
.Update
.BookMark = .LastModified
ErrorLogID = !ErrLogID
End With
rst.Close: Set rst = Nothing
dbs.Close: Set dbs = Nothing
DoCmd.Hourglass False
DoCmd.Echo True
DoEvents
If MustQuit = True Then DoCmd.Quit
exitLogError:
Exit Function
errLogError:
MsgBox "An error occured whilst logging the details of another error " & vbNewLine & _
"Send details to Developer: " & Err.number & ", " & Err.Description, vbCritical, "Please e-mail this message to developer"
Resume exitLogError
End Function
Note that an error logger has to be the most bullet proofed function in your application as the application cannot gracefully handle errors in the error logger. For this reason, I use NZ() to make sure that nulls cannot sneak in. Note that I also add [loop] to the second identical error so that I know to look in the loops in the error procedure first.
What about?
If oSheet.QueryTables.Count > 0 Then
oCmbBox.AddItem oSheet.Name
End If
Or
If oSheet.ListObjects.Count > 0 Then
'// Source type 3 = xlSrcQuery
If oSheet.ListObjects(1).SourceType = 3 Then
oCmbBox.AddItem oSheet.Name
End IF
End IF