Reputation: 313
I'm trying to use excel VBA to automate the data entering on a intranet Webpage of my company. I know how to interact with values of a web page the fields have "id" like in the html code below
<input name="txtUserName" tabindex="1" id="txtUserName" type="text">
With that kind of html code I would use something like
IE.Document.getElementbyId("txtUserName").Value = "UserName"
The problem I'm facing is that the code associated with the field I'm trying to interact is
<HTML><HEAD><META content="IE=5.0000" http-equiv="X-UA-Compatible">
<SCRIPT type=text/javascript>
function ajusterFrames() {
var iLargeurGauche = 217;
var iLargeurDroite = 850;
var iLargeurFenetre = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var iMarge = 0;
var sCols = "";
if (iLargeurFenetre > (iLargeurGauche + iLargeurDroite)) {
iMarge = (iLargeurFenetre - (iLargeurGauche + iLargeurDroite)) / 2;}
sCols = (iLargeurGauche + iMarge) + ",*";
document.getElementById("framesetbas").cols = sCols;
document.getElementById("cadres").style.display = "block";}
window.onload = ajusterFrames;
window.onresize = ajusterFrames;
</SCRIPT>
<TBODY>
<TR> </TR>
<TR>
<TD>
<!--RECHERCHE-->
DIV id=Projet>
<!--RECHERCHE-->
<CENTER>
<FIELDSET style="WIDTH: 600px" name="recherche">
<LEGEND style="FONT-SIZE: 10px; FONT-FAMILY: verdana; COLOR: #767676" name="legende_recherche">
<INPUT onclick=afficherRecherche(this.value); type=radio value=simple name=TypeRecherche>
</DIV><!------RECHERCHE AVANCÉE------------------------------------->
<DIV id=divAvancee>
<CENTER>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TR>
<TR>
<TR>
<TR>
<TR>
<TD align=right>
<FONT color=#003366 size=1 face=verdana>No Projet :</FONT></TD>
So I'm trying to modify the value of the field identify by: "txtNoProjet" Here's the code I could come up with, I tried many versions around this and still can't get it right.
UPDATED CODE TO INCLUDE SOLUTION
Private Sub entree_budget()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
Dim buttonCollection As Object
Dim valeur_heure As Object
num_proj = Cells(1, 3) 'this is the value that I need to input
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = True
' Send the form data To URL As POST binary request
IE.Navigate "http://intranet.cima.ca/fr/application/paq/projets/index.asp?v1_lang=1"
' Wait while IE loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'UPDATED CODE BELOW
Set links = IE.Document.frames(2).Document.getElementsByTagName("input")
n = links.Length
While i < n
If links(i).Name = "txtMotCle" Then
links(i).Value = num_proj
End If
i = i+ 1
Wend
End Sub
Can anyone help me with this?
And also if I may I will the need to click the button "search" on the bottom of the form , but I can't recognize it's syntax so I don't know how to interact with it. Could someone tell me how to click the button that has this html code?
<A href="javascript:submitForm('avancee');">
<IMG border=0 alt="Rechercher un projet" src="../../../images/fr/rechercher.gif"></A>
UPDATED CODE SOLUTION FOR THIS IS:
Set links = IE.Document.frames(2).Document.getElementsByTagName("a")
n = links.LengtH
i = 0
While i < n
If links(i).href = "javascript:submitForm('avancee');" Then
Set objElement = links(i)
objElement.ClicK
End If
i = i + 1
Wend
Thank you so much in advance for the time you'll spend answering my questions.
Upvotes: 0
Views: 4574
Reputation: 3490
Edited: the input elements were contained in a frame, which is why @jeeped's answer wasn't working. getElementsByTagName("input") should have returned them. Hopefully this edit will save you from having to read through the comments to find that out. To return inputs contained in a frame, use
IE.document.frames(x).document.getElementsByTagName("input")
where x is the index of the frame.
Original response below.
=======================================================
If it's zero-based, shouldn't you remove the -1 that's preventing the loop from running? That is, if there is one element, then the for loop would be iNPT = 0 to 0
and execute once. If there were two, then the .length
would return 1 and =0 to 1
would execute twice, as expected.
I personally would probably include both Microsoft Internet Controls and Microsoft HTML Object Library in the references for the project so that I could use early binding and declare the variables, and then use a for each to iterate:
Dim inputs As MSHTML.IHTMLElementCollection
Dim inpt As MSHTML.IHTMLInputElement
Dim IE As New SHDocVw.InternetExplorer
IE.Visible = True
IE.navigate "http://intranet.cima.ca/fr/application/paq/projets/index.asp?v1_lang=1"
While IE.readyState <> READYSTATE_COMPLETE: DoEvents: Wend
Set inputs = IE.document.getElementsByTagName("input")
For Each inpt In inputs
If inpt.Name = "txtNoProjet" Then inpt.Value = num_proj
Next
Be aware that the HTML Object Library includes several different IHTMLElementCollections, with different numbers. In some situations you might need to use one of those instead. Also, you may need to use getAttribute
to access the attribute:
If inpt.getAttribute("name") = "txtNoProjet" then inpt.Value = num_proj
Upvotes: 2
Reputation:
The index to a collection of elements is zero-based. Assuming that there is only a single txtNoProjet
you would use,
IE.Document.getElementsbyName("txtNoProjet")(0).Value = num_proj
I've had trouble with .getElementsbyName
in the past. If the above does not work for you, collect all of the <input>
elements and cycle through them until you find the one you want.
dim iNPT as long
for iNPT=0 to (IE.Document.getElementsbyTagName("input").length - 1)
if IE.Document.getElementsbyTagName("input")(iNPT).name = "txtNoProjet" then
IE.Document.getElementsbyTagName("input")(iNPT).value = num_proj
exit for
end if
next iNPT
One of those should get you going. The biggest problem you will run into would be duplicate names.
EDIT: addendum for clicking an image anchor
dim iIMG as long
for iIMG=0 to (IE.Document.getElementsbyTagName("img").length - 1)
if CBool(InStr(1, IE.Document.getElementsbyTagName("img")(iIMG).src, "rechercher.gif", vbTextCompare)) then
IE.Document.getElementsbyTagName("img")(iIMG).click
do while IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE: Do Events: Loop
exit for
end if
next iIMG
I usually prefer something closer to IE.Document.getElementsbyTagName("form")(0).submit
but you haven't provided enough HTML source code to write that properly. You will have to adjust that code to look into your .Frames
element.
Upvotes: 0