【问题标题】:Automate Internet Explorer: enter a value that has no "ID"自动化 Internet Explorer:输入一个没有“ID”的值
【发布时间】:2015-04-19 04:34:23
【问题描述】:

我正在尝试使用 excel VBA 来自动输入我公司内联网网页上的数据。我知道如何与字段具有“id”的网页的值进行交互,就像下面的 html 代码中一样

<input name="txtUserName" tabindex="1" id="txtUserName" type="text">  

有了这种 html 代码,我会使用类似

IE.Document.getElementbyId("txtUserName").Value = "UserName"  

我面临的问题是与我尝试交互的字段相关的代码是

        <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>

所以我正在尝试修改字段标识的值:“txtNoProjet”这是我可以想出的代码,我尝试了很多版本,但仍然无法正确。
更新代码以包含解决方案

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

'下面的更新代码

    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 

谁能帮我解决这个问题?
如果可以的话,我还需要单击表单底部的“搜索”按钮,但我无法识别它的语法,所以我不知道如何与之交互。有人可以告诉我如何单击具有此 html 代码的按钮吗?

<A href="javascript:submitForm('avancee');">
<IMG border=0 alt="Rechercher un projet" src="../../../images/fr/rechercher.gif"></A>  

对此的更新代码解决方案:

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

非常感谢您花时间回答我的问题。

【问题讨论】:

    标签: html excel vba internet-explorer


    【解决方案1】:

    已编辑:输入元素包含在一个框架中,这就是@jeeped 的答案不起作用的原因。 getElementsByTagName("input") 应该返回它们。希望此编辑将使您不必通读 cmets 来找出答案。要返回包含在框架中的输入,请使用

    IE.document.frames(x).document.getElementsByTagName("input") 
    

    其中 x 是帧的索引。

    以下原始回复。

    ================================================ ========

    如果它是从零开始的,你不应该删除阻止循环运行的 -1 吗?也就是说,如果只有一个元素,那么 for 循环将是 iNPT = 0 to 0 并执行一次。如果有两个,那么.length 将返回 1,=0 to 1 将按预期执行两次。

    我个人可能会在项目的引用中同时包含 Microsoft Internet 控件和 Microsoft HTML 对象库,以便我可以使用早期绑定并声明变量,然后使用 for each 进行迭代:

    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
    

    请注意,HTML 对象库包含几个不同的 IHTMLElementCollections,编号不同。在某些情况下,您可能需要改用其中一种。此外,您可能需要使用getAttribute 来访问该属性:

    If inpt.getAttribute("name") = "txtNoProjet" then inpt.Value = num_proj
    

    【讨论】:

    • Tx 试一试。但还是没有运气! for 循环只是被忽略。 “输入”变量为空。第二个选项“如果 inpt.getAttribute ...”给我一个运行时错误 91。这显然是一个棘手的问题。还有其他可能吗?
    • 它是一个从零开始的索引和一个常规编号的长度。它们不是同一件事。如果有三个 &lt;input&gt; 元素,则 .getElementsbyTagName("input").length 返回 3。它们以.getElementsbyTagName("input")(0).getElementsbyTagName("input")(1).getElementsbyTagName("input")(2) 访问。
    • @jeeped 你能看看我更新的 html 代码并评论@tricky 的建议吗?基本上长度返回 0 作为值。 IT 似乎我们没有使用适当的语法来调用它。任何其他关于此的教导
    • 啊,抱歉,@jeeped,没有意识到。 getElementsByTagName() 应该返回所有输入元素。 @excelguigui11,是的,页面来源会有所帮助。有没有机会获得整个页面源,而不是 sn-p?我将您所拥有的内容原样复制到文本文档(以 开头并以 结尾)并使用 buffer 变量加载:Dim doc As MSHTML.IHTMLDocument Set doc = New HTMLDocument doc.write(buffer ) 并且它按预期工作。你为什么不试试 `test = IE.document.body.outerHTML 看看你实际上有什么源代码。
    • 那个href是它独有的吗?如果是这样,您可以创建一个名为“a”的标签元素集合来获取锚标签集合 (MSHTML.IHTMLAnchorElement),然后您将迭代它们并匹配 href。但是,我认为您无需单击按钮即可提交该表单,除非该页面具有某种事件验证。我认为您可以执行.document.forms("avancee").submit 之类的操作,但您可能必须知道表单的索引才能这样做。如果是这样,请遍历表单 (MSHTML.IHTMLFormElement),然后单击名为 avancee 的表单。
    【解决方案2】:

    元素集合的索引从零开始。假设您只会使用一个 txtNoProjet

    IE.Document.getElementsbyName("txtNoProjet")(0).Value = num_proj
    

    我过去在使用 .getElementsbyName 时遇到过麻烦。如果上述方法不适合您,请收集所有 &lt;input&gt; 元素并循环浏览它们,直到找到您想要的。

    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
    

    其中一个应该可以帮助您前进。您将遇到的最大问题是名称重复。

    编辑:点击图片锚点的附录

    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
    

    我通常更喜欢更接近IE.Document.getElementsbyTagName("form")(0).submit 的东西,但您没有提供足够的 HTML 源代码来正确编写它。您必须调整该代码以查看您的 .Frames 元素。

    【讨论】:

    • Tx 为您提供帮助,但它不起作用。第一个返回运行时错误 91 运行时错误 91 - 对象变量或未设置块变量。第二个什么都不做,因为 getElementsbyTagName("input").length 返回一个 0 值。还有其他关于这方面的教导吗?
    • @excelguigui11 你描述的这个错误通常是因为页面没有完成加载,你的等待循环可能有问题。 Application.Wait 通常不可靠。你可以试试While IE.Busy Or IE.ReadyState &lt;&gt; 4: DoEvents: Wend
    • @DavidZemens Tx 以获得洞察力,但我逐行运行代码,但仍然得到相同的结果。有人可以分享的任何其他可能性
    • 对不起,我的评论太长了,如下新答案。
    • @Jeeped 和@David Zemens,我更新了 html 代码,请你再看看我的问题
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签