0

good afternoon!

I'm trying to run a Macro that opens a website, login, select an option in the menu, fill a text-box and click another button.

So far, I can open the website, login, select the option in the menu, but I can't get the text-box filled by any means. That text box has a text mask:

Format: 00000-000 Type: Numeric Max Char.: 8 Min Char.: 8

Sub SAVE()


    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
    Application.StatusBar = "Searching"


Sheets("WEB").Visible = True

    Dim IE As New InternetExplorer
    Dim WshShell As Object
    Dim dtInicio As Date
    Dim objIE As New DataObject



    Sheets("SAVE").Select
    Sheets("SAVE").Cells.Clear


S = 2
V = 2

SALVA = 0
Do While Sheets("Adress").Cells(V, 2) <> ""
    IE.Visible = True

    Sheets("WEB").Select
    ActiveWindow.SelectedSheets.Delete
    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets(Sheets.Count).Select
    Sheets(Sheets.Count).Name = "WEB"


'OPEN URL
    IE.navigate "URL HERE"

    While IE.Busy Or IE.readyState <> READYSTATE_COMPLETE
        Sleep (1000)
        DoEvents
    Wend



    IE.Document.forms(0).pUsrLg.Value = "user"
    IE.Document.forms(0).pUsrSn.Value = "password"
    IE.Document.parentWindow.execScript "login();"

    While IE.Busy Or IE.readyState <> READYSTATE_COMPLETE
    Sleep (1000)
    DoEvents
    Wend

    IE.Document.parentWindow.execScript "enviaPage('mod_pesquisa/DisponibilidadeNaoClientes.asp', 'GET', 'True', 'dv_pagina', 'pUsrId=0000050007', 'True', 389, 892);"

    While IE.Busy Or IE.readyState <> READYSTATE_COMPLETE
    Sleep (1000)
    DoEvents
    Wend

The Input I must fill looks like this:

<input name="pCepNr" id="pCepNr" type="text" class="st_cxt_01" style="height: 20px; width: 85px; background-color: #FFEEDD; color: #913A1A;">
Diego Patrocinio
  • 100
  • 1
  • 4
  • 13
  • How are you trying to fill in the text box? Does `IE.Document.getelementbyid("pCepNr").value = "BLAH"` simply not set the value or not show it? – cheezsteak Sep 09 '14 at 17:06
  • Actually I've tried many ways to set it, none worked so far. I've tried as you mentioned, but it results in "Run Time Error 91". – Diego Patrocinio Sep 09 '14 at 17:13
  • What happens when you `Debug.Print` the value? Does that return the same error? Can you even `Set` an object to that element? – cheezsteak Sep 09 '14 at 17:58
  • Yes, it return the same error, and I don't know if I can set an element to to that object, how do I check it? I'm sorry, I'm not a programmer hehe just trying to get it workin.. so I don't know much about VBA.. but what I find weird is that as you can see I can fill the other 2 input forms (pUsrLg and pUsrSn) fine, and they have the same class and all.. the only difference I can notice is the text mask. – Diego Patrocinio Sep 09 '14 at 18:22
  • Does the element exist before the last script you execute? – cheezsteak Sep 09 '14 at 20:12
  • No, the last script loaded a new page where the element is located. – Diego Patrocinio Sep 09 '14 at 20:24

1 Answers1

1

Because the method IE.Document.getelementbyid("pCepNr").value is returning error code 91 (Object not set), I suspect .getElementById is failing to find an HTML element with id="pCepNr"

Please confirm this by trying this in your code:

' snip ...
IE.Document.parentWindow.execScript "enviaPage('mod_pesquisa/DisponibilidadeNaoClientes.asp', 'GET', 'True', 'dv_pagina', 'pUsrId=0000050007', 'True', 389, 892);"

While IE.Busy Or IE.readyState <> READYSTATE_COMPLETE
    Sleep (1000)
    DoEvents
Wend

Dim problemTextBox as Object
Set problemTextBox = IE.Document.getelementbyid("pCepNr")

I suspect it will throw the same error. (EDIT See this question for the Sleep routine.)

Unless you have the wrong id of the element you are looking for, the element simply doesn't exist when you try to access it.

If this script you are running ,

IE.Document.parentWindow.execScript "enviaPage('mod_pesquisa/DisponibilidadeNaoClientes.asp', 'GET', 'True', 'dv_pagina', 'pUsrId=0000050007', 'True', 389, 892);"

is what loads the element and the element doesn't exist before then, then your wait loop is failing to wait long enough for it to load.

I have noticed that for .asp pages IE.Busy or IE.readyState do not always work. You can test that by either stepping through slowing with the debugger and accessing the input box after you know it is loaded or just by forcing a large (10 second) sleep.

If simply your wait loop is exiting before the element is loaded, then you will need a better waiting routine. Here is one that I have used, parts of it are from other questions on SE.

Public Function ElementExists(document as Object, id As String) As Boolean

    Dim el As Object
    Set el = Nothing

    On Error Resume Next
    Set el = document.getElementById(id)

    On Error GoTo 0
    ElementExists = Not (el Is Nothing)

End Function
Public Function WaitForElement(document as Object, ByVal id As String, Optional ByVal timeout As Integer = 3) As Boolean

    Dim start_time As Single
    start_time = Timer

    Do While Not (ElementExists(document, id)) And start_time + timeout > Timer
        DoEvents
    Loop
    WaitForElement = ElementExists(document, id)

End Function

Calling WaitForElement(IE.Document, "pCepNr") will wait no more than 3 seconds for the element to load and will return whether the element is accessible (true|false). 3 seconds is optional you can increase or decrease as you see fit eg (WaitForElement(IE.Document, "pCepNr", timeout:=10).

Community
  • 1
  • 1
cheezsteak
  • 2,731
  • 4
  • 26
  • 41
  • Oh man, you were spot on! It was the sleep time.. I forced a 10 seconds sleep time and it worked right way! Thank you so much for the help, you are the guy! – Diego Patrocinio Sep 09 '14 at 20:50