Run time error 1004 on using Vlookup function - vba

Im trying to highlight range of cells when a date is present in the list of holidays. But on running the below code, the Run time error 1004 is displayed. I have even tried handling it in error handler; but it is not working. Can somebody please help me why this error is occuring and resolve the same?
Sub highlight_cells()
Dim myrange As Range
On Error GoTo myerr:
For i = 1 To 10
Set myrange = Range(Cells(1, i), Cells(10, i))
temp = Application.WorksheetFunction.VLookup(Range(Cells(1, i)), [holidays], 2, False)
If (Application.WorksheetFunction.IsNA(temp)) Then
myrange.Interior.Color = 3
End If
Next i
myerr:
If Err.Number = 1004 Then
MsgBox "vlookup error"
End If
End Sub

Range(Cells(1, i)) isn't a valid range reference
maybe you wanted to reference Cells(1, i)
furthermore you can exploit the Application VLookup() method that wraps the possible error in the returned variant variable that you can check with IsError() function like follows:
Dim temp As Variant
For i = 1 To 10
Set myrange = Range(Cells(1, i), Cells(10, i))
temp = Application.VLookup(Cells(1, i), [holidays], 2, False)
If Not IsError(temp) Then Cells(1, i).Interior.Color = 3
Next i

Here is a conditional formatting method, without using VBA.
Select your range > Conditional Formating > New Rule > Use a formula ...
Enter this formula
=VLOOKUP($A2,$J$2:$K$6,1,FALSE)
Take care of the "$" in the formula. This should highlight all cells that were found in the holidays list.

Your code is okay , It worked in Excel 2010 , Your problem is with VBA Error handling method.
Go to Tools --> Options -->General --> Error Trapping
And check "Break on unhanded Errors"

sorry all these times I was referring to column 2 in vlookup. That was causing the problem. The list of holiday is a single column list. Hence vlookup was throwing error. ANd one more thing the named ranges work as I have entered and even the actual range also gives the same result.
Sub highlight_cells()
Dim myrange As Range
For i = 1 To 10
Set myrange = Range(Cells(1, i), Cells(10, i))
MsgBox Cells(1, i)
temp = Application.VLookup(Cells(1, i), [holidays], 1, False)
If Not IsError(temp) Then
myrange.Interior.ColorIndex = 3
End If
Next i
End Sub

Related

Excel VBA VLookup Run-time error '1004'

I want to consolidate two sheets. In Tabelle 3 is already some data. Therefore, I defined the Next Free Row (NFR) and want my data from Tabelle 5 added to the next free row in Tabelle 3. Therefore, I wrote the following VLookup function.
Sub ConsolidateData()
Dim lastrow As Long
Dim NFR As Long
lastrow = Tabelle5.Range("A" & Rows.Count).End(xlUp).Row
NFR = Tabelle3.Range("A" & Rows.Count).End(xlUp).Offset(-3).Row
Set myrange = Tabelle5.UsedRange
For i = 4 To lastrow
Tabelle3.Cells(NFR + i, 1) = Application.WorksheetFunction.VLookup(Tabelle5.Cells(i, 1), myrange, 1, False)
Tabelle3.Cells(NFR + i, 2) = Application.WorksheetFunction.VLookup(Tabelle5.Cells(i, 1), myrange, 2, False)
Next i
End Sub
Even though, I'm already using this code in a different workbook, where it works smooth, it doesn't work here. Instead Run-time error '1004' occurs for this line:
Tabelle3.Cells(NFR + i, 1) = Application.WorksheetFunction.VLookup(Tabelle5.Cells(i, 1), myrange, 1, False)
Does anyone see the mistake or can tell me what I've coded wrong?
It seems that Vlookup cannot find value you are looking for and therefore throws an error. Application.WorksheetFunction.VLookup will return error '1004' if value cannot be found. Please consider following test:
Put in cell A2 value of 15.
Run below macros
macro 1:
Sub test1()
check = Application.WorksheetFunction.VLookup(15, Range("A1:A5"), 1, False)
Debug.Print check
End Sub
macro 2:
Sub test2()
check = Application.WorksheetFunction.VLookup(1, Range("A1:A5"), 1, False)
Debug.Print check
End Sub
As you can see second one throws an error. To overcome that issue you should change WorksheetFunction.VLoookup to Application.VLookup and implement error checking:
Sub test2()
If IsError(Application.VLookup(1, Range("A1:A5"), 1, False)) = False Then
check = Application.VLookup(1, Range("A1:A5"), 1, False)
End If
Debug.Print check
End Sub
Please look here as well: How to error handle 1004 Error with WorksheetFunction.VLookup?

Errors 91 and 424 when iterating over ranges in Excel VBA

I am an absolute VBA beginner. I have been trying to create a function that separates a large range into smaller ranges. However, when I try and iterate over the large range, I get errors 91 and 424 interchangeably. Here is the relevant bit of code:
Dim cell As Range
Set cell = Range(Cells(1, 1), Cells(1, 1))
For Each cell In nonZeroes
question = isTouching(cell, firstfeat)
If question = True Then
Set firstfeat = Union(firstfeat, cell)
cell.Interior.ColorIndex = 3
End If
Next
nonZeroes is a range, defined as such:
Dim nonZeroes As Range
For i = 3 To 87
For j = 3 To 87
If Cells(i, j).Value = 0 Then
End If
If Cells(i, j).Value <> 0 Then
If Not nonZeroes Is Nothing Then
Set nonZeroes = Union(nonZeroes, Cells(i, j))
Else
Set nonZeroes = Cells(i, j)
End If
End If
Next j
Next i
What I'm trying to do here is group together non-zero cells that have been entered in a grid. I am considering cells as part of a group if the cell is adjacent to another non-zero cell.
The error occurs with the For Each line highlighted. What am I doing wrong? I've been googling this for a while and all the solutions I've tried don't work.
I think the error is because, as mentioned in the comments, that your "for each" isn't being used correctly. Try this:
Dim cel
Set nonZeroes = Range(Cells(1, 1), Cells(10, 1)) ' You need to set the range to search through here.
For Each cel In nonZeroes
question = isTouching(cel.Value, firstfeat)
If question = True Then
Set firstfeat = Union(firstfeat, cel.Value)
cell.Interior.ColorIndex = 3
End If
Next
I don't think that'll work straight off the bat, because I don't know what your UDFs are, but that should get you started. I also changed "Dim cell" to "Dim cel" since "cell" is also used by VBA

VBA EXCEL Range syntax

I don't understand syntax for range.
Why does this work:
For i = 1 To 10
Range("A" & i & ":D" & i).Copy
Next
But this doesn't work:
For i = 2 To lastRow
num = WorksheetFunction.Match(Cells(i, 1), Range("A" & lastRow), 0)
Next
Why do I need to use
For i = 2 To lastRow
'num = WorksheetFunction.Match(Cells(i, 1), Range("A1:A" & lastRow), 0)
Next
What A1:A mean? Why can't I use
Range("A" & lastRow), 0
There is nothing wrong with your syntax and your code should've work just fine.
The problem with using worksheet function like Match, Vlookup and other look up functions is that if the value being searched is not found, it throws up an error.
In your case, you are trying to search multiple values in just one cell.
So let us say your lastrow is 9. You're code will loop from Cell(2,1) to Cell(9,1) checking if it is within Range("A" & lastrow) or Range("A9").
If your values from Cell(2,1) through Cell(9,1) is the same as your value in Range("A9"), you won't get an error.
Now, if you use Range("A1:A" & lastrow), it will surely work cause you are trying to match every element of that said range to itself and surely a match will be found.
WorksheetFunction.Match(Cells(2,1), Range("A1:A9")) 'will return 2
WorksheetFunction.Match(Cells(3,1), Range("A1:A9")) 'will return 3
'
'
'And so on if all elements are unique
It doesn't matter if you use Range("A9") or Range("A1:A9").
What matters is that you handle the error in case you did not find a match.
One way is to use On Error Resume Next and On Error Goto 0 like this:
Sub ject()
Dim num As Variant
Dim i As Long, lastrow As Long: lastrow = 9
For i = 2 To lastrow
On Error Resume Next
num = WorksheetFunction.Match(Cells(i, 1), Range("A" & lastrow), 0)
If Err.Number <> 0 Then num = "Not Found"
On Error GoTo 0
Debug.Print num
Next
End Sub
Another way is to use Application.Match over WorksheetFunction.Match like this:
Sub ject()
Dim num As Variant
Dim i As Long, lastrow As Long: lastrow = 9
For i = 2 To lastrow
num = Application.Match(Cells(i, 1), Range("A" & lastrow), 0)
Debug.Print num
'If Not IsError(num) Then Debug.Print num Else Debug.Print "Not Found"
Next
End Sub
Application.Match works the same way but it doesn't error out when it returns #N/A. So you can assign it's value in a Variant variable and use it later in the code without any problem. Better yet, use IsError test to check if a value is not found as seen above in the commented lines.
In both cases above, I used a Variant type num variable.
Main reason is for it to handle any other value if in case no match is found.
As for the Range Syntax, don't be confused, it is fairly simple.
Refer to below examples.
Single Cell - All refer to A1
Cells(1,1) ' Using Cell property where you indicate row and column
Cells(1) ' Using cell property but using just the cell index
Range("A1") ' Omits the optional [Cell2] argument
Don't be confused with using cell index. It is like you are numbering all cells from left to right, top to bottom.
Cells(16385) ' refer to A2
Range of contiguous cell - All refer to A1:A10
Range("A1:A10") ' Classic
Range("A1", "A10") ' or below
Range(Cells(1, 1), Cells(10, 1))
Above uses the same syntax Range(Cell1,[Cell2]) wherein the first one, omits the optional argument [Cell2]. And because of that, below also works:
Range("A1:A5","A6:A10")
Range("A1", "A8:A10")
Range("A1:A2", "A10")
Non-Contiguous cells - All refer to A1, A3, A5, A7, A9
Range("A1,A3,A5,A7,A9") ' Classic
Without any specific details about the error, I assume that Match does not return the value you expect, but rather an #N/A error. Match has the syntax
=match(lookup_value, lookup_range, match_type)
The lookup_range typically consists of a range of several cells, either a column with several rows or a row with several columns.
In your formula, you have only one cell in the lookup_range. Let's say Lastrow is 10. The first three runs of the loop produce the formula
=Match(A2,A10,0)
=Match(A3,A10,0)
=Match(A4,A10,0)
It is a valid formula but in most cases the result won't be a match but an error. Whereas what you probably want is
=Match(A2,A1:A10,0)
Looking again at your code, stitch it together and find why you need A1:A as a string constant in your formula:
For i = 2 To lastRow
num = WorksheetFunction.Match(Cells(i, 1), Range("A1:A" & lastRow), 0)
Next

Excel VBA Get hyperlink address of specific cell

How do I code Excel VBA to retrieve the url/address of a hyperlink in a specific cell?
I am working on sheet2 of my workbook and it contains about 300 rows. Each rows have a unique hyperlink at column "AD". What I'm trying to go for is to loop on each blank cells in column "J" and change it's value from blank to the hyperlink URL of it's column "AD" cell. I am currently using this code:
do while....
NextToFill = Sheet2.Range("J1").End(xlDown).Offset(1).Address
On Error Resume Next
GetAddress = Sheet2.Range("AD" & Sheet2.Range(NextToFill).Row).Hyperlinks(1).Address
On Error GoTo 0
loop
Problem with the above code is it always get the address of the first hyperlink because the code is .Hyperlinks(1).Address. Is there anyway to get the hyperlink address by range address like maybe sheet1.range("AD32").Hyperlinks.Address?
This should work:
Dim r As Long, h As Hyperlink
For r = 1 To Range("AD1").End(xlDown).Row
For Each h In ActiveSheet.Hyperlinks
If Cells(r, "AD").Address = h.Range.Address Then
Cells(r, "J") = h.Address
End If
Next h
Next r
It's a bit confusing because Range.Address is totally different than Hyperlink.Address (which is your URL), declaring your types will help a lot. This is another case where putting "Option Explicit" at the top of modules would help.
Not sure why we make a big deal, the code is very simple
Sub ExtractURL()
Dim GetURL As String
For i = 3 To 500
If IsEmpty(Cells(i, 1)) = False Then
Sheets("Sheet2").Range("D" & i).Value =
Sheets("Sheet2").Range("A" & i).Hyperlinks(1).Address
End If
Next i
End Sub
My understanding from the comments is that you already have set the column J to a string of the URL. If so this simple script should do the job (It will hyperlink the cell to the address specified inside the cell, You can change the cell text if you wish by changing the textToDisplay option). If i misunderstood this and the string is in column AD simply work out the column number for AD and replace the following line:
fileLink = Cells(i, the number of column AD)
The script:
Sub AddHyperlink()
Dim fileLink As String
Application.ScreenUpdating = False
With ActiveSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastrow
fileLink = Cells(i, 10)
.Hyperlinks.Add Anchor:=Cells(i, 10), _
Address:=fileLink, _
TextToDisplay:=fileLink
Next i
End With
Application.ScreenUpdating = True
End Sub
Try to run for each loop as below:
do while....
NextToFill = Sheet2.Range("J1").End(xlDown).Offset(1).Address
On Error Resume Next
**for each** lnk in Sheet2.Range("AD" & Sheet2.Range(NextToFill).Row).Hyperlinks
GetAddress=lnk.Address
next
On Error GoTo 0
loop
This IMO should be a function to return a string like so.
Public Sub TestHyperLink()
Dim CellRng As Range
Set CellRng = Range("B3")
Dim HyperLinkURLStr As String
HyperLinkURLStr = HyperLinkURLFromCell(CellRng)
Debug.Print HyperLinkURLStr
End Sub
Public Function HyperLinkURLFromCell(CellRng As Range) As String
HyperLinkURLFromCell = CStr(CellRng.Hyperlinks(1).Address)
End Function

VBA Run-time error 1004: Application-defined or object-defined error

I'm just getting familiar with VBA and my code
xxLastrow = xLastRow+1
For x = 11 To xLastRow
For y = 12 To xxLastrow
If ActiveSheet.Cells(x, 2).Value = Cells(y, 2).Value Then
For z = 4 To xLastColumn
If ActiveSheet.Cells(y, z).Value <> "" Then '(possible If Not IsEmpty(Cells(y, z).Value))
ActiveSheet.Cells(y, z).Select
Selection.Copy
ActiveSheet.Cells(x, z).Select
ActiveSheet.Paste
End If
Next z
End If
Next y
Next x
makes Run-time error 1004: Application-defined or object-defined error when the line "If ActiveSheet.Cells(y, z).Value <> "" Then" goes. All variables are integer (including lastrow/column). What's the problem here?
I promise sea of cats for man who will try to help :)
This i smoe of a comment than an answer, but as code looks ugly in a comment I thought I would post as answer.
You can accomplish your same results with a much more efficient code, the below code uses value = value instead of copy paste, as to avoid using the clipboard (that itself is a buggy slow process). It also does not loop every single column reducing your loops by (Row matches * Column Count) number of times, probably a lot.
Dim rngTest As Range
Dim rngCur As Range
Dim rngCOff As Range
Set rngTest = Range("B11:B" & xLastRow)
For Each rngCur In rngTest
Set rngCOff = rngCur.Offset(1)
If rngCur.Value = rngCOff.Value Then
rngCOff.Offset(, 2).Resize(, xLastColumn - 4).Value = rngCur.Offset(, 2).Resize(, xLastColumn - 4).Value
End If
Next rngCur