PDA

View Full Version : GetObject for Internet Explorer?


spacey123
12-10-2005, 02:12 AM
Is there anyway/alternative method of using GetObject for Internet Explorer?

I was doing some browsing yesterday and it seems that GetObject cannot be used with Internet Explorer, because it doesn't include itself in the application list or something.

I was reading http://www.xtremevbtalk.com/showthread.php?t=247142 on how to manipulate Internet Explorer, and that example works fine, but I am trying to grab data from a textbox on an existing IE window.

I thought about using the example above to make that IE window the foremost, and then try to grab the textbox value, but to no avail at the moment.

I tried running the above code, and then something like:

myvalue=IE.document.All("amount").Value
but because I haven't set up 'IE' it doesn't work.

I also tried to open a new IE window, use the other forum code to bring the window foremost and then try my vb above, but still to no avail.

Is there a workaround for GetObject? I saw some things yesterday but it seemed to involve downloading something, which doesn't work for me at work (we're not supposed to use downloaded things etc).

Cheers.

PS. Navigating to the page won't work due to it being an IE based application that is always the same web page, but it extracts data for different accounts etc. Has to be from an existing window.

herilane
12-10-2005, 11:41 AM
Example:
Sub ListShellWindows()
'Get all currently open IE and Explorer windows (those are based on the same class).
'For IE windows, get location. For WE windows, get path.

Dim objShell As Shell
Dim objIE As InternetExplorer
Dim objExplorer As ShellFolderView

Dim obj As Object

Set objShell = New Shell
For Each obj In objShell.Windows
If TypeName(obj.Document) = "HTMLDocument" Then
Set objIE = obj
Debug.Print objIE.LocationURL
Else
Set objExplorer = obj.Document
Debug.Print objExplorer.FocusedItem.Path
End If
Next obj

End SubThis requires a reference to Microsoft Internet Controls and to Microsoft Shell Controls and Automation. You can also choose to not add the references, but then replace the variable declarations with As Object.

NateO
12-10-2005, 05:15 PM
Hello,

Also, as I tend to think of GetObject() as a late-bind approach, you can do the same thing using the Late Bind (i.e., no references). The following example is a little different, it looks for IE, if it finds it, it hijacks it, otherwise it creates a new instance and navigates to this site:


Public Declare Function ShowWindow& Lib "user32" ( _
ByVal hwnd As Long, _
ByVal nCmdShow As Long)

Sub LoopIeInstances()
Dim oShApp As Object, oWin As Object, IE As Object
Dim WScript As Object
Set oShApp = CreateObject("Shell.Application")
For Each oWin In oShApp.Windows
If TypeName(oWin.Document) = "HTMLDocument" Then
Set IE = oWin
Exit For
End If
Next
If IE Is Nothing Then _
Set IE = CreateObject("InternetExplorer.Application")
With IE
.navigate "http://www.xtremevbtalk.com"
Do While .busy: DoEvents: Loop
Do While .readystate <> 4: DoEvents: Loop
Call ShowWindow(.hwnd, 3)
.Visible = True
Set WScript = CreateObject("WScript.Shell")
WScript.PopUp Left$(.Document.body.innerText, 20), _
2, "Hello!", vbSystemModal
Set WScript = Nothing
End With
Set IE = Nothing: Set oShApp = Nothing
End Sub
:)

spacey123
12-12-2005, 06:42 AM
Thanks for the replies guys/gals. Tried them both but neither seem to do what I want!

The first example seems to return the URL of the window (which I don't need to know, opening a new IE at this URL does nothing much with the application), whilst the second seems to return 'Microsoft Internet Explorer', or if no IE windows are open, navigates to the web address specified.

I tried inserting the following into the first's If...Else... routine
Range("a1").Value = objIE.txtFundsXX thinking that would work, but to no avail.

Am I misunderstanding the purpose of the replies?

As always, thanks for any replies :)

PS. Or alternatively, I can get the output from View Source on this window into a cell, then I can work with that? If I could use a URL then I could do this easily enough, but entering a URL is no good, data is retrieved after we enter an account number from a database of some sort held elsewhere which holds all of the values I require.

herilane
12-12-2005, 02:31 PM
Well, my question was an answer to this part of your original post:
I tried ... something like:
myvalue=IE.document.All("amount").Value
but because I haven't set up 'IE' it doesn't work.

spacey123
12-16-2005, 02:43 AM
I have hopefully been getting further with this, and have got this so far:

Sub ListShellWindows()
'Get all currently open IE and Explorer windows (those are based on the same class).
'For IE windows, get location. For WE windows, get path.

Dim objShell As Shell
Dim objIE As InternetExplorer
Dim objExplorer As ShellFolderView

Dim obj As Object

Set objShell = New Shell
For Each obj In objShell.Windows
If TypeName(obj.Document) = "HTMLDocument" Then
Set objIE = obj
'Range("a1").Value = objIE.txtFundsXX
Range("a1").Value = objIE.LocationURL
Else
Set objExplorer = obj.Document
MsgBox objExplorer.FocusedItem.Path
End If
Next obj

End Sub

The above gets me the web address because it changes every time, and is unknown to the user etc.

The below is what I am now trying to get the data I require:
Dim objShell As Object, objShellWindows As Object, o As Object
Dim retVal As Object, sURL As String
Set retVal = Nothing
Set objShell = CreateObject("Shell.Application")
Set objShellWindows = objShell.Windows
'see if IE is already open
For Each o In objShellWindows
sURL = ""
On Error Resume Next
sURL = o.Document.Location
On Error GoTo 0
If sURL <> "" Then
If sURL Like sAddress & "*" Then
Set retVal = o.Document
Exit For
End If
End If
Next o
Set GetHTMLDocument = retVal
End Function

Sub Button4_Click()
Dim a As Object
Dim b As String
Set a = GetHTMLDocument(range("a1").value)
MsgBox a.getElementById("txtAdvanceXX")
(also tried) MsgBox a.Document'.body.innerText
End Sub

Anyone able to see if I'm gettng closer? When I try the above I get the error message:

Run-Time error 438
Object doesn't support this property or method

I have got the following information about the web page from View Source if it's of any assistance?

From the header:
<! -- 16/12/2005,08:24:35 -->
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>

<LINK rel='stylesheet' type='text/css' href='Styles/style.css'>

<SCRIPT LANGUAGE="JAVASCRIPT" src="/xxx/xxx/xxx.js"></SCRIPT>
<SCRIPT LANGUAGE="JAVASCRIPT">

and from the area around where the textbox is (I presume it's a textbox! You enter values into it!)
<TD><INPUT CLASS='mediumnumber' id="txtFundsXX" name="txtFundsXX" value="99999" readOnly></TD>

I think I have provided as much info as I can now, so if anyone can assist further, cheers :)

If not then I will consider this undoable at this moment in time.

Thanks.

NateO
12-16-2005, 09:49 AM
Hello,

I think you might be getting closer...

'txtFundsXX' looks like a textbox, and that's its name. Why hijack IE, though? You could just use a new instance and navigate to where you're going...

And, not sure why you'd use a function, why not just write an inline sub, perhaps something like:

http://www.xtremevbtalk.com/showthread.php?p=973120

This example passes values to textboxes, submits the info and waits to return information from a resulting document's table...

spacey123
12-16-2005, 10:58 AM
Thanks NateO. I can do what's in that post if I can navigate to the page, but when I do from the link that I get then all the fields are empty. That's why I need to hijack an existing IE window.

Navigating to the site is not an option, tried that.

I use the above code because it's what I've found elsewhere, and seems to be close to what I am needing. Rather than ask for help from the start, tried to find some existing code, and adapt as necessary.

NateO
12-16-2005, 12:27 PM
Hello again,

Perhaps I'm missing something here, but I believe the trick is to populate the Controls. In that example .street_name.Value is a textbox with no value in it until I do this:

.street_name.Value = "Imperial Street"

This populates the specific textbox with Imperial Street.

And etc... Then you submit the Form and wait for results. Yes-no? :confused:

spacey123
12-16-2005, 12:49 PM
We have a main sheet, and an account number is keyed. We then press the Tab key and it loads the same form but only with all of the details (texboxes) filled in.

It is at this stage when it's populated that I want to get the data I need.

As long as we don't close this window whatever account number is keyed, the web address will always be the same.

When we are done with the data we refresh the page, enter an account number, press tab and so it all begins again.

It just changes whenever we start the application.

Being able to crack this will save hours of work and increase accuracy so much it's going to be unbelievable.

NateO
12-16-2005, 01:06 PM
Hello again,

Your process sounds a lot like this:

http://mrexcel.com/board2/viewtopic.php?p=884522#884522

Tabbing is for people and keyboards, not VBA. ;)

I'm really not following how tabbing in Excel automates IE. You want to populate a textbox on a Web Form, submit it, wait, then grab the results from a table on the resulting sheet, right? So why not just do that with a new IE instance?

I suppose if you're dead set on doing it this way, by all means. But I'm confused as to the benefit of approaching this problem this way... :confused:


Even more confusing is why someone tried to use the exact same source code with a different website/problem set... Don't do that, to be sure. :huh:

spacey123
12-16-2005, 01:34 PM
The tabbing is done on the web site.

I open IE and go to the main portal.
I key the roll number and pressing tab makes the web page populate with the account details.
I then want to go to Excel, and the user will push a button, it will get this IE window and get the details required and paste it into Excel.
This will then save the user having to key the data manually and making mistakes, as they do. I just want to automate things as much as possible.
I can't navigate to the web site (which would be easy to do as I've done it before) to grab the data. It has to be from the open IE window.

I don't really comprehend another way of doing it. I can't navigate to it, got to use existing web page, from how I am seeing things (maybe I just need a kick).

Can't look at code until I go to work on Monday, so will see what it does then.

Thanks for the suggestion...

NateO
12-16-2005, 01:40 PM
Okay, fair does,

So you know how to grab the IE instance. Are you having trouble getting data from a Table back into Excel then? I.e., what's the problem where you stand now? :)

spacey123
12-16-2005, 01:47 PM
I seem to be able to focus the window (I can resize it!!) it's just grabbing the data using the code above.

Using Sub Button4_Click()
Dim a As Object
Dim b As String
Set a = GetHTMLDocument(range("a1").value)
MsgBox a.getElementById("txtAdvanceXX")
(also tried) MsgBox a.Document'.body.innerText
End Sub returns [object] into a, which is hopefully correct (I dunno!), so then I want to get the textbox contents using a.whatever goes here.

the msgbox line is what I would use if I navigated to the web site manually, eg www.google.com, but I can't do that (cos the web address changes everytime, so I am targetting the IE window that holds the web address I have manually gotten using the above code, and when I do get it using above code, it displays with all fields blank), so I thought I would try it in this code but I get the error message

Run-Time error 438
Object doesn't support this property or method

So, the a.whatever code I am using above in the vb tags isn't compatible this way.

NateO
12-16-2005, 01:54 PM
Would it be:


msgbox ie.document.Forms(x).txtAdvanceXX.Value

Where x is the proper index or string of the form you want? Perhaps IE should be o, I can't really tell how your marshalling around your IE object based on your posts...

spacey123
12-17-2005, 12:13 AM
Thanks NateO, will try that on Monday.

I don't know how I'm marshalling around neither.

Just trying to combine what code looks like will work to do the job!

spacey123
12-19-2005, 02:34 AM
Error:

Run-time error '438':
Object doesn't support this property or method

No good, never mind.

Thanks for the assistance gang.

NateO
12-19-2005, 09:44 AM
Hello again,

What did you try? What's the source code for the form? I.e., does it have a name? If not, try making x = 0, if not, try making x = 1, etc...

herilane
12-20-2005, 03:55 PM
Could you post a copy of the web page in question, perhaps?

spacey123
12-21-2005, 03:18 AM
I will post what I can, but because of security etc I can not exactly post too much.

I have included a screenshot of the page we use.
An account number is entered in the top left hand box, we press tab and this then populates the rest of the page. I have left outstanding the box that will contain the value I need to grab.

Here is some of the source code for the web page, when viewed as source after it has finished loading. I have replaced most variables with XXX, and the part that affects what I need I have replaced with QQQ and WWW (again for security issues).

I have not copied the whole text, as some of it is in blocks, ie do a load of functions for checks, populate the fields etc:

<! -- 21/12/2005,08:36:30 -->
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>

<LINK rel='stylesheet' type='text/css' href='Styles/style.css'>

<SCRIPT LANGUAGE="JAVASCRIPT" src="xxx.js"></SCRIPT>
<SCRIPT LANGUAGE="JAVASCRIPT">
var xxx= 0;
var xxx= "";
var xxx = "xxx";
var xxx= "xxx";
var xxx;
var xxx;
var xxx= 1;

var xxx= false;
top.CaptureClose.document.all.xxx.value='N';

var cPFT_MSP = 1;
var cPFT_FA = 4;
var cPFT_TOMP = 5;
var cPFT_COMBINED = 6;
var cPFT_PT = 7;
var cPFT_MAINT = 8;
var cPFT_DRAW = 9;
var cPFT_PAYARRANGE = 10;
var sErrMsgs;
var bButtonSelected
bButtonSelected = false;

if ("" == "True") {
xxx= true;
xxx= false;
}
if ("" == "True") {
xxx= false;
xxx= true;
}

function xxx(strFldName,strMand)
{
top.xxx(strFldName,strMand);
return true;
}


function xxx(sAction)
{
var xxx;

sChild= top.main.document.all.CHILD.value;

if (top.main.document.all.LOADED.value!="Y")
{
alert("Please wait until the page fully loads.");
return false
}

if (sChild=="Y" && sAction=="UNDERWRITE")
{
alert("This option is not valid in this screen.");
return false;
}

if (bButtonSelected)
{
alert("Please wait until previous action has been processed.");
return false
}
else
bButtonSelected = true;

//top.footer.FooterTable.style.visibility="hidden";

return true;
}

THERE ARE OTHER PIECES OF CODE IN THIS BIT, BUT THEY FOLLOW A SIMILAR PROCEDURE TO THE ABOVE EXAMPLE. i HAVE HAD TO REPLACE VARIABLES WITH XXX DUE TO THE NATURE OF THE BUSINESS (CAN'T RISK ANYTHING!)

</SCRIPT>
<script language=javascript>top.XXX("XXX", "1");top.bSiteMapEnabled = false;top.header.xxx.src = 'xxx.gif';</script><INPUT TYPE="HIDDEN" NAME="CHILD" ID="CHILD" VALUE="N">

AND THEN SOME A LOAD MORE INSTRUCTIONS SIMILAR TO THE ABOVE LINE
<script language='javascript'>
//JUN04
function printPage()
{
if (window.print)
{
window.print()
}
else //IE 4

{
WebBrowser = '<OBJECT ID="WebBrowser1" WIDTH=0 HEIGHT=0 CLASSID="' XXX"></OBJECT>';
document.body.XXX('beforeEnd', WebBrowser);
execScript("on error resume next: WebBrowser1.ExecWB 6, 1", "VBScript");
WebBrowser1.outerHTML = "";
}
}
//END JUN04
SOME MORE FUNCTIONS ARE HERE^^^
</script>
<script language=javascript>top.header.XXX.src = 'IMAGES/XXX.gif';</script><input type=hidden id="XXX" name="XXX" value=""><input type=hidden id="XXX" name="XXX" value="XXX">
SOME MORE INSTRUCTIONS SIMILAR TO THE ABOVE<TABLE class='mainfirst' cellspacing='0' cellpadding='0'><TR><TD WIDTH = '21%'><LABEL CLASS='XXX'>XXX</LABEL></TD></TR>
SOME OTHER CODE TO POPULATE THE SCREE HERE<TD WIDTH = '14%'>QQQ</TD><TD WIDTH = '1%'>£</TD><TD><INPUT CLASS='mediumnumber' id="WWW" name="WWW" value="99999" readOnly></TD></TR>AND THEN SOME MORE CODE TO POPULATE THE PAGEAND THEN SOME MORE CODE TO FILL THE PAGE, CARRY OUT FUNCTIONS ETC</script></HTML

and the VB I am trying is:
This gets me the IE URL (when it is already populated with data):
Sub ListShellWindows()
'Get all currently open IE and Explorer windows (those are based on the same class).
'For IE windows, get location. For WE windows, get path.
Dim objShell As Shell
Dim objIE As InternetExplorer
Dim objExplorer As ShellFolderView
Dim obj As Object
Set objShell = New Shell
For Each obj In objShell.Windows
If TypeName(obj.Document) = "HTMLDocument" Then
Set objIE = obj
Range("a1").Value = objIE.LocationURL
Else
Set objExplorer = obj.Document
MsgBox objExplorer.FocusedItem.Path
End If
Next obj
End Sub

and this bit is the part I am trying to use to get the field:
'Find an IE window with matching location and get a reference
'to the document object from the loaded page. Assumes no frames.
Function GetHTMLDocument(sAddress As String) As Object

Dim objShell As Object, objShellWindows As Object, o As Object
Dim retVal As Object, sURL As String
Set retVal = Nothing
Set objShell = CreateObject("Shell.Application")
Set objShellWindows = objShell.Windows
'see if IE is already open
For Each o In objShellWindows
sURL = ""
On Error Resume Next
sURL = o.Document.Location
On Error GoTo 0
If sURL <> "" Then
If sURL Like sAddress & "*" Then
Set retVal = o.Document
Exit For
End If
End If
Next o
Set GetHTMLDocument = retVal
End Function

Sub Button4_Click()
Dim a As Object
Dim b As String
Set a = GetHTMLDocument("http://hww.mortgagesales.hx-online.hxgroup.com/NMSPFramework.asp?MODE=HxCompletions&PROCFLOW=1&sRole=11&sLogicalDate=2005-12-20&CLIENTSPEC=*4251*109*")
MsgBox a.Document.Forms(4).txtAdvanceXX.Value
'MsgBox a.getElementById("txtAdvanceXX").Value
'MsgBox a.Document '.body.innerText
End Sub

I think that's about all I can give you I'm afraid. I don't understand most of it, but this is the only way forward from how I perceive things, due to not being able to navigate manually to the web page.

spacey123
12-21-2005, 05:25 AM
Woopsie, forgot Screenie. Add it on here so I don't mess anything up :)

herilane
12-21-2005, 06:17 AM
I was mostly hoping for the body of the document, that defines / specifies the input elements...

The basic approach would be this:
Dim d As HTMLDocument
Set d = GetHTMLDocument("test")
Debug.Print d.body.all("theBox").Value
where "theBox" is the name of the textbox.

The page I ran this on looked like this:
<html>
<head></head>
<body>
<input type = text name = "theBox">
</body></html>