VBA Internet Explorer自动化-"权限被拒绝"

3
Dim IE as New InternetExplorer
IE.Visible = True

IE.Navigate("http://www.google.com")

Do Until IE.Busy = False
Loop

IE.document.getElementsByTagName("Input")(3).Value = "Search Term"

IE.document.Forms(0).Submit     <------ This line results in error.

错误提示为运行时错误70: '权限被拒绝'。
请不要建议更改代码。代码没有任何问题。这个宏在10台电脑中有9台能够正常工作。这不是时间问题(即使我手动逐步进行,仍然会出现错误)。我知道有其他方法可以声明Internet Explorer对象。我已经尝试使用CreateObject等所有方法。但这些都无关紧要。以管理员身份运行也没有帮助。
这只是问题的简单示例(我们实际上正在自动化更复杂的任务)。所以请不要问“为什么要进行谷歌搜索?”和请不要问“你想做什么”。我需要解决这个问题。我不需要重写我的代码。
我们使用Windows XP、Internet Explorer 7和Office 2003。某些情况下,随机的用户可能无法自动化Internet Explorer。这不是用户的问题,而是计算机的问题。我的意思是,在受影响的计算机上,无论哪个用户登录,都无法自动化。但是同一用户可以使用另一台计算机,一切正常。因此,很可能是本地计算机上的注册表设置或类似设置的原因。我们这里的所有计算机都是相同的设置、规格和软件。
我已经通过谷歌搜索了很多次。不幸的是,运行时错误70似乎是一个包含所有问题的错误,许多用户报告不同症状的错误。在我的情况下,我没有找到解决办法,否则我就不会在这里问了。
我们唯一能解决问题的方法是让IT完全重新加载硬盘上的所有内容。清除刷新,包括操作系统。这样可以解决问题,但也迫使用户将他们的机器重新设置为他们之前的状态,并重新安装所有软件和其他东西。那不是一个好的解决方案。如果没有设置,刷新就不会产生影响。我想知道那个设置是什么(我认为它是一个注册表设置)。
感谢任何帮助。谢谢。

这个问题只在IE7上发生吗? - Siddharth Rout
我一直乐于提高效率,所以欢迎任何建议 :) - Dennis Williams
很好。一个快速的问题。你在美国吗?我的意思是,如果你按Google.com,它会显示Google.com还是重定向到例如(在我的情况下https://www.google.co.in/)? - Siddharth Rout
是的,我在美国。它显示google.com。 - Dennis Williams
抱歉,不确定这是否有帮助,但它听起来非常像可能会触发您问题的事情的类型。http://support.microsoft.com/kb/908356 - Andrew
显示剩余3条评论
8个回答

5

在测试了上述所有建议的解决方法甚至更多之后,我可以肯定这是一个奇怪的 bug ,与 IE 调用子进程时的事件处理有关,只要一个网站上存在不同的安全区域。

言归正传,这里是解决方案:

'Craziest workaround ever due to bugged IE Eventhandling
Do While IE.ReadyState = 4: DoEvents: Loop 
Do Until IE.ReadyState = 4: DoEvents: Loop

在每次导航到新页面或其他可能导致网站重新加载的事件之后,比如点击提交按钮或类似的操作,请添加以下代码���。

Dan建议在你的代码中慷慨地添加DoEvents语句,但这对我来说并没有完全解决问题。相反,我建议在适用的地方添加上述代码。

感谢Dan,没有你的评论,我永远不会想到这个方法!

此方法相比其他建议修复方法的优点简要总结:

  • 如果愿意,可以坚持使用后期绑定(Dim IE as Object)
  • 可以坚持创建InternetExplorer对象(而不是例如InternetExplorerMedium)
  • 无需更改IE的安全区域设置
  • 应用程序中没有不必要的等待时间
  • 消除错误70 - 权限被拒绝
  • 消除丢失的会话,即“运行时错误'-2147417848(80010108)':自动���错误所调用的对象已从其客户端断开连接。”
  • 消除接口问题,即“运行时错误'-2147023179(800706b5)':自动化错误接口未知”

通过此方法,您无需使用以下方法:

  • InternetExplorerMedium对象
  • 一般的早期绑定
  • 对Microsoft Internet Controls的引用
  • 对Microsoft Shell Controls和Automation的引用
  • 奇怪的错误处理
  • 在代码中不需要检查IE.Busy
  • 应用程序.wait或sleep会导致不必要的估计延迟

我之所以包括上述摘要,是因为我看到了所有这些解决方法,并亲自尝试了它们,但都没有成功。

基于OP问题的示例代码:

Dim IE as Object    
Set IE = CreateObject("InternetExplorer.Application")

IE.Visible = True
IE.Navigate("http://www.google.com")

'Craziest workaround ever due to bugged IE Eventhandling
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop

IE.document.getElementsByTagName("Input")(3).Value = "Search Term"
IE.document.Forms(0).Submit     ' this previously crashed

我真心希望这篇文章能帮助未来的读者。对于所有帮忙解决问题的人,祝你们一路顺风。
最好的祝福, Patrick

1
非常感谢您!我的解决方案使用Office 365登录,并进行内部和外部重定向。我一直在使用可怕的重试方法来使其工作。这个解决方案刚刚修复了所有问题! - Casper Alant
确认一下,使用这个解决方法后,整个页面已经被IE解析和渲染了?而且整个DOM树都可以访问? - TechFanDan
根据解决方法,有些情况下 ie.busy 显示为 True。 - TechFanDan

1
这是使用VBA进行Internet Explorer自动化时常见的问题。通常情况下,它似乎发生在加载新页面后。我成功地使用DoEvents、Application.Wait和在加载新页面后将HTMLDocument对象设置为Nothing的组合解决了这个问题。
我在下面提供了示例代码以进行演示:
Option Explicit

Sub IEAutomation()

    Dim IE As InternetExplorer
    Dim html As HTMLDocument
    Dim i As HTMLHtmlElement
    Dim search_bar_id As String
    Dim submit_button_name As String
    Dim search_term As String

    'Define Variables
    search_bar_id = "lst-ib"
    submit_button_name = "btnK"
    search_term = "Learning VBA"

    'Create IE and Naviagate to Google
    Set IE = CreateObject("InternetExplorer.Application") 'Late Binding
    IE.Visible = True
    IE.navigate "http://www.google.com"

    'Wait for IE To Load
    Do While IE.readyState <> READYSTATE_COMPLETE: DoEvents: Loop

    'Create HTMLDocument Object
    Set html = IE.document

    'Enter Search Term into Search Bar and Click Submit Button
    html.getElementById(search_bar_id).innerText = search_term
    Application.Wait Now + TimeValue("0:00:01")
    html.getElementsByName(submit_button_name)(, 1).Click

    'Wait for New Page to Load (** DoEvents Helps with the Permission Issue **)
    Do While IE.readyState <> READYSTATE_COMPLETE: DoEvents: Loop

    'After Page Loads, Reset HTMLDocument Object and Wait 1 Second Before Recreating It
    Set html = Nothing
    Application.Wait Now + TimeValue("0:00:01") '<<< This seems to really help
    Set html = IE.document

    'Print All Elements In H3 Tags to Immediate Window in VBE
    For Each i In html.getElementsByTagName("H3")
        Debug.Print i.innerText
    Next i

End Sub

是的,这是唯一对我有效的解决方案!谢谢你!我尝试了很多……除了这个,其他都似乎不起作用,这个完美无缺。 - user10368025
我很高兴你觉得这篇文章有帮助! - Justin

1

当我自动化IE时,我遇到了同样的错误,但是我没有修复它,而是绕过了它。

  Label1:
         If myIe Is Nothing Then
             Set myIe = CreateObject("InternetExplorer.Application") 
         End If

         myIe.Navigate URL:=imdbLink

    For Each link In myIe.document.Links
         If Right(link.href, 9) = "/keywords" And Left(link.href, 26) = "http://www.imdb.com/title/" Then
                    mKPlot = link.href 'ERROR GENERATES FROM THIS, SOMETIMES...
         End If
    next link



errHandler:
    If Err.Number = 70 Then
        Debug.Print "permission denied for: |" & title & "|"

        myIe.Quit
        Set myIe = Nothing

        Application.Wait Now + TimeValue("00:00:10")

        Resume Label1:

    End If

这不是你想象中的流畅注册表修复,但对我来说很有效。


1
我曾经遇到过完全相同的问题。我有一个自动化IE的脚本,已经运行了一年,一切正常。突然间,我开始收到“权限被拒绝”的错误信息。我做了两件事情,其中一件解决了问题,但我不知道是哪一件。
  1. 我删除了对“Microsoft Internet Controls”的引用,尝试编译项目,重新添加了对“Internet Controls”的引用,并编译了项目。

  2. 在声明InternetExplorer对象时,我删除了'WithEvents'关键字,因为我不需要从IE中捕获事件。

我怀疑是第一种情况,某种方式上引用已经损坏,删除和重新添加它解决了问题。

1
"

重置HTMLDocument对象的解决方案对我也有效,即:

"
'After Page Loads, Reset HTMLDocument Object and Wait 1 Second Before recreating It
Set html = Nothing
Application.Wait Now + TimeValue("0:00:01") '<<< This seems to really help
Set html = IE.document

其他解决方案都没有解决我的问题。


1
以下方法对我有效。我没有进行全面测试,但问题已经没有再次出现。我曾间歇性地遇到错误,但总是在同一时间点。第一个IE实例的控制似乎会消失。不过,可以通过引用第一个实例来创建另一个实例。然后关闭死亡的实例,我们就可以继续进行了。
Set IEa = CreateObject("InternetExplorer.Application")
Set IEa = IE
   'Where IE is the instance that's about to error
SendKeys ("%{F4}")
   'Closes the old window, IE.quit in the code wouldn't work
IEa.Visible = True

希望这对其他人有用,我已经相当沮丧了。

Brian

PS:这是我在stackoverflow上的第一篇帖子,我认为我做对了格式。


0

我在使用MS Access 2010下的VBA自动化Webbrowser控件时,遇到了相同的运行时错误70。当时我的目标是为Content Editable节点设置innerHTML。最初,它完美地工作,但由于某种未知原因,我开始收到“错误70.权限被拒绝”的提示。有趣的是,这个错误似乎来自IE Web Browser控件,而不是MS Access。有时,它没有被VBA错误处理程序On Error捕获。另一个谜团是,当我单步执行代码时,它会工作,但在正常运行时,Webbrowser控件就无法正常工作,但不会引发错误。然而,如果我设置断点,然后在VBA的立即窗格中查询WebBrowser,例如:? DIV.innerHTML,它会引发错误。

以下是失败的代码:

Private Function SetInnerHTML(HTML As String) As String
Dim HTMLEmail As HTMLDocument
Dim DIV As HTMLDivElement
Set HTMLEmail = Me.Email_MainBrowser.Controls("MyBrowser").Object.Document
Set DIV = HTMLEmail.getElementById("MyText")
DIV.innerHTML = HTML ' This is the line that failed

和 OP Dennis 一样,我尝试添加 Sleep 调用并添加函数调用以确保浏览器返回“就绪状态” CurrentState = Me.Form("Email_MainBrowser").Controls("MyBrowser").ReadyState (CurrentState 应为 acComplete)。

以下是我尝试但未解决问题的方法: 1)反编译并重新编译 MS Access 应用程序。 2)添加调用 Win32 sleep 函数以等待 WebBrowser 控件。 3)查询 Webbrowser,以确保它处于导航完成状态。

以下是解决问题的方法: 在引用和自动化 Webbrowser 控件的代码周围大量添加 "DoEvents"。

Dim HTMLEmail As HTMLDocument
Dim DIV As HTMLDivElement
DoEvents
Set HTMLEmail = Me.Email_MainBrowser.Controls("MyBrowser").Object.Document
Set DIV = HTMLEmail.getElementById("MyText")
DoEvents
DIV.innerHTML = HTML
DoEvents

我还没有想出需要的最少数量的DoEvents;可能只需要一个策略性放置的。我仍然检查Webbrowser控件是否处于“导航完成”状态,但我相信这是Webbrowser控件中深层次的错误。这可能永远都不会被修复。


0

帮我试试这段代码。它可以绕过在浏览器中选择/点击任何元素的需求。

我已经为印度测试过了

Sub Sample1() '<~~ Works as expected
    Dim IE As New InternetExplorer
    IE.Visible = True
    IE.Navigate ("http://www.google.co.in/#hl=en&q=" & "Search Term")
End Sub

针对英国

Sub Sample2() '<~~ Works as expected
    Dim IE As New InternetExplorer
    IE.Visible = True
    IE.Navigate ("http://www.google.co.uk/#hl=en&q=" & "Search Term")
End Sub

针对美国,请尝试此方法(由于重定向我的请求,无法测试)

Sub Sample3()
    Dim IE As New InternetExplorer
    IE.Visible = True
    IE.Navigate ("http://www.google.com/#hl=en&q=" & "Search Term")
End Sub

那将解决通过http请求发送GET数据到服务器的情况,但不幸的是我们正在使用大多数内部网站使用POST方法。此外,我们访问的HTML元素远不止表单,而且“权限被拒绝”错误在其中发生了很多次。表单提交只是一个快速的示例,以说明问题。 - Dennis Williams
很奇怪,你的代码第一次对我起作用,然后就开始在另一行出错了。当我使用 Sleep 时,它又开始工作了。你想测试一下吗? - Siddharth Rout
不,我已经测试过了。你无法复制这个问题......我自己都几乎无法复制它,只有在我们公司的某些电脑上才能出现。我甚至让它睡眠了20或30秒,只是为了确保这不是一个时间问题。 - Dennis Williams
不确定您是否看到了这个?http://www.fixerrorcodesnow.com/runtime-error-70-permission-denied - Siddharth Rout
实际上我已经看过那个网站了。那个网站实际上是一个诱骗,旨在让你购买注册表清理软件。那里没有我的问题信息。 - Dennis Williams
显示剩余4条评论

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