OPERATION OF THE EXPLORER VIA VBA

Asked

Viewed 2,678 times

2

Good morning, I’m starting to work with VBA so my doubt may be very basic, but my problem is the following: When I run the code (below) it looks like an error alert on the 'For each' line'

"Runtime error '438'. Object does not accept this property or method"

The code is analogous to another one I took from a friend, just making the relevant changes and his is working.

Sub TesteBusca()

Dim ie As Object
Dim sWindows As Object
Dim sJanelas As Object
Dim sDados As String


Set ie = CreateObject("InternetExplorer.Application")

ie.navigate "http://sdro.ons.org.br/SDRO/DIARIO/index.htm"
ie.Visible = True

    Do Until (ie.readyState = 4 And Not ie.Busy)
        DoEvents
    Loop

i = 1
For Each link In ie.document.getElementByTagName("a")

    If Mid(link.href, 8, 22) = "EnergiaNaturalAfluente" Then
    i = i + 1

       With iefat
           .Visible = bMostrarNavegador
           .navigate link.href
       End With

       Do Until (iefat.readyState = 4 And Not iefat.Busy)
         DoEvents
       Loop
    link.Click
    If i = 2 Then Exit For
    End If

Next link


End Sub

Thank you in advance, Abs.

  • Your friend’s is on the same site? Because in this da ons, I believe you have an iframe... Then the DOM code would change.

  • No, the website he used was this "http://sys.sigetplus.com.br/cobranca/transmitter/1191/invoices?agent=5111". How should I open the link then?

1 answer

3


Code

You can accomplish this with this code:

'Declara função Sleep
#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'For 32 Bit Systems
#End If

Sub TesteBusca()

    Dim IE As Object
    Dim sWindows As Object
    Dim sJanelas As Object
    Dim sDados As String
    Dim doc As MSHTML.HTMLDocument

    Set IE = CreateObject("InternetExplorer.Application")

    IE.navigate "http://sdro.ons.org.br/SDRO/DIARIO/index.htm"
    IE.Visible = True

    EsperaIE IE, 2000

    'Debug.Print IE.document.getElementsByTagName("frame")(1).contentDocument.getElementsByTagName("a").innerText
    i = 1
    For Each link In IE.document.getElementsByTagName("frame")(1).contentDocument.getElementsByTagName("a")
    'Debug.Print EXTRAIRELEMENTO(link.href, 8, "/")
        If EXTRAIRELEMENTO(link.href, 8, "/") = "21_EnergiaNaturalAfluente.html" Then
            i = i + 1


            link.Click
             EsperaIE IE, 2000
            If i = 2 Then Exit For
        End If

    Next link   
End Sub

Public Sub EsperaIE(IE As Object, Optional time As Long = 250)
'Código de: https://stackoverflow.com/questions/33808000/run-time-error-91-object-variable-or-with-block-variable-not-set
Dim i As Long
Do
    Sleep time
    Debug.Print CStr(i) & vbTab & "Ready: " & CStr(IE.READYSTATE = 4) & _
                vbCrLf & vbTab & "Busy: " & CStr(IE.Busy)
    i = i + 1
Loop Until IE.READYSTATE = 4 Or Not IE.Busy
End Sub

Function EXTRAIRELEMENTO(Txt As String, n, Separator As String) As String
    On Error GoTo ErrHandler:
    EXTRAIRELEMENTO = Split(Application.Trim(Mid(Txt, 1)), Separator)(n - 1)
    Exit Function
ErrHandler:
    ' error handling code
    MsgBox "Erro, veriique os dados de entrada."
    EXTRAIRELEMENTO = CVErr(xlErrNA)
    On Error GoTo 0
End Function

Explanation

Extract Element

The User Defined Function (UDF - User Defined Function) of extract element is declared to extract the elements of a string separated by a separator, in this example "/", where each element has an index.

This uses the function Split to split the string into multiple elements from a separator.

And the function Trim is used to avoid errors when space is used as a separator, as this function removes the spaces from the beginning and end of the string.

Example: EXTRAIRELEMENTO("http://sdro.ons.org.br/SDRO/DIARIO/2018_03_15/Html/DIARIO_15-03-2018.xlsx", 1, "/") returns the value http:

Other Example: EXTRAIRELEMENTO("http://sdro.ons.org.br/SDRO/DIARIO/2018_03_15/Html/DIARIO_15-03-2018.xlsx", 2, "/") returns the value `` or empty

Other:

EXTRAIRELEMENTO("http://sdro.ons.org.br/SDRO/DIARIO/2018_03_15/Html/DIARIO_15-03-2018.xlsx", 3, "/") returns the value sdro.ons.org.br

A very useful function, which can be applied to extract elements of Strings with separators, such as links, directories, product codes, dates, among others.

Wait IE

Normally I use a Soen function to perform the function of waiting a while for the page to load completely, only While IE.Busy Or IE.ReadyState <> 4: Wend may not be enough.

So instead of While IE.Busy Or IE.ReadyState <> 4: Wend You call the function EsperaIE and chooses the waiting time in ms. Example: EsperaIE IE, 5000

Master code

As the ONS site has a hierarchy with iframes and not only the "pure" HTML. You need to search for the "a" tag with: IE.document.getElementsByTagName("frame")(1).contentDocument.getElementsByTagName("a"), where the frame index is (1), index (0) is at the top of the page.

NOTE: Don’t forget to enable references: Microsoft HTML Object Library and Microsoft Internet Controls.

In Tools > References...

Habilitar as Referências

  • Daniel, thank you so much for your help!! Only I could not understand right to part the Extract Element which wants to Split "Split(Application.Trim(Mid(Txt, 1)), Separator)(n - 1)". I tried to execute the code and it appears "Compile error: user-defined type has not been defined" and highlights "doc As MSHTML.Htmldocument". What should I do?

  • 1

    @Leandrolazari I edited the answer, you need to enable the MS HTML Object Library reference. And this is a user-defined function, that is, a custom function created by the user and not native to Excel. It was created to separate the elements, where its input data is Txt, Separator and n. Many functions can be found on the internet and often you don’t need to understand them by complex (it’s good to know how they work), but to save time, you can only know the input data and what values/outputs the function returns.

  • 1

    Very good! Congratulations on the answer.

  • Got it! Thank you first! You’re being a big help! But I’m having another question, my next step would be to click on the icon that downloads the xls file. I tried using the same argument but changing the 'If' of 'For Each': For Each link In IE.document.getelementsbytagname("frame")(1).contentDocument.getelementsbytagname("a") 'Debug.Print EXTRAIRELEMENT(link.href, 8, "/") Link.getscr(attribute") = ". /img/exportxls.gif" Then i = i + 1 But nothing happens. If you can help me one more time...

  • @Leandrolazari I suggest creating a new question and when some user is free will answer it.

  • Okay. Thank you, Daniel!!

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.