Results 1 to 7 of 7
  1. #1
    redbull's Avatar
    redbull is offline Competent Performer
    Windows XP Access 2010 32bit
    Join Date
    Mar 2012
    Location
    Missouri
    Posts
    480

    Pass a HTML string to a function, String doesn't cut it.

    So here's the story. I do a lot of IE automation, and often times I have to confirm that my code is on the correct page. Normally I do this just by searching for innertext. Because webpages are structured differently, sometimes I have to change my statement a little bit. I have a function that allows me to check for innertext on a page, its nice because I can return a true or false and this function just gets loaded into new projects. If it's not flexible, its worthless lol.



    So here is the original Function, it works great as long as the HTML structure matches.

    Code:
    Function ConfirmIE(oie As InternetExplorer, TextNeeded As String, MSecs As Integer, MaxLoop As Integer, Optional AttemptNo As Integer)
    'This is used as a confirmation that IE is actually on the correct page. Its more reliable than readstate waits in IE. Things might need to be 
    'adjusted depending on the page. change innertext to value, or extend out the oie statement to look inside an iframe.
    'Use Example: Loaded = ConfirmIE(oie, "The Inner Text we want to see on the page", 500 ' millisecs, 40 ' Max time to loop through Msecs) 
    'Use Example: If Loaded = False Then GoTo CClick ' loaded is false, it means the text was not found in the maxtime
    
    
    
    LoopCt = 0 ' going from 0 to MaxLoop. 
    If AttemptNo = 3 Then ' This if statement ties into the IEresp, if the user keeps trying to wait for the page the code will kill it on the 3rd attempt. 
    ConfirmIE = False
    Exit Function
    End If  ''''' end of IEresp Attemptcount
    
    
    
    
      Do Until InStr(oie.document.body.innerText, TextNeeded) > 0         ' <~~~~~ this is what I want to be a bit more flexible. 
          Call SleepIE(oie)
          Call AppSleep(MSecs)
            If LoopCt = MaxLoop Then GoTo ExitLoop
          LoopCt = LoopCt + 1
      Loop
    ConfirmIE = True
    GoTo Exit_Sub:
    
    
    ExitLoop:
    Call IEresp(oie, TextNeeded, MSecs, MaxLoop, AttemptNo) ' IEresp is nifty, it will give the users options on how to handle the failed webpage load. But
    'thats a topic for another post. 
    Exit_Sub:
    End Function
    So the code above works great on about 90% of websites, because oie.document.body.innertext usually contains some sort of information that I can confirm the page loaded on. BUT now I'm working on a different website and that oie structure no longer works, because everything is tied into a form. SOOOO the oie structure has to look like this.

    oie.document.forms(0).innertext


    Now I could just swap out the oie statements and everything would work fine, but What I'd like to be able to do is just pass an optional "thing"(because string isn't working) and assign it in the function. Something like this...


    Code:
    Function ConfirmIE(OIE As InternetExplorer, TextNeeded As String, MSecs As Integer, MaxLoop As Integer, Optional AttemptNo As Integer, Optional HTMLString As String ' Or whatever I need to get this bit to work. )
    
    
    'Use Example: Loaded = ConfirmIE(oie, "Important Short Sale Update", 500, 40, "oie.document.forms(0).innertext")   ' This would pass the html structure
    'Use Example: If Loaded = False Then GoTo CClick ' loaded is false, it means the text was not found in the maxtime
    
    
    LoopCt = 0
    If AttemptNo = 3 Then
    ConfirmIE = False
    Exit Function
    End If
    If HTMLString = "" Then HTMLString = OIE.Document.all.innerText ' This is new, sets the HTMLstring... but apparently string doesn't do it. 
    
    
      Do Until InStr(HTMLString, TextNeeded) > 0   ' This instr would use the structure that was passed. 
          Call SleepIE(OIE)
          Call AppSleep(MSecs)
            If LoopCt = MaxLoop Then GoTo ExitLoop
          LoopCt = LoopCt + 1
      Loop
    ConfirmIE = True
    GoTo Exit_Sub:
    
    
    ExitLoop:
    Call IEresp(OIE, TextNeeded, MSecs, MaxLoop, AttemptNo)
    Exit_Sub:
    End Function


    Now I've tried to pass that html structure as a string but it doesn't work. I started looking into the HTML reference library and the Microsoft internet controls library and I am not having any luck.

    So I guess the big question, to summarize is how should I pass the html structure into my function, what should I call it as? Or should I just build a list of oie structures in the function to try on error?


    I. Hate. Mondays.

  2. #2
    orange's Avatar
    orange is offline Moderator
    Windows 10 Access 2010 32bit
    Join Date
    Sep 2009
    Location
    Ottawa, Ontario, Canada; West Palm Beach FL
    Posts
    16,716
    Can you post a sample/demo data base that actually calls your function with a URL so we can experience the issue?
    I'm not a big user of HTML innertext etc, but am interested.

  3. #3
    redbull's Avatar
    redbull is offline Competent Performer
    Windows XP Access 2010 32bit
    Join Date
    Mar 2012
    Location
    Missouri
    Posts
    480
    All unnecessary words. Example is below.

  4. #4
    redbull's Avatar
    redbull is offline Competent Performer
    Windows XP Access 2010 32bit
    Join Date
    Mar 2012
    Location
    Missouri
    Posts
    480
    So here is a fully functioning example. It will open an IE window to THIS website. There are 3 IE checks. The first two have hardcoded HTML structure, the first one will fail. The second one is successful. The last one is trying to pass the HTML structure to the function as a string. The code will execute, but the innertext is never found.

    Just copy/paste this into a new module. Make sure "Microsoft Internet Controls" and "Microsoft HTML Object Library" libraries are enabled.

    Sorry for the wall of text.


    Code:
    Private Declare Sub AppSleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
     
    Public Sub PauseApp(PauseInSeconds As Long)
        Call AppSleep(PauseInSeconds) 'Used to be actual seconds, but this program doesn't recognize them. OY!
    End Sub
    Option Explicit
    
    
    Sub AccessForumsDemo()
    Dim OIE As InternetExplorer
    Set OIE = New InternetExplorer
    Dim Loaded As Boolean
    
    
    OIE.navigate ("https://www.accessforums.net/index.php")
    OIE.Visible = True
    Call SleepIE(OIE)
    
    
    
    
    
    
    
    
    ''''This Block is using hard-coded HTML structure. And shows why I'd like to be able to pass it in into the function.
    'Failing Test
    Loaded = ConfirmLoaded(OIE, "Access Forums", 500, 10)
    If Loaded = False Then
       MsgBox "This failed because 'confirmloaded' is using oie.document.forms(0).innertext"
    End If
    'Successful Test
    Loaded = ConfirmLoaded1(OIE, "Microsoft Access Forums", 500, 10)
    If Loaded = True Then MsgBox "Access Forums text was found, oh happy day."
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    
    
    
    ''''What I would like to be able to do. ' When "HTMLStruct" is set as a string, the code will execute, but the innertext is never found.
    Loaded = AttemptingFunction(OIE, "Microsoft Access Forums", 500, 10, , "OIE.Document.body.innerText")
    If Loaded = True Then MsgBox "Items found"
    If Loaded = False Then MsgBox "Still not working"
    
    
    
    
    
    
    
    
    
    
    
    
    End Sub
    
    
    
    
    Function ConfirmLoaded(OIE As InternetExplorer, TextNeeded As String, MSecs As Integer, MaxLoop As Integer, Optional AttemptNo As Integer)
    'This is used as a confirmation that IE is actually on the correct page. Its more reliable than readstate waits in IE. Things might need to be
    'adjusted depending on the page. change innertext to value, or extend out the oie statement to look inside an iframe.
    'Use Example: Loaded = ConfirmIE(oie, "Important Short Sale Update", 500, 40)
    'Use Example: If Loaded = False Then GoTo CClick ' loaded is false, it means the text was not found in the maxtime
    On Error GoTo Errs:
    MaxTime = MSecs * MaxLoop / 1000 * AttemptNo
      Do Until InStr(OIE.Document.forms(0).innerText, TextNeeded) > 0
          Call SleepIE(OIE)
          Call AppSleep(MSecs)
            If LoopCt = MaxLoop Then GoTo ExitLoop
          LoopCt = LoopCt + 1
      Loop
    ConfirmLoaded = True
    GoTo Exit_Sub:
    
    
    ExitLoop:
    MsgBox "Timeout Message Box" & vbCr & "TextNeeded = " & TextNeeded & vbCr & "Max wait time in Seconds = " & MaxTime & vbCr & "Oie Page = " & OIE.LocationURL
    Errs:
    If Err.Number = -2147467259 Then
    Debug.Print "Bad HTML structure"
    
    
    End If
    
    
    Exit_Sub:
    End Function
    
    
    Function ConfirmLoaded1(OIE As InternetExplorer, TextNeeded As String, MSecs As Integer, MaxLoop As Integer, Optional AttemptNo As Integer)
    'This is used as a confirmation that IE is actually on the correct page. Its more reliable than readstate waits in IE. Things might need to be
    'adjusted depending on the page. change innertext to value, or extend out the oie statement to look inside an iframe.
    'Use Example: Loaded = ConfirmIE(oie, "Important Short Sale Update", 500, 40)
    'Use Example: If Loaded = False Then GoTo CClick ' loaded is false, it means the text was not found in the maxtime
    
    
    MaxTime = MSecs * MaxLoop / 1000 * AttemptNo
      Do Until InStr(OIE.Document.body.innerText, TextNeeded) > 0
          Call SleepIE(OIE)
          Call AppSleep(MSecs)
            If LoopCt = MaxLoop Then GoTo ExitLoop
          LoopCt = LoopCt + 1
      Loop
    ConfirmLoaded1 = True
    GoTo Exit_Sub:
    
    
    ExitLoop:
    MsgBox "Timeout Message Box" & vbCr & "TextNeeded = " & TextNeeded & vbCr & "Max wait time in Seconds = " & MaxTime & vbCr & "Oie Page = " & OIE.LocationURL
    Exit_Sub:
    End Function
    
    
    Function AttemptingFunction(OIE As InternetExplorer, TextNeeded As String, MSecs As Integer, MaxLoop As Integer, Optional AttemptNo As Integer, Optional HTMLStruct As String)
    'This is used as a confirmation that IE is actually on the correct page. Its more reliable than readstate waits in IE. Things might need to be
    'adjusted depending on the page. change innertext to value, or extend out the oie statement to look inside an iframe.
    'Use Example: Loaded = ConfirmIE(oie, "Important Short Sale Update", 500, 40)
    'Use Example: If Loaded = False Then GoTo CClick ' loaded is false, it means the text was not found in the maxtime
    
    
    
    
    If HTMLStruct = "" Then HTMLStruct = OIE.Document.body.innerText
    
    
    MaxTime = MSecs * MaxLoop / 1000 * AttemptNo
      Do Until InStr(HTMLStruct, TextNeeded) > 0
          Call SleepIE(OIE) ' readywait, ussually works. Not always though.
          Call AppSleep(MSecs) 'Hard pause for so many miliseconds. Adjust MSecs depending on the website
            If LoopCt = MaxLoop Then GoTo ExitLoop
          LoopCt = LoopCt + 1
      Loop
    AttemptingFunction = True ' IF the innertext, innerhtml or whatever we want is found. Its true.
    GoTo Exit_Sub:
    
    
    ExitLoop:
    MsgBox "Timeout Message Box" & vbCr & "TextNeeded = " & TextNeeded & vbCr & "Max wait time in Seconds = " & MaxTime & vbCr & "Oie Page = " & OIE.LocationURL
    Exit_Sub:
    End Function

  5. #5
    orange's Avatar
    orange is offline Moderator
    Windows 10 Access 2010 32bit
    Join Date
    Sep 2009
    Location
    Ottawa, Ontario, Canada; West Palm Beach FL
    Posts
    16,716
    You should use Option Explicit at the top of your modules to ensure all variables are explicitly identified.

    Call SleepIE(OIE)
    is not in the supplied code.

    Is this info of value to you??

  6. #6
    redbull's Avatar
    redbull is offline Competent Performer
    Windows XP Access 2010 32bit
    Join Date
    Mar 2012
    Location
    Missouri
    Posts
    480
    Here is the call sleep thing

    Code:
    Sub SleepIE(OIE As InternetExplorer)
    'Readystate check, not accurate on JS pages or pages with iframes. beware.
    'Use Example: PauseApp 500 ' This waits 1/2 of a second. The program did not like PauseApp 0.5
    On Error GoTo Exit_Sub:
        Do While OIE.Busy: DoEvents: Loop
        Do While OIE.readyState <> 4: DoEvents: Loop
        Do While OIE.Document.readyState <> "complete": DoEvents: Loop
    Exit_Sub:
    End Sub
    Yea I know about option explicit, I'm in a bad habit of leaving it off because I am usually looking at someone elses code.

    I'm reviewing the webpage now.

  7. #7
    redbull's Avatar
    redbull is offline Competent Performer
    Windows XP Access 2010 32bit
    Join Date
    Mar 2012
    Location
    Missouri
    Posts
    480
    Yea, the website shows some basics about navigating IE. I think I need to learn more about the IE reference libraries to figure out what I need to pass the oie structure as. I think...

Please reply to this thread with any new information or opinions.

Similar Threads

  1. Empty String Function
    By Paul H in forum Programming
    Replies: 2
    Last Post: 07-30-2015, 08:48 AM
  2. Replies: 2
    Last Post: 04-05-2015, 06:06 PM
  3. Replies: 2
    Last Post: 09-19-2014, 07:16 AM
  4. How To Pass a String to a Parameter in a Report
    By hammer187 in forum Programming
    Replies: 1
    Last Post: 09-17-2012, 01:44 PM
  5. Replies: 2
    Last Post: 01-14-2012, 05:08 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums