I am trying to run as a macro a custom Excel function XpathOnUrl from the add-in called SeoTools by Niels Bosma. The function runs fine and it seems that I am able to store its result in a variable. This variable can then be correctly output to an Excel cell, but when I try to look for a string in it in the next part of the macro, I get the error Run-time error '13': Type mismatch. From what I understand from here, the function returns an array, but when I try to access it as the first item of the array, I get the same error. I tried to convert the variable into a string with CStr, but no luck there either. What am I missing?
Here's the problematic part of the code:
WebSite = Sheet1.Range("A1")
contactPage = Application.Run("XPathOnUrl", WebSite, "//a[contains(translate(#href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),""contact"")]", "href")
MsgBox TypeName(contactPage) 'trying to find out the data type results in 'Error'
If Left(contactPage(0), 4) = "http" Then
Sheet1.Range("B1").Value = contactPage
ElseIf InStr(contactPage, "/") = 1 Then
Sheet1.Range("B1").Value = WebSite & contactPage
End If
Just to make it clear: the problem starts only with conditional statements. If I assign the value of the variable directly to a cell like this Sheet1.Range("B1").Value = contactPage, it outputs the correct result.
Here's a easy workaround:
Make XpathURL spit its return to a range. Then, use Range.value to assign the return to a contactpage and clear the range using .Clearcontents property. I think Application.Run is not letting XpathURL return get to contactpage.
Edit: Added the comment below:
Sheet1.Range("B1").Value = Application.Run("XPathOnUrl", WebSite, "//a[contains(translate(#href, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),""contact"")]", "href")
contactPage = Sheet1.Range("B1").Value
Did you try the Formula and FormulaR1C1 functions? Just my assumptions.
Try and let us know if it helped.
Sheet1.Range("B1").Formula = WebSite & contactPage
or
Sheet1.Range("B1").FormulaR1C1 = WebSite & contactPage
What does the MsgBox TypeName(contactPage) display?
Related
I am trying to filter an array in VBA by using the filter function. But every time I try to execute the code, I get an error message
Compile error:
Wrong number of arguments or invalid property assign
for some reason. I copied some code from an external source to test it out, but even the simplest example doesn't seem to work. Here's the code:
Private Sub Befehl0_Click()
Dim langs(5) As Variant
langs(0) = "English"
langs(1) = 375
langs(2) = "Spanish"
langs(3) = 442
langs(4) = "Chinese"
langs(5) = 1299.5
output_arr = Filter(langs, 375)
End Sub
Every time I execute the code, the function "Filter" gets highlighted. Does anyone know the answer to this problem?
It works if I try output_arr = VBA.Filter(langs, 375) as BigBen has stated in the comments!
Hey maybe I'm not seeing something obvious here but how can you use the Find VBA function with a predefined variable. I'm using a concatenation of a string assigned from a user form and just "total " in front of it, yet I can't return the row.
Below is my code
Dim HBWS As Worksheet
Dim TickerString As String
TickerString = "Total " & TTB
Set HBWS = Sheets("Hoenheimm Worksheet")
BorrowColumn = HBWS.Cells.Find(What:="Borrow").Column 'Works just fine
TickerRow = HBWS.Cells.Find(What:=TickerString).Row 'Throws an error
Note that TTB is set to a ticker ex. AAPL, and I can check in my local windows that Tickerstring is in fact = to "Total AAPL"
I would expect the .Row column to give me the row on my worksheet as to where this string is located.
EDIT: the error being thrown is as follows...
"Run-Time error '91':
Object Variable or With block variable not set"
Any throughts,
Thanks
You're invoking Range.Find. That method returns a Range object reference - and when it does not find what it's told to look for, it returns Nothing, i.e. a null reference.
TickerRow = HBWS.Cells.Find(What:=TickerString).Row 'Throws an error
What this code is doing (and the working instruction just above it), is assuming that Find returns a valid object reference.
Apparently HBWS.Cells does not contain "Total " & TTB (whatever TTB is), so your code is effectively trying to invoke Range.Row against a Range reference that's Nothing... which is illegal, and raises run-time error 91 as you're experiencing.
You shouldn't assume that Find will return a valid reference, ever. Split it up, and validate the returned object reference with an If ... Is Nothing check:
Set tickerResult = HBWS.Cells.Find(What:=TickerString)
If Not tickerResult Is Nothing Then
tickerRow = tickerResult.Row
Else
'tickerString was not found.
'watch for leading/trailing/extra spaces if the string does *look* legit.
End If
When calling Range.Find, you should always provide a value for the optional parameters, because its implementation "remembers" values from previous invocations, and this is easily bug-prone.
This question already exists:
VBA Function not storing variable
Closed 5 years ago.
I am reposting this question, because I haven't gotten an answer and I still can't figure out what I'm doing wrong. My latest efforts to resolve the problem on my own are detailed below the code.
Original post: VBA Function not storing variable
I have included the code of my function. I mostly scrapped this together from things I found online, because I am very much an amateur coder. I am trying to take the trendline of a graph and use it for a mathematical calculation. When I step through this code, it works great. However, when I call the function from another sub, it gives me an error. Error 9: Subscript out of range. When I debug, it shows me the line a = spl(0). The real problem is that the variable "s" remains empty. Why?
Function TrendLineLog() As Double
Dim ch As Chart
Dim t As Trendline
Dim s As String
Dim Value As Double
' Get the trend line object
Set ch = ActiveSheet.ChartObjects(1).Chart
Set t = ch.SeriesCollection(1).Trendlines(1)
' make sure equation is displayed
t.DisplayRSquared = False
t.DisplayEquation = True
' set number format to ensure accuracy
t.DataLabel.NumberFormat = "0.000000E+00"
' get the equation
s = t.DataLabel.Text '<--------- ACTUAL PROBLEM HERE
' massage the equation string into form that will evaluate
s = Replace(s, "y = ", "")
s = Replace(s, "ln", " *LOG")
s = Replace(s, " +", "")
s = Replace(s, " - ", " -")
spl = Split(s, " ")
a = spl(0) '<----------- DEBUG SAYS HERE
b = spl(1)
c = spl(2)
y = 0.5
..... Math stuff
End Function
I have tried adding the creation of the chart to the function to avoid an error with "Active Sheet". I also tried pasting this code into my sub instead of calling a separate function. Still nothing. When I debug and highlight the t.DataLabel.Text, it shows me the correct value, but for some reason s is not saving that value. In the Locals window, t has value, but s is blank (" ").
Yes, of course you will get an error on the line you pointed out. You are calling spl(0) as though it is its own function, though you did not define spl() as a sub (function) anywhere in this code. Or, alternatively (more likely) you are calling it as an array, which also throws up some flags.
Make sure you are defining spl in your code. You never do this. Add line:
Dim spl(1 to 3) As String
Then you should find that spl(1), spl(2), and spl(3) are what you desire.
If i change it manually it works.
If then i run this:
Sub cellformat()
ShowCellFormat = Range("A1").NumberFormat
MsgBox ShowCellFormat
Range("A2").NumberFormat = ShowCellFormat
End Sub
this works too, msgbox displays:
Generic "randomtext"
The only thing that i cant manage is to change the format like this:
Range("A1").NumberFormat = "Generic "randomtext""
Tried 100 different ways still not working...
Assuming you want your number format to be something like "XYZ"0000"DEF" to display the number 15 as XYZ0015DEF, then you can't write your code as
Range("A1").NumberFormat = ""XYZ"0000"DEF""
'or
'Range("A1").NumberFormat = "Generic "randomtext""
You instead need to write the code as:
Range("A1").NumberFormat = """XYZ""0000""DEF"""
'or
'Range("A1").NumberFormat = "Generic ""randomtext"""
because each double-quotation mark (i.e. ") used within a string literal needs to be escaped by writing it as "".
I'm using Excel (because the data is saved in a spreadsheet) to go through a list of a few thousand links and see if they are broken, AKA do they return a 404 or not when I RESTful GET them. However, my VBA code is returning something other than when I use curl, and in this case curl is right (the page exists). Here's my code with the link that's causing trouble (it's inside a subroutine, don't worry):
For i = StartRow To EndRow
Let copyRange = "H" & i
Let writeRange = "T" & i
query = Worksheets("Sheet1").Range(copyRange).Value
If query = "" Then
Else
With zipService
.Open "GET", query, False
End With
zipService.send
zipResult = zipService.Status
Worksheets("Sheet1").Range(writeRange).Value = zipResult
End If
Next i
The curl command line:
curl –sL –w “%{http_code} \n” http://URLHERE” –o /dev/null
The link that's causing trouble: http://www.stopwaste.org/home/index.asp#
Curl returns 200, VBA returns 404. The same link has failed several times, so I don't think it's a "server was just down for a second" situation. I thought it my have been a problem with the # character, so I removed it but got the exact same response. The code is successfully reporting other 404's, so somehow there's a situation that creates false positives (or negatives, whichever you want to call it). the "If query = "" Then" is so that there aren't GETs to empty URLS, VBA doesn't like those.
I'm pretty stumped here, and was hoping someone would be able to help me out. Thanks in advance!
Why not use .FollowHyperlink to check if the URL exists?
See this example.
Sub Sample()
Dim url As String
url = "http://www.stopwaste.org/home/index.asp#"
Debug.Print url, CheckIfURLExists(url)
url = "http://www.Google.com"
Debug.Print url, CheckIfURLExists(url)
url = "http://www.Goo00000gle.com"
Debug.Print url, CheckIfURLExists(url)
End Sub
Function CheckIfURLExists(ByVal sLink As String) As Boolean
On Error Resume Next
ThisWorkbook.FollowHyperlink (sLink)
CheckIfURLExists = Err.Number = 0
End Function
Screenshot:
Removed the '#' character and it worked just fine.
In Fiddler I saw that browser didn't send '#' character at all:
Try changing this line to include double quotes:
zipService.send ""
Also, try reseting zipService after each URL
Set zipService = Nothing
I'm assuming the excel version works for some of your URLs since your pointing out one specific one.?.?