使用VBA点击按钮或执行JavaScript函数

3

我正在尝试让我的VBA程序与使用JavaScript的页面进行交互,并且过去已经成功了。但是在最近的更新后,它不再起作用了。现在我需要做的是:要么A)以编程方式单击一个按钮,要么B)执行该按钮调用的函数。棘手的部分是该按钮没有声明名称。有其他在代码中声明名称的表格,我可以与它们很好地交互。以下是页面源代码中的html代码:

<input type="button" class="buttonForm" value='Run Report' onclick="exportData(workOrderSearchForm)"/>

正如您所看到的,它并没有为按钮声明名称。过去,以下内容是有效的:

Set ie = CreateObject("InternetExplorer.application")
ie.document.all(79).Click

“79” 是项号的索引。现在看起来按钮已经更改为“81”,但只需输入:

ie.document.all(81).Click

由于某些原因,该功能无法正常工作。我知道要执行的函数是:exportData(workOrderSearchForm),但不知道如何在不使用“click”方法的情况下执行该函数。

我已经查找了一些关于IE应用程序对象的文档,但似乎找不到一个好的来源。有没有一种执行该函数的方法?

3个回答

11

试一下这个:

Dim CurrentWindow As HTMLWindowProxy: Set CurrentWindow = ie.Document.parentWindow
Call CurrentWindow.execScript("exportData(workOrderSearchForm)")

但首先,您需要在“引用”(工具 > 引用)下包含 Microsoft HTML Object 库。


2
你可以循环遍历所有输入标签,并通过检查“最具标识性”的属性(id、name、type、innerHTML等)来确定相关标签。以下是我在Excel表格中使用的一个子程序,它可以自动登录到网站。
Sub FormAction(Doc As MSHTML.HTMLDocument, ByVal Tag As String, ByVal Attrib As String, ByVal Match As String, ByVal Action As String)
Dim ECol As MSHTML.IHTMLElementCollection
Dim IFld As MSHTML.IHTMLElement
Dim Tmp As String

    Set ECol = Doc.getElementsByTagName(Tag)
    For Each IFld In ECol                                         ' cycle thru all <[tag]> elements
        If VarType(IFld.getAttribute(Attrib)) <> vbNull Then      ' does it contain the attribute
            If Left(IFld.getAttribute(Attrib), Len(Match)) = Match Then
                If Action = "/C/" Then
                    IFld.Click
                Else
                    IFld.setAttribute "value", Action
                End If
                Exit Sub
            End If
        End If
    Next
End Sub

该函数接受以下参数:
  • Doc .... HTML DOM对象
  • Tag .... 您要处理的标签(通常为input、image、a等)
  • Attrib .... 您想要匹配值的属性
  • Match .... 匹配属性的值
  • Action ..... 如果是“/C/”,则在匹配的标签上执行.Click()操作,否则将操作值放入标签的value属性中

如果您想挂钩包含JavaScript代码的任何属性(例如“onclick”),请不要忘记在HTML源代码中看到的代码嵌入在一个匿名函数中,例如

function anonymous()
{
onclick="exportData(workOrderSearchForm)";
}

如果您想在例如“exportData(workOrder”上挂钩,需要使用Instr()函数或类似函数进行考虑。

另外非常重要的一点是:给页面足够的时间进行导航和DOM对象的加载。我注意到在我的公司中,一旦页面发生变化,加载时间有时会大幅增加。

我通过以下方法取得了不错的成功:

Sub MyMainSub()
Dim Browser As SHDocVw.InternetExplorer
Dim HTMLDoc As MSHTML.HTMLDocument
' my other Dim's

    ' start browser
    Set Browser = New SHDocVw.InternetExplorer
    Browser.navigate "http://www.whatever.com"
    WaitForBrowser Browser, 5           ' wait for browser, but not more than 5 sec

    ' gain control over DOM object
    Set HTMLDoc = Browser.document
    WaitForBrowser Browser, 5           ' wait for browser, but not more than 5 sec

    ' do actions
    ' FormAction HTMLDoc, w, x, y, z

End Sub


Sub WaitForBrowser(Browser As SHDocVw.InternetExplorer, Optional TimeOut As Single = 10)
Dim MyTime As Single

    MyTime = Timer                   ' seconds since midnight
    Do While Browser.Busy Or (Timer <= MyTime + TimeOut)
        DoEvents                     ' go do something else
    Loop

    If Browser.Busy Then
        MsgBox "I waited for " & Timer - MyTime & " seconds, but browser still busy" & vbCrLf & _
               "exititing Login sequence now"
        End
    End If
End Sub

希望这足够激励你去创造自己的解决方案。
祝好,MikeD。

哇,你的FormAction函数真的很有用!谢谢。 - cyberponk
您可以将Attrib设置为“outerHTML”,并从对象中搜索确切的HTML标记,例如<input onclick="toggleCheck();" type="checkbox"> - cyberponk

0

就像这样:

ie.window.exportData(ie.document.forms.workOrderSearchForm)

不幸的是,它说这不是一个支持的方法或属性。一旦我把它放进去,它也会将代码空格排列成这样“ie.Window.exportData (ie.Document.forms.workOrderSearchForm)”。 - Michael
尝试使用ie.window.exportData ie.window.workOrderSearchFormie.window.eval "exportData(workOrderSearchForm)" - SLaks
这两个似乎都不起作用。它们产生相同的错误。 - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接