Excel VBA Run time Error 424: Object Required - excel

I am totally new in VBA and coding in general, I'm trying to get data from cells from the same workbook if the condition is met to paste in another book.
I am getting this error when trying to get values entered in excel cells:
Run Time Error '424' object required
When I'm pressing the debug button it takes to the first line and highlights it. I am not able to recognize why it is happening? Also when in watch window it shows a=0.
The code is
Sub copycells()
a = ThisWorkbook.Worksheets("Sale").Cells(Row.Count, 2).End(xlUp).Row
For i = 2 To a
If Worksheets("Sale").Cells(i, 6).Value = "Parmesh" Then
Worksheets("Sale").Row(i).copy
Workbooks("Source.xlsx").Worksheets("Billdetails").Activate
b = Workbooks("Source.xlsx").Worksheets("Billdetails").Cells(Row.Count, 2).End(xlUp).Row
Workbooks("Source.xlsx").Worksheets("Billdetails").Cells(b + 1, 1).Select
ActivateSheet.Paste
Worksheets("Sale").Activate
End If
Next
Application.CutCopyMode = False
Workbooks("Purchase.xlsx").Worksheets("Sale").Cells(1, 1).Select
End Sub

Option Explicit: Your Friend
That should teach you to always use Option Explicit. If you had been using it the following might have happened (Compile error: Variable not defined):
After OK:
you see that something is wrong with Row.
After changing to Rows another Compile error: Variable not defined. After OK:
you see that something is wrong with a =.
After adding Dim a As Long another Compile error: Variable not defined. After OK:
you see that something is wrong with i.
After adding Dim i As Long another Compile error: Variable not defined. After OK:
You see something is wrong with Row again.
After changing to Rows another Compile error: Variable not defined. After OK:
you see that something is wrong with b =.
After adding Dim b As Long another Compile error: Variable not defined. After OK:
you see that something is wrong with ActivateSheet.
After changing to ActiveSheet finally a Run-time error:
and after Debug:
Row looks suspicious again.
After changing to Rows another Run-time error:
and after Debug:
you see that something is wrong with ActiveSheet.Paste, especially Paste.
After changing to ActiveSheet.PasteSpecial another Run-time error:
and after Debug:
you see something is wrong with Worksheets("Sale").Activate.
Since Source.xlsx is active you consider changing to Workbooks("Purchase.xlsx").Worksheets("Sale").Activate and everything's finally OK. Or is it?
The Code
Option Explicit
Sub copycells()
Dim a As Long
Dim b As Long
Dim i As Long
With ThisWorkbook.Worksheets("Sale")
a = .Cells(.Rows.Count, 2).End(xlUp).Row
For i = 2 To a
If .Cells(i, 6).Value = "Parmesh" Then
.Rows(i).Copy
With Workbooks("Source.xlsx").Worksheets("Billdetails")
b = .Cells(.Rows.Count, 2).End(xlUp).Row
.Cells(b + 1, 1).PasteSpecial
End With
End If
Next
' If Purchase.xlsx and ThisWorkbook are the same then use the following:
'.Cells(1).Select
End With
Application.CutCopyMode = False
' If Purchase.xlsx and ThisWorkbook are not the same then use the following:
'Workbooks("Purchase.xlsx").Worksheets("Sale").Cells(1, 1).Select
End Sub
' Assuming that you need only values and that "Thisworkbook" is "Purchase.xlsx"
Sub copyCellsValues()
Const SourceBook As String = "Source.xlsx"
Const SourceSheet As String = "Billdetails"
Const MainSheet As String = "Sale"
Const MainColumn As Long = 6
Const Criteria As String = "Parmesh"
Dim Sale As Worksheet
Dim Bill As Worksheet
Dim a As Long
Dim b As Long
Dim i As Long
Set Sale = ThisWorkbook.Worksheets(MainSheet)
Set Bill = Workbooks(SourceBook).Worksheets(SourceSheet)
a = Sale.Cells(Sale.Rows.Count, 2).End(xlUp).Row
b = Bill.Cells(Bill.Rows.Count, 2).End(xlUp).Row + 1
For i = 2 To a
If Sale.Cells(i, MainColumn).Value = Criteria Then
Bill.Rows(b).Value = Sale.Rows(i).Value
b = b + 1
End If
Next
End Sub

First of all, it seems you need to declare missed variable:
Sub copycells()
Dim a as Integer
Dim b as Integer
a = ThisWorkbook.Worksheets("Sale").Cells(Row.Count, 2).End(xlUp).Row
For i = 2 To a
If Worksheets("Sale").Cells(i, 6).Value = "Parmesh" Then
Worksheets("Sale").Row(i).copy
Workbooks("Source.xlsx").Worksheets("Billdetails").Activate
b = Workbooks("Source.xlsx").Worksheets("Billdetails").Cells(Row.Count, 2).End(xlUp).Row
Workbooks("Source.xlsx").Worksheets("Billdetails").Cells(b + 1, 1).Select
ActivateSheet.Paste
Worksheets("Sale").Activate
End If
Next
Application.CutCopyMode = False
Workbooks("Purchase.xlsx").Worksheets("Sale").Cells(1, 1).Select
End Sub
Also, you may try to use the Set operator.
Anyway, it is not clear what property or method gives an error. So, I'd recommend breaking the chain of property and method calls:
a = Workbooks("Purchase.xlsx").Worksheets("Sale").Cells(Rows.Count, 2).End(xlUp).Row
Just declare separate lines of code where a single property or method will take its place. For example:
Dim workbk as Excel.Workbook
Dim worksht as Excel.Worksheet
Set workbk = Workbooks("Purchase.xlsx")
Set worksht = workbk.Worksheets("Sale")
Following that way, you will be able to find the problematic call.

Related

My Range on Vlookup source worksheet says Nothing

This code line says = Nothing?
Set SrcDataRange = Src.Range("A13:P" & LastRow)
It`s in a Vlookup code shown below.
If there is a simpler way to write a Vlookup code please tell me?
I used the same code as before but different workbooks and it worked??
Private Sub Up_Date_Prices_Click()
Application.ScreenUpdating = False
Dim SrcOpen As Workbook
Dim Des As Workbook
Dim JCM As Worksheet
Dim Src As Worksheet
Dim FilePath As String
Dim Filename As String
Dim PLDataRange As Range
Dim LastRow As Long
FilePath = "\\TGS-SRV01\Share\ShopFloor\PRODUCTION\PURCHASING\"
Filename = "TGS Group Inventory Sheet - Main.xlsx"
Set SrcOpen = Workbooks.Open(FilePath & Filename)
Set Src = SrcOpen.Worksheets("Part List")
LastRow = Src.Cells(Src.Rows.Count, "A").End(xlUp).row
Set SrcDataRange = Src.Range("A13:P" & LastRow)
Windows("TGS Group Inventory Sheet - Main.xlsx").Visible = True
Set Des = Workbooks("Automated Cardworker.xlsm")
Set JCM = Des.Worksheets("Job Card Master")
JCM.Range("O15").Value = Application.WorksheetFunction.VLookup(JCM.Range("D15"), SrcDataRange, 16, 0)
Application.DisplayAlerts = False
SrcOpen.Close
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
This row I think is wrong
LastRow = Src.Cells(PL.Rows.Count, "A").End(xlUp).row
PL is not set anywhere. Also the variable PLDataRange is never used. I guess you intend to set that somewhere?
I have Option Explicit turned on as default and it means you can never use undeclared variables
Let me know if this is helpful, thanks
I think this is answered here How to error handle 1004 Error with WorksheetFunction.VLookup?
In summary, if there is no match VLookup throws an error - if it is not this then check your last row: O15 your output is only 2 rows below A13 the first anchor to your input range so check that columnP doesnt extend below row 14.
Some observations, JCM.Range("D15") might be better as JCM.Range("D15").value and also the final parameter is actually a boolean so might be better as False rather than zero. They may or may not have any effects here but it may be helpful to get into that habit: Little mistakes like these have cost me hours debugging in the past :)

Still Run time error 1004 'Unable to get the VLookup property of the WorksheetFunction class

I got this error and I tried to fixed with many solution, but I don't know why this error is happening. Could you help me to fix this problem? In this code I have twice used VLookup function same source, different only Worksheet name and column. Another one can compile this code and don't have any error.
I'm doing, VLookup item on column B of worksheet "ImportData2" match with column A of worksheet "Noallocate" if match show result of VLookup at column Q of worksheet "ImportData2"
get this error
Source code:
'Vlook up function no import
Dim Vrow1 As Long
Dim myLookupValue1 As String
Dim myFirstColumn1 As Long
Dim myLastColumn1 As Long
Dim myColumnIndex1 As Long
Dim myFirstRow1 As Long
Dim myLastRow1 As Long
Dim myVLookupResult1 As String
Dim myTableArray1 As Range
For Vrow1 = 2 To 99999
myLookupValue1 = Workbooks("ExpenseData.xlsm").Worksheets("ImportData2").Range("B" & Vrow).Value
myFirstColumn1 = 1
myLastColumn1 = 2
myColumnIndex1 = 2
myFirstRow1 = 2
myLastRow1 = Workbooks("ExpenseData.xlsm").Worksheets("Noallocate").Range("b1").End(xlDown).Row
With Workbooks("ExpenseData.xlsm").Worksheets("Noallocate")
Set myTableArray1 = .Range(.Cells(myFirstRow1, myFirstColumn1), .Cells(myLastRow1, myLastColumn1))
End With
myVLookupResult1 = WorksheetFunction.VLookup(myLookupValue1, myTableArray1, myColumnIndex1, False) 'xxx
Workbooks("ExpenseData.xlsm").Worksheets("ImportData").Range("Q" & Vrow).Value = myVLookupResult1 'xxx
Next 'end function no import
Try the next code, please. It would be a good habit to have 'Option Explicit' on top of your module. This will oblige you to declare all variables. It looks, your code iterates using Vrow1 but inside the loop you used Vrow... I discovered it only after trying to make your code a little friendlier. It is not good to use big variables name instead of 1, 2. This can only make the code more difficult to be understood by looking at it. As short it would be, as easy to be understood and debugged:
Sub testVlookup()
Dim Wb As Workbook, Vrow1 As Long, lastRDat As Long, wsNoall As Worksheet
Dim wsImpD2 As Worksheet, myLookupValue1 As String, myLastRow1 As Long
Dim myVLookupResult1 As String, myTableArray1 As Range
Set Wb = Workbooks("ExpenseDataMcframe.xlsm")
Set wsNoall = Wb.Worksheets("Noallocate")
Set wsImpD2 = Wb.Worksheets("ImportData2")
myLastRow1 = wsNoall.Range("b" & Rows.count).End(xlUp).Row
lastRDat = wsImpD2.Range("B" & Rows.count).End(xlUp).Row
For Vrow1 = 2 To lastRDat
myLookupValue1 = wsImpD2.Range("B" & Vrow1).value
Set myTableArray1 = wsNoall.Range(wsNoall.Cells(2, 1), wsNoall.Cells(myLastRow1, 2))
On Error Resume Next 'for the case when lookup_value is not found
myVLookupResult1 = WorksheetFunction.VLookup(myLookupValue1, myTableArray1, 2, False) 'xxx
If Err.Number <> 0 Then
Err.Clear: On Error GoTo 0
Wb.Worksheets("ImportData").Range("Q" & Vrow1).value = "Not a mach"
Else
Wb.Worksheets("ImportData").Range("Q" & Vrow1).value = myVLookupResult1 'xxx
End If
On Error GoTo 0
Next
End Sub
When the lookup_value is not found, the code will return (on Q:Q column) "Not a match" and you must check the specific code/whatever it is...

Variable not defined error upon execution

can someone explain why I get a variable not defined error on this private sub?
Private Sub CommandButton4_Click()
'Autocomplete Button
Dim w As Long, lastRow As Long
For w = 2 To lastRow
'If existing data = entered data
If sh.Cells(w, 2).Value = Me.TextBox1.Value Then
'fill textbox with associated existing data from same row
Me.TextBox2.Value = sh.Cells(w, 3).Value
'save value of i in invisible textbox because no better solution came to mind yet
Me.TextBox8.Value = w
Exit Sub
End If
Next w
End Sub
The error occurs because you used a variable but did not declare it before. This variable looks like to be sh. So if sh is not a global variable then you need to delare it and set it to your desired worksheet before using the variable:
Dim sh As Worksheet
Set sh = ThisWorkbook.Worksheets("YourSheetName")
Also note that lastRow has no value and therefore is 0 before you use it you need to set a value for this variable.
Otherwise For w = 2 To lastRow is just For w = 2 To 0 and therefore will never run.

Is there a way to reassign a Range variable to a different range?

I am very new to VBA, having started programming it yesterday. I am writing a data processing program which requires keeping track of two cells, one on each spreadsheet. The code which reproduces the errors I am experiencing is below. When I call the sub moveCell() in sub Processor(), nothing happens to DIRow and DIColumn, and the code spits out error 1004 at the line indicated. I have tried using DICell = DICell.Offset(), but it returns the same error.
How can I redefine a Range variable to be a different cell?
'<<Main Processor Code>>'
Sub Processor()
Dim PDRow As Integer
Dim PDColumn As Integer
Dim DIRow As Integer
Dim DIColumn As Integer
PDRow = 1
PDColumn = 1
DIRow = 1
DIColumn = 1
Dim PDCell As Range
Dim DICell As Range
Set PDCell = Worksheets("Processed Data").Cells(PDRow, PDColumn)
Set DICell = Worksheets("Data Input").Cells(DIRow, DIColumn)
Call moveCell(2, 0, "Data Input")
End Sub
'<<Function which moves the cell which defines the range>>'
Sub moveCell(r As Integer, c As Integer, sheet As String)
If sheet = "Processed Data" Then
PDRow = PDRow + r
PDColumn = PDColumn + c
Set PDCell = Worksheets("Data Input").Cells(PDRow, PDColumn)
ElseIf sheet = "Data Input" Then
DIRow = DIRow + r '<<<<<<This line does nothing to DIRow's value
DIColumn = DIColumn + c
Set DICell = Worksheets("Data Input").Cells(DIRow, DIColumn) '<<<<<<This line causes error 1004
End If
End Sub
As far as I can tell, you could instead use a quick Function instead. There doesn't seem to be any difference in your If statement results in the moveCell() function, except which worksheet you're using.
We can make this simpler by referring to the Range you're passing to moveCell.
Option Explicit ' forces you to declare all variables
Sub something()
Dim PDCell As Range
Set PDCell = Worksheets("Processed Data").Cells(1, 1)
Dim DICell As Range
Set DICell = Worksheets("Data Input").Cells(1, 1)
PDCell.Select ' can remove
Set PDCell = moveCell(2, 0, PDCell, PDCell.Worksheet.Name)
PDCell.Select ' can remove
Worksheets(DICell.Worksheet.Name).Activate ' can remove
DICell.Select ' can remove
Set DICell = moveCell(5, 0, DICell, DICell.Worksheet.Name)
DICell.Select ' can remove
End Sub
Function moveCell(rowsToMove As Long, colsToMove As Long, cel As Range, ws As String) As Range
Set moveCell = Worksheets(ws).Cells(cel.Row + rowsToMove, cel.Column + colsToMove)
End Function
I've included some rows you don't need (which I've marked with a comment afterwards), but that will show you how the routine works. You can step through with F8 to help see it step-by-step.
Edit: Although, you don't need a separate function at all. Just use OFFSET().
Set PDCell = ...whatever originally
Set PDCell = PDCell.Offset([rows],[cols])

Iferror/Vlookup using variables

I have recorded an Excel function (Iferror/Vlookup) which I need to modify to inpput variables to make it more dynamic (Allow for columns moving). Below is a brief outline of what I want to do. The First section is the recorded Function and the variables I want to add. The second section is my proposed solution. My problem is I need to drop the function into excel and copy it down over 50,000 rows. So my error handling solution won't work here. Is it possilbe to make the original recorded function dynamic using iferror/Vlookup. Any help appreciated.
Dim Lookup1 As Long
Dim LookupOffset As Long
Dim LRange As Range
Lookup1 = -99
LookupOffset = 28
Set LRange = Column("CU:CV")
With Worksheets("consolidated")
.Cells(2, 99).FormulaR1C1 = _
"=RC[-71]-IFERROR(VLOOKUP(RC[-12],C[-2]:C[-1],2,FALSE),0)"
.Cells(2, 99).Copy Range(.Cells(2, 99), .Cells(glLastRow, 99))
Application.CutCopyMode = False
.Calculate
End With
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Proposed Solution
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim Res As Variant
On Error Resume Next
Err.Clear
Res = Application.WorksheetFunction.VLookup(Lookup1 - LookupOffset, LRange, 2, False)
If Err.Number = 0 Then
''''''''''''''''''''''''''''''''''''''''''''''''''''
' Value found by VLookup. Continue normal execution.
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Else
''''''''''''''''''''''''''''''''''''''''''''''''''''
' Value NOT found by VLookup. Error handling code here.
'''''''''''''''''''''''''''''''''''''''''''''''''''''
End If
Try this one:
Sub LookUpMod()
Dim wSht As Worksheet: Set wSht = ThisWorkbook.Sheets("Consolidated")
With wSht
On Error Resume Next
.Cells(2, 99).Formula = "=XCV34-IFERROR(VLOOKUP(XFC34,$I:$J,2,FALSE),0)"
.Range(Cells(2, 99), Cells(glLastRow, 99)).FillDown
.Calculate
On Error GoTo 0
End With
End Sub
Just noticed, though, that you don't have glLastRow instantiated properly. Let us know if this helps.
EDIT:
As per chat with OP:
Function LookUpMod(Str As Variant, Rng As Range, OffsetToRight As Long)
Application.Volatile
LookUpMod = Rng.Cells.Find(What:=Str).Offset(0, OffsetToRight).Value
End Function
A simple flexible lookup is what is needed.

Resources