Excel VBA: Error 1004 When Trying To Add Hyperlink - vba

The series of commands seems to result in Runtime Error: 1004 I would like to know what the cause of this error is.
If I do not have the Activesheet.Hyperlinks.add line the cell values get set correctly, just missing the hyperlink... which would make me think I've lost the xCell reference but I've placed debug statements just before the hyperlink.add and it seems to be accessible.
Example URL: http://www.walmart.com/ip/Transformers-Robots-in-Disguise-3-Step-Changers-Optimus-Prime-Figure/185220368
For Each xCell In Selection
Url = xCell.Value
If Url = "" Then
'Do Nothing
ElseIf IsEmpty(xCell) = True Then
'Do Nothing
ElseIf IsEmpty(Url) = False Then
splitArr = Split(Url, "/")
sku = splitArr(UBound(splitArr))
xCell.Value = "https://www.brickseek.com/walmart-inventory-checker?sku=" & sku
'Error happens on next command
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=xCell.Formula
End If
Next xCell

Don't both with .ValueDon't use .Formula:
Sub demo()
Dim s As String, xCell As Range
s = "http://www.walmart.com"
Set xCell = Range("B9")
ActiveSheet.Hyperlinks.Add Anchor:=xCell, Address:=s, TextToDisplay:=s
End Sub
is a typical working example.

There is always another possibilty, that your sheet may be locked and you have to grant permission to do so when locking the sheet.
I know this is not the solution for the problem described here, but the non-deterministic error messages provided by Microsoft VBA is the same. I came here looking for the solution of my problem, an others might bump in this and find my comment relevant.

Related

'With Worksheets("xxxx")' works only when "xxxx" is the active worksheet

I'm pretty new to Excel VBA. So far I've read and learned a lot on this site, but haven't found a solution for my problem.
As part of a macro I have the following code:
With Worksheets("Oracle")
On error resume next
ActiveWorkbook.Names("bron").Delete
ActiveWorkbook.Names.Add Name:="bron", RefersTo:= Range("A1", Range("A1").End(xlToRight).End(xlDown))
.Cells.Select
With Selection.Font
.Name = "Verdana"
.FontStyle = "Standaard"
.Size = 8
End With
.Range("A1", Range("A1").End(xlToRight)).Font.Bold = True
MsgBox "Tabblad ‘Oracle’ is klaar!", vbOKOnly
End With
I understand that with the first line of the code it shouldn't matter what the active sheet actually is. But the problem is it only works when Oracle is the active sheet. What have I done wrong?
If you are using With Worksheets() ... End With it means that you want to refer to a specific worksheet and not to the ActiveSheet. This is considered a good practice in VBA.
As mentioned in the comments by #GSerg, your code does not work, because you do not have a dot in front of all the Ranges. However, you cannot notice this because you are using On Error Resume Next, which ignores all errors.
In your case the problem is that you are trying to Refer to a range which is in both the ActiveSheet and in Oracle with this line .Range("A1", Range("A1").End(xlToRight)).. Thus the error is unevitable.
You have two options to make sure your code works:
Simply activate Worksheet "Oracle" and run the code. It will work ok.
Try to rewrite it like this:
With Worksheets("Oracle")
On Error Resume Next
ActiveWorkbook.Names("bron").Delete
ActiveWorkbook.Names.Add Name:="bron", _
RefersTo:=.Range("A1", .Range("A1").End(xlToRight).End(xlDown))
With .Cells.Font
.Name = "Verdana"
.FontStyle = "Standaard"
.Size = 8
End With
.Range("A1", .Range("A1").End(xlToRight)).Font.Bold = True
MsgBox "Tabblad ‘Oracle’ is klaar!", vbOKOnly
End With
Take a look that all the Ranges are referred with a dot and the Select command is not used any more.

Finding a cell based on the header of a section of data, then selecting the last row of that section

I am attempting to find the text of a header row based on the value of a cell relative to the cell that is clicked in. The way I have attempted to do this is follows:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim var1 As Variant
Dim var2 As Variant
Dim var3 As Variant
Dim FormName As String
FormName = "New Form"
Static NewFormCell As Range
Application.ScreenUpdating = False
If Not Intersect(Target, Range("G16:X80")) Is Nothing Then
If Target.Cells.Count = 1 Then
var1 = Cells(Target.Row, 2).Value
var2 = Cells(15, Target.Column).Value
If Not (IsEmpty(var1)) And Not (IsEmpty(var2)) And var2 <> "+" And Target.Interior.ColorIndex <> 2 And Target.Borders(xlEdgeLeft).LineStyle <> xlNone Then
If IsEmpty(Target) Then
Target.Value = "X"
Target.HorizontalAlignment = xlCenter
Target.VerticalAlignment = xlCenter
Target.Font.Bold = True
Dim Header As Range
Set Header = Range("A54:E160").Find(var2, LookIn:=xlValues)
Header.Offset(1, 1).End(xlDown).EntireRow.Select
Dim CopyCell As Range
'Header.End(xlDown).EntireRow.Insert
'Set CopyCell = Header.End(xlDown). [offset?]
'CopyCell.Value = var1
Else
Target.ClearContents
End If
Else
Exit Sub
End If
End If
End If
Application.ScreenUpdating = True
End Sub
The issue is VBA is throwing Run-Time Error 91 ("Object variable or With block variable not set"). It then highlights the last row in that section of code. Since I set that variable in the previous line, I'm not sure why I'm receiving this error or if I'm even going about this the right way.
Any input would be greatly appreciated!
EDIT: I cleared the above issue by searching over a wider range. The cell I wanted to select was merged, but I still assumed the value was stored within column A. But this code still isn't quite doing what I'd like it to:
I want to select the last row in the section (not the last row of data in the sheet, but the last contiguous data in column B), but right now my code is jumping me all the way to the bottom of the sheet.
The problem is that your .Find isn't finding the value. In this case, you can add some code to handle that.
...
Dim Header As Range
Set Header = Range("A59:A159").Find(var2, LookIn:=xlFormulas)
If Header Is Nothing Then
' There's no value found, so do something...
msgbox(var2 & " was not found in the range, will exit sub now."
Exit Sub
End If
MsgBox Header
...
...of course there are myriad ways/things you can do to handle this. If you still want to execute other code, then wrap everything in an If Header is Nothing Then // 'do something // Else // 'other code // End IF type thing.
It really just depends on what you want to do. Again, your error is being caused by the fact that the var2 isn't being found, so just find other things to do in that case.

VBA runtime error 13 using Msgbox

I'm very new to VBA and only have a basic level of knowledge.
I have been trying to create a macro to cross-reference data on one sheet against multiple other sheets within the same work book. If a record is found I would like a msgbox to appear to alert the user of the location of the data.
After many hours searching the internet and piecing together bits of code this is what I have
Sub search()
Dim ws As Worksheet, found As Range
Dim TextToFind(1 To 20) As String
Dim iText As Long
TextToFind(1) = "Jade Smith"
TextToFind(2) = "Bob Collins"
TextToFind(3) = "Jemima Smythe"
For Each ws In ThisWorkbook.Worksheets
With ws
If .Name <> "Blacklisted Candidates" Then 'Do not search blacklist candidates!
iText = 1
Do While iText <= UBound(TextToFind)
If TextToFind(iText) <> "" Then 'Do not search blank strings!
Set found = .UsedRange.Find(what:=TextToFind(iText), LookIn:=xlformulas, LookAt:=xlPart, MatchCase:=False)
If Not found Is Nothing Then
MsgBox "Proxy Candidate Found at " & found.Address
Else
MsgBox "No Proxy Candidates Found ", vbOKOnly, "Success!"
End If
iText = iText + 1
End If
Loop
End If
End With
Next ws
End Sub
This code however doesn't find the values from other sheets.
when testing this I just get the msgbox when no data has been found even though there is test data there.
I have a workbook of approx 9 sheets (ever growing) and I want to search the first 9 columns of each work book for the specified data which as you can see I have manually input into the macro but when running the macro I get no results returned even though there is data to find.
You are trying to use the binary operator And on two strings. You probably meant to use & instead to concatenate strings.
Documentation :
And
&
(The docs are for VB.Net, but they work the same in both languages)
So to fix it, replace
MsgBox ("Proxy Candidate Found at " And rngX.Address)
By
MsgBox ("Proxy Candidate Found at " & rngX.Address)
edited to account for searching in cell whose content derives from a formula
to both summarize all what has been already pointed out in comments and litelite answer and add some 0.02 cents, here a working code
Option Explicit
Sub search()
Dim ws As Worksheet, found As Range
Dim TextToFind(1 To 20) As String
Dim iText As Long
TextToFind(1) = "xxxx"
TextToFind(2) = "xxxx"
TextToFind(3) = "xxxxx"
For Each ws In ThisWorkbook.Worksheets
With ws
If .name <> "Blacklisted Candidates" Then 'Do not search blacklist candidates!
iText = 1
Do While iText <= UBound(TextToFind)
If TextToFind(iText) <> "" Then 'Do not search blank strings!
Set found = .UsedRange.Find(what:=TextToFind(iText), LookIn:=xlFormulas, LookAt:=xlPart, MatchCase:=False)
If Not found Is Nothing Then
MsgBox "Proxy Candidate Found at " & found.Address
Else
MsgBox "No Proxy Candidates Found ", vbOKOnly, "Success!"
End If
iText = iText + 1
End If
Loop
End If
End With
Next ws
End Sub

VBA: No CellTypeBlanks available

I've got a spreadsheet I'm working on where sometimes my wRange has no blank cells left to use. In this case I want to jump to the end of the macro. I'm currently using this:
On Error Resume Next
wRange.SpecialCells(xlCellTypeBlanks) = "0"
On Error GoTo -1
to deal with the error I get if there are no blank cells left after my other changes.
I'm planning on using a flag like
If wRange.SpecialCells(xlCellTypeBlanks) is Blank Then
Boolean emptycells = FALSE
End If
Is there a better way to go about doing this? And if not, how do I go about coding this?
Thank you.
You can do it like that:
Dim blanks As Range
On Error Resume Next
Set blanks = wRange.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If blanks Is Nothing Then
emptyCells = False
End If
mielk's answer is perfectly fine, but from reading your question it sounds like the only reason you are even using the emptyCells boolean is to go to the end of macro. So I would not even bother with it and would instead modify mielk's answer in the following way:
Whateveryoursubsnameis()
Dim rngBlanks As Range
On Error Resume Next
Set rngBlanks = wRange.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If blanks Is Nothing Then
GoTo MacroEnd
End If
(rest of your macro's code)
MacroEnd:
End Sub

Range & If Statement using multiple sheets

I have several Sheets involved but I'll have Sheet 2 Active. When I'm on "Sheet 2" I need to know when cell ("C14") becomes active with an IF statement I'm guessing. Once it becomes active, I then need to know if the string in cell ("B2") on Sheet 1 = "Fighter" then I want to insert "some wording regarding the fighter here" in cell ("C14") on Sheet 2. IF it's not "Fighter"then is it "Mage"? If so then insert "some wording regarding the mage here".
This is short hand for example.
if cell C14 on Sheet 2 is active then
check cell B2 on Sheet1. If the text = "Fighter"? Then
insert "You are brave and use a sword" into cell C14 Sheet2
if it's not equal to Fighter then is it = "Mage"? Then
insert "You cast spells" in cell C14 sheet2
etc..
I need to know how to code this in VBA. I've spent hours searching and trying various code but can't seem to get it right. Thanks ahead of time for your help.
Try something like this:
'The way you check which cell is active is by using an
'Event like this one. This goes into the Sheet2 code module
'which you can get to by right clicking on the sheet's tab and
'selecting View Code.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim rng_Source As Excel.Range
Dim rng_Target As Excel.Range
On Error GoTo ErrorHandler
'Setting the cells that you're interested in as
'ranges will help minimise typo errors.
Set rng_Target = ThisWorkbook.Sheets("Sheet2").Range("C14")
Set rng_Source = ThisWorkbook.Sheets("Sheet1").Range("B2")
'Target is a range that specifies the new
'selection. Check its address against rng_Target
'which we defined above.
If Target.Address <> rng_Target.Address Then
Exit Sub
End If
'If you don't want case sensitivity, convert to upper case.
If UCase(rng_Source.Value) = "FIGHTER" Then
rng_Target.Value = "some wording regarding the fighter here"
ElseIf UCase(rng_Source.Value) = "MAGE" Then
rng_Target.Value = "You cast spells"
'You get the idea.
End If
ExitPoint:
On Error Resume Next
'Clean up
Set rng_Source = Nothing
Set rng_Target = Nothing
On Error GoTo 0
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & vbCrLf _
& Err.Description
Resume ExitPoint
End Sub
I do agree with the comments that you should always post the code that you've already tried (which you subsequently did), but this is a relatively trivial one and this just clears it out of the way and may be of use to somebody else as well in the future.
Try this ;)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo errH
Dim rng1 As Range
Set rng1 = ThisWorkbook.Worksheets(1).Range("B2")
If Not Intersect(Target, Me.Range("C14")) Is Nothing Then
Application.EnableEvents = False
If rng1.Value2 = "Mage" Then
Target.Value = "OMG This is MAGE!!! Run run run away!!!"
ElseIf rng1.Value2 = "Fighter" Then
Target.Value = "Fighter? :/ Was hoping for something better"
MsgBox "Fighter? :/ Was hoping for something better"
rng1.Value2 = "Mage"
Target.Value = "Mage. Now This is better ;)"
Else
Target.Value = "No, we haven't discussed it."
End If
Application.EnableEvents = True
End If
Exit Sub
errH:
MsgBox ("Error number: " & Err.Number & "Description: " & Err.Description)
Application.EnableEvents = True
End Sub