You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA跨页面按钮点击遇Run-time error 91问题求助

Fixing Run-time Error 91 When Clicking Second Button in VBA IE Automation

Hey Mike, let's dig into why you're hitting that Error 91 when trying to click the second button. This error means your code is trying to use an object (Button2) that wasn't successfully found or assigned—so getElementById("seite-itm-2") is returning Nothing. Let's break down the issues and fix this step by step.

Key Issues Causing the Error

  1. Unreliable fixed wait times: Using Application.Wait (Now + TimeValue("0:00:05")) is hit-or-miss. Sometimes the page isn't fully rendered yet when your code tries to find the button; other times it's waiting unnecessarily.
  2. Possible iframe nesting: Looking at your element's class names (urTbsLabelOff, urBtnEmph), this looks like a SAP-based UI, which often uses iframes to embed content. If the second button is inside an iframe, your code won't find it by accessing IE.Document directly.
  3. Incomplete page load checks: The ReadyState check might not account for post-load JavaScript rendering of elements.

Solution Code with Improvements

First, add a helper function to reliably wait for elements to load (instead of fixed waits):

' Helper function: Waits for an element to exist on the page (times out after 10s by default)
Function WaitForElement(targetDoc As Object, elementId As String, Optional timeoutSeconds As Integer = 10) As Object
    Dim startTime As Date
    Dim targetElement As Object
    
    startTime = Now
    Do
        ' Suppress errors temporarily while we check for the element
        On Error Resume Next
        Set targetElement = targetDoc.getElementById(elementId)
        On Error GoTo 0
        
        ' Exit loop if we found the element
        If Not targetElement Is Nothing Then Exit Do
        
        ' Yield control to other processes
        DoEvents
    Loop Until Now > startTime + TimeValue("00:00:" & timeoutSeconds)
    
    Set WaitForElement = targetElement
End Function

Now update your main subroutine with better wait logic and iframe handling:

Public Sub SHAREREPORTING()
 Dim IE As SHDocVw.InternetExplorer
 Dim Button As Object
 Dim Button2 As Object
 Dim iframe As Object
 Dim targetDoc As Object

 Set IE = New InternetExplorerMedium
 IE.Visible = True
 IE.navigate "URL"

 ' Wait for initial page to fully load
 Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop

 ' Locate and click first button
 Set Button = IE.Document.getElementById("b1_pki")
 If Not Button Is Nothing Then
    Button.Click
 Else
    MsgBox "First button (b1_pki) not found!"
    IE.Quit
    Set IE = Nothing
    Exit Sub
 End If

 ' Handle password input (note: SendKeys is fragile—see tips below to replace this)
 Application.Wait (Now + TimeValue("0:00:02")) ' Shorter wait since SendKeys is instant
 SendKeys "mypassword", True
 SendKeys "{ENTER}", True

 ' Wait for post-login page to load
 Do While IE.ReadyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
 Application.Wait (Now + TimeValue("0:00:01")) ' Extra time for JS rendering

 ' Start with the main document
 Set targetDoc = IE.Document

 ' Try to find the second button in the main document
 Set Button2 = WaitForElement(targetDoc, "seite-itm-2")

 ' If not found, check for iframes (common in SAP UIs)
 If Button2 Is Nothing Then
    On Error Resume Next
    ' Try the first iframe (adjust index or use getElementById if you know the iframe's ID)
    Set iframe = targetDoc.getElementsByTagName("iframe")(0)
    On Error GoTo 0
    
    If Not iframe Is Nothing Then
        ' Wait for iframe to load
        Do While iframe.Busy Or iframe.ReadyState <> READYSTATE_COMPLETE: DoEvents: Loop
        ' Switch to the iframe's document
        Set targetDoc = iframe.contentDocument
        ' Try finding the button again in the iframe
        Set Button2 = WaitForElement(targetDoc, "seite-itm-2")
    End If
 End If

 ' Click the second button if found
 If Not Button2 Is Nothing Then
    Button2.Click
 Else
    MsgBox "Second button (seite-itm-2) not found! Check if it's in a different iframe or ID changed."
 End If

 ' Optional cleanup
 ' IE.Quit
 ' Set IE = Nothing
End Sub

Additional Tips to Improve Reliability

  • Replace SendKeys with direct element access: SendKeys is unpredictable if the focus shifts. Instead, locate the password input field and login button directly:
    ' Example: If password input has ID "password" and login button has ID "loginBtn"
    Dim passwordInput As Object
    Set passwordInput = IE.Document.getElementById("password")
    If Not passwordInput Is Nothing Then
        passwordInput.Value = "mypassword"
        IE.Document.getElementById("loginBtn").Click
    End If
    
  • Verify the element ID: Use your browser's dev tools (F12) to inspect the second button and confirm its ID is still seite-itm-2 on the post-login page—some dynamic UIs change IDs between page loads.
  • Check for new windows: If clicking the first button opens a new window, you'll need to switch to that window. Add this after the first button click:
    Dim newIE As SHDocVw.InternetExplorer
    ' Loop through all IE windows to find the new one
    For Each newIE In CreateObject("Shell.Application").Windows
        If newIE.LocationURL = "POST_LOGIN_URL" Then ' Replace with your actual post-login URL
            Set IE = newIE
            Exit For
        End If
    Next
    

内容的提问来源于stack exchange,提问作者Mike Hill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:25:00