Office 2016 VBA 无法打开 Internet Explorer shell 窗口,但在 Office 2013 中工作

Office 2016 VBA fails to open Internet Explorer shell window but works in Office 2013

提问人:Keesler Water Walker 提问时间:3/18/2020 最后编辑:Keesler Water Walker 更新时间:3/19/2020 访问量:340

问:

我从我的前任那里继承了这个 VBA 脚本。它在 Excel 2013 中对我来说效果很好,直到最近我被告知我可能需要在家工作。快来了解一下,我新访问的 VPN 桌面的 Office 2016 环境不喜欢这个脚本。当它到达时,我不断收到“远程服务器计算机未知或不可用”。.ReadyState <> READYSTATE_COMPLETE

导航没有失败,因为我可以看到它成功导航到 URL 的窗口,并且我可以正确地与它交互。奇怪的是,如果我将 URL 更改为“www.google.com”,我会得到一个有效的就绪状态结果。

我还需要弄清楚如何后期绑定 Shell Windows,以便它同时与 v15 和 v16 库一起使用。

此脚本的目的是自动执行
1.通过 Web 界面
2 打开内部数据库。操作并运行位于网页
3 上的 java 脚本。关闭浏览器窗口而不关闭任何其他浏览器窗口

这可以通过查找页面元素(例如页面上的搜索框或特定按钮)并与之交互来修改以供其他人使用。

编辑:
其他测试显示,暂停和跳过循环并恢复会导致此脚本在 Office 2016 中工作。因此,唯一的问题是没有循环,当脚本尝试运行交互时,页面尚未准备好进行下一步。等待 5 秒钟代替循环创可贴的这个问题。找出无法读取的原因将解决此问题。
DBurlDo WhileIETab1 = SWs.Count.ReadyState

Declare PtrSafe Function apiShowWindow Lib "user32" Alias "ShowWindow" _
            (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Sub OpenWebDB()

Dim ieApp As Object
Dim SWs As ShellWindows
Dim IETab1 As Integer
Dim JScript As String
Dim CurrentWindow As Object
Dim DBurl As String
Dim tNow As Date, tOut As Date

DBurl = "My.Database.url"

Set SWs = New ShellWindows
tNow = Now
tOut = tNow + TimeValue("00:00:15")

If ieApp Is Nothing Then
    Set ieApp = CreateObject("InternetExplorer.Application")
    With ieApp
        .Navigate DBurl
        Do While tNow < tOut And .ReadyState <> READYSTATE_COMPLETE
            DoEvents
            tNow = Now
        Loop
        IETab1 = SWs.Count
    End With
End If

If Not tNow < tOut Then GoTo DBFail

On Error GoTo DBFail
Set CurrentWindow = SWs.Item(IETab1 - 1).Document.parentWindow
JScript = "javascript: DoSomething"
Call CurrentWindow.execScript(JScript)

On Error GoTo 0
SWs.Item(IETab1 - 1).Quit

Set ieApp = Nothing
Set SWs = Nothing

Exit Sub

DBFail:
MsgBox (DBurl & vbCrLf & "took too long to connect or failed to load correctly." & vbCrLf & _
    "Please notify the Database manager if this issue continues."), vbCritical, "DB Error"
SWs.Item(IETab1 - 1).Quit

Set ieApp = Nothing
Set SWs = Nothing

End Sub
VBA Shell Internet-Explorer Office-2016

评论

0赞 Zhi Lv 3/18/2020
尝试使用IE浏览器直接访问DBurl,是否能成功访问?在此链接中,“远程服务器计算机不存在或不可用”错误具有以下原因和解决方案:指定了服务器参数,但无法访问或找到该服务器。有关其他信息,请选择相关项目,然后按 F1(在 Windows 中)或 HELP(在 Macintosh 上)。你可以检查一下。
0赞 Keesler Water Walker 3/18/2020
@Zhi Lv - MSFT:我正在使用的 URL 和服务器处于活动状态。正如我所说,我看到IE页面成功打开,我可以手动与它交互。在 Office 2016 中的其他测试期间,当它到达循环时,我让它暂停。然后我跳过了那个循环并恢复了一切正常。存在此循环是为了确保在继续下一步之前加载页面(如果失败,则超时)。如果由于某种原因尚未加载页面,则没有任何可交互的内容,并且会导致此时失败。Do WhileIETab1 = SWs.Count

答:

0赞 Zhi Lv 3/19/2020 #1

尝试从“执行时”条件中删除。或者,使用 While 语句等待页面完成:tNow < tOut

    While IE.ReadyState <> 4
        DoEvents
    Wend

此脚本的目的是自动执行一个过程 1. 通过 Web 界面在 DBurl 打开一个内部数据库 2. 操作并运行位于网页上的 java 脚本 3. 关闭浏览器窗口,而不关闭任何其他浏览器窗口

此外,根据脚本的意图,我建议您可以引用以下代码(它可以遍历选项卡,并根据标题关闭特定选项卡):

Sub TestClose()
    Dim IE As Object, Data As Object
    Dim ticket As String
    Dim my_url As String, my_title As String

    Set IE = CreateObject("InternetExplorer.Application")
    With IE
        .Visible = True
        .Navigate "https://www.microsoft.com/en-sg/" '1st tab
        .Navigate "https://www.bing.com", CLng(2048) '2nd
        .Navigate "https://www.google.com", CLng(2048) '3rd

        While IE.ReadyState <> 4
            DoEvents
        Wend

        'wait some time to let page load
        Application.Wait (Now + TimeValue("0:00:05"))

        'get the opened windows
        Set objShell = CreateObject("Shell.Application")
        IE_count = objShell.Windows.Count

        'loop through the window and find the tab
        For x = 0 To (IE_count - 1)
            On Error Resume Next
            'get the location and title
            my_url = objShell.Windows(x).Document.Location
            my_title = objShell.Windows(x).Document.Title

            'debug to check the value
            Debug.Print x
            Debug.Print my_title

            'find the special tab based on the title.
            If my_title Like "Bing" & "*" Then
                Set IE = objShell.Windows(x)
                IE.Quit 'call the Quit method to close the tab.
                Exit For   'exit the for loop
            Else
            End If
        Next

    End With
    Set IE = Nothing
End Sub

评论

0赞 Keesler Water Walker 3/19/2020
这个答案有两个问题......1. 正如我所说,就绪状态不会从页面中抓取。这可能是 v16 需要引用其他对象而不是 .2.如果页面无法加载,是否有故障保护。没有它,就有可能出现无休止的循环(或者至少需要比我想等待的时间更长的时间来决定互联网/页面已关闭)。ieApptNow < tOut
0赞 Zhi Lv 3/20/2020
正如您之前所说,如果将 URL 更改为 google site,代码运行良好,我们可以使用就绪状态来检查页面是否已准备就绪,因此。我想这个问题可能与DBurl有关。在 While 语句中,是否可以添加调试来检查 IE 的状态。ReadyState。此外,这里有一个关于 如何使用 vba 等待页面加载,您可以参考它。