VBA跨页面按钮点击遇Run-time error 91问题求助
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
- 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. - 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 accessingIE.Documentdirectly. - Incomplete page load checks: The
ReadyStatecheck 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-2on 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
相关产品推荐
相关产品推荐

