Reputation: 23
I'm struggling with my VBA code. I have two Subs :
My goal is to call the VARIANT variable IE_Title from the first Sub (IEGetActivePage) into the next Sub (TestScrape2) and convert it to an OBJECT variable (for the code in TestScrape2 to work).
EDIT:
SET
function does not seem to work. I get the same result: the Internet Explorer window pops up but nothing more. Not even the MsgBox to check the variable type.This is the IEGetActivePage code, with the IE_Title variable:
Option Explicit
Sub IEGetActivePage()
Dim marker As Variant
Dim IE_Window As Variant
Dim IE_count As Variant
Dim X As Variant
Dim IE_Title As Variant 'The web page used in this code is the following: https://fr.wikipedia.org/wiki/Visual_Basic_for_Applications
Dim IE As Variant
marker = 0
Set IE_Window = CreateObject("Shell.Application")
IE_count = IE_Window.Windows.Count
For X = 0 To (IE_count - 1)
On Error GoTo ErrorHandler
IE_Title = IE_Window.Windows(X).Document.Title
If IE_Title Like "Visual Basic for Applications — Wikipédia" Then
Set IE = Fenêtre.Windows(X)
marker = 1
Exit For
Else
End If
Next
If marker = 0 Then
MsgBox ("The Internet window cannot be found")
Else
AppActivate IE_Title 'Activates the correct Internet Explorer windows
'---Until there, the code works fine. The next step is an attempt to create a new variable out of the IE_Title variable and converting it to an object. As @Gustav suggested, I tried the SET function but I get the same result---
Dim IEObject As Object
Set IEObject = IE_Title.InternetExplorer
'---To check if the conversion worked, I inserted a MsgBox using the IsObject function below---
Dim VariableCheck As Boolean
If VariableCheck = IsObject(IEObject) Then
MsgBox (VariableCheck)
Else
End If
'---As a result, the message box does appear. No errors displayed either. And the scraping evidently did not work. The only thing that works is the Internet Explorer window activation. So there must be an issue here---
Call TestScrape2 'Calling the next Sub
End If
ErrorHandler:
If Err.Number > 0 Then 'TODO: handle specific error
Err.Clear
Resume Next
End If
End Sub
And the following code is the next Sub (TestScrape2):
Option Explicit
Sub TestScrape2()
Dim IEObject As Object
Set IEObject = New InternetExplorer
IEObject.Visible = True
Dim IEDocument As HTMLDocument
Set IEDocument = IEObject.Document
Debug.Print IEDocument.getElementbyId("firstHeading").innerText
End Sub
Any ideas? On how to call a variable used in a Sub and converting it to an object variable in another Sub?
Hopefully this is clear enough
Upvotes: 0
Views: 766
Reputation: 23
So after combining the answers of @Gustav for the message box, @Toddleson for the module-level variable and @Yu Zhou for his sample, here's the code that works for me:
Option Explicit
Public IE_Title As Variant 'The web page used in this code is the following: https://fr.wikipedia.org/wiki/Visual_Basic_for_Applications
Sub IEGetActivePage()
Dim marker As Variant
Dim IE_Window As Variant
Dim IE_count As Variant
Dim X As Variant
Dim IE As Variant
marker = 0
Set IE_Window = CreateObject("Shell.Application")
IE_count = IE_Window.Windows.Count
For X = 0 To (IE_count - 1)
On Error GoTo ErrorHandler
IE_Title = IE_Window.Windows(X).Document.Title
If IE_Title Like "Visual Basic for Applications — Wikipédia" Then
Set IE = IE_Window.Windows(X)
marker = 1
Exit For
Else
End If
Next
If marker = 0 Then
MsgBox ("The Internet window cannot be found")
Else
AppActivate IE_Title
TestScrape2 IE 'Calling the next Sub
End If
ErrorHandler:
If Err.Number > 0 Then 'TODO: handle specific error
Err.Clear
Resume Next
End If
End Sub
Sub TestScrape2(IE_Title As Variant)
Dim IEObject As Object
Set IEObject = New InternetExplorer
IEObject.Visible = True
IEObject.Navigate IE_Title.LocationURL
Do While IEObject.Busy = True Or IEObject.ReadyState <> READYSTATE_COMPLETE
Application.Wait Now + TimeValue("00:00:05")
Loop
Debug.Print IEObject.LocationURL
End Sub
Declaring IE_Title
as a module-level variable (or as a public variable) at the top of the module script, instead of declaring it only on the first Sub (as shown in my first draft). This allows the second Sub to reuse the variable without creating a conflict in the variable types declaration.
Forgetting the idea of converting a variable within the same Sub. It might work in some other cases. Maybe an advanced user would make it work but I'm happy with this script working as it is haha.
Create a duplicate Internet Explorer window out of the first one to make the script work. This simple code line IEObject.Navigate IE_Title.LocationURL
suggested by @Yu Zhou was a game-changer (although I kept IE_Title
instead of IE
which didn't work). As the first Sub identifies the correct IE window, it also stores properties information about the opened window such as the URL, which in this case can be reused.
I also realized that although having a duplicate IE window can be redundant, the script works as it is and closing the duplicates at the end is not such a big deal.
Adding a temporary MsgBox in the second Sub to confirm that IE_Object
is an object variable. It is not shown in the code above, but I added them on my version to check that nothing blocks the script.
Thanks to you all!
N.B.: hey you advanced user reading this, if you can simplify this script, feel free to share it here :-)
Upvotes: 0
Reputation: 12961
The message box doesn't show because VariableCheck
is false and IsObject(IEObject)
is true. Besides, IE_Title
is a string, I think Set IEObject = IE_Title.InternetExplorer
is wrong syntax.
If you want to pass a variable from sub1 to sub2, you can refer to this answer.
As a workaround, you can pass the IE
variant from sub1 to sub2, then get the url of IE
and open a new Internet Explorer window with the url. You can check the sample below:
Option Explicit
Sub IEGetActivePage()
Dim marker As Variant
Dim IE_Window As Variant
Dim IE_count As Variant
Dim X As Variant
Dim IE_Title As Variant 'The web page used in this code is the following: https://fr.wikipedia.org/wiki/Visual_Basic_for_Applications
Dim IE As Variant
marker = 0
Set IE_Window = CreateObject("Shell.Application")
IE_count = IE_Window.Windows.Count
For X = 0 To (IE_count - 1)
On Error GoTo ErrorHandler
IE_Title = IE_Window.Windows(X).Document.Title
If IE_Title Like "Visual Basic for Applications — Wikipédia" Then
Set IE = IE_Window.Windows(X)
marker = 1
Exit For
Else
End If
Next
If marker = 0 Then
MsgBox ("The Internet window cannot be found")
Else
AppActivate IE_Title
TestScrape2 IE 'Calling the next Sub
End If
ErrorHandler:
If Err.Number > 0 Then 'TODO: handle specific error
Err.Clear
Resume Next
End If
End Sub
Sub TestScrape2(IE As Variant)
Dim IEObject As Object
Set IEObject = New InternetExplorer
IEObject.Visible = True
IEObject.navigate IE.LocationURL
While IEObject.Busy
DoEvents
Wend
Debug.Print IEObject.Document.getElementbyId("firstHeading").innerText
End Sub
Upvotes: 0
Reputation: 55816
Try to Set
the object:
Dim IEObject As Object
Set IEObject = IE_Title.InternetExplorer
Also, check like this:
Dim VariableCheck As Boolean
VariableCheck = IsObject(IEObject)
MsgBox CStr(VariableCheck)
Upvotes: 1