1

I'm a beginner in VBA and I'm facing problem in selecting country name automatically in web Combo box using cell value from my Excel sheet via loop. It'll be great help if someone could just help me to fix my VBA and XMLHTTP code. My sheet and VBA code is as follows,

Sheet, VBA Code, XML Code below,

1      PP #           Nationality   DOB           Work Permit Number
2      REDACTED       Indian        03/01/1978    ?
3                                                 ?
4                                                 ?
5                                                 ?


Sub MOLScraping()
Dim sht As Worksheet
Dim LastRow As Long

Set sht = ThisWorkbook.sheets("MOL")
LastRow = sht.Cells.SpecialCells(xlCellTypeLastCell).Row

Dim IE As New InternetExplorer, HTML As HTMLDocument, post As Object, URL$

URL = "https://eservices.mol.gov.ae/SmartTasheel/Complain/IndexLogin?lang=en-gb"

For i = 2 To LastRow

With IE
    .Visible = True
    .navigate URL
    While .Busy = True Or .readyState <> 4: DoEvents: Wend
    Set HTML = .document

HTML.querySelector("button[ng-click='showEmployeeSearch()']").Click
Application.Wait Now + TimeValue("00:00:03")  ''If for some reason the script fails, make sure to increase the delay
    
    HTML.getElementById("txtPassportNumber").Value = sht.Range("C" & i)
                  
    HTML.getElementById("Nationality").Focus
    For Each post In HTML.getElementsByClassName("ng-scope")
        With post.getElementsByClassName("ng-binding")
            For i = 0 To .Length - 1
                If .Item(i).innerText = sht.Range("D" & i) Then ''you can change the country name here to select from dropdown
                    .Item(i).Click
                    Exit For
                End If
            Next i
        End With
    Next post
    HTML.getElementById("txtBirthDate").Value = sht.Range("E" & i)
    
    HTML.querySelector("button[onclick='SearchEmployee()']").Click
    
    HTML.getElementById("TransactionInfo_WorkPermitNumber").innerText = sht.Range("G" & i)
    
End With
Next x
End Sub


Sub Get_Data()
Dim res As Variant, QueryString$, ID$, Name$

QueryString = "{""PersonPassportNumber"":""REDACTED"",""PersonNationality"":""100"",""PersonBirthDate"":""01/01/1990""}"

With New XMLHTTP
    .Open "POST", "https://eservices.mol.gov.ae/SmartTasheel/Dashboard/GetEmployees", False
    .setRequestHeader "User-Agent", "Mozilla/5.0"
    .setRequestHeader "Content-Type", "application/json"
    .send QueryString
    res = .responseText
End With

ID = Split(Split(Split(res, "Employees"":")(1), "ID"":""")(1), """,")(0)
Name = Split(Split(Split(res, "Employees"":")(1), "OtherData2"":""")(1), """}")(0)

[A1] = ID: [B1] = Name
End Sub
Community
  • 1
  • 1

1 Answers1

2

Comments:

Here is an example with selenium basic which should be easy to adapt to a loop or even to re-write for Internet Explorer.

You can play around with adding explicit wait times if you choose ( thanks to @Topto for reminding me of those). Examples shown below. The one case where explicit wait, selenium style, didn't seem to work is with Passport #. Here I added a loop to ensure that it was displayed before attempting to update.


References:

The selenium basic wrapper is free. After installation you go VBE > Tools > References > Selenium type library


TODO:

This was to demonstrate the principals. You can easily start the driver and then have your loop pick up variables from the sheet and issue new GET requests.


Code:

Option Explicit

Public Sub MOLScraping()
    'Tools > references > selenium type library

    Dim d As New ChromeDriver                    '<== can change to other supported driver e.g. IE

    Const URL = "https://eservices.mol.gov.ae/SmartTasheel/Complain/IndexLogin?lang=en-gb"

    With d
        .Start
        .Get URL
        .FindElementByCss("button[ng-click='showEmployeeSearch()']").Click

         Do
             DoEvents
         Loop Until .FindElementById("txtPassportNumber").IsDisplayed

        .FindElementById("txtPassportNumber", timeout:=20000).SendKeys "123456"
        .FindElementById("Nationality").SendKeys "ALBANIA"
        .FindElementByCss("td.ng-binding").Click
        .FindElementById("txtBirthDate", timeout:=20000).SendKeys "12/01/20009"
        .FindElementByCss("td.active.day").Click
        .FindElementByCss("button[onclick*='SearchEmployee']").Click

        Stop

        'QUIT
    End With

End Sub

EDIT

No selenium based answer (based on @SIM's answer you referenced)

Option Explicit

Public Sub GetData()
    Dim res As Variant, QueryString As String, Permit As Long, Name As String, i As Long

    Dim passportNumber As String, personNationality As Long, birthdate As String

    Dim sht As Worksheet, lastRow As Long
    Set sht = ActiveSheet

    With sht
        lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
    End With

    For i = 2 To lastRow

        QueryString = "{""PersonPassportNumber"":""" & sht.Cells(i, 3) & """,""PersonNationality"":""" & sht.Cells(i, 4) & """,""PersonBirthDate"":""" & sht.Cells(i, 5) & """}"

        With CreateObject("MSXML2.serverXMLHTTP") 'New XMLHTTP60
            .Open "POST", "https://eservices.mol.gov.ae/SmartTasheel/Dashboard/GetEmployees", False
           ' .setRequestHeader "User-Agent", "Mozilla/5.0"
            .setRequestHeader "Content-Type", "application/json"
            .send QueryString
            res = .responseText
            Debug.Print res
        End With

        Permit = Replace(Split(Split(s, """OtherData"":""")(1), ",")(0), Chr$(34), vbNullString)
        Name = Split(Split(Split(res, "Employees"":")(1), "OtherData2"":""")(1), """}")(0)

        sht.Cells(i, 1) = Permit: sht.Cells(i, 2) = Name
    Next i
End Sub
QHarr
  • 83,427
  • 12
  • 54
  • 101
  • There is an excellent way of using `explicit wait` within `selenium-vba` binding. Check out [this link](https://stackoverflow.com/questions/50238062/unable-to-check-for-availability-of-any-element-removing-hardcoded-delay/50241962#50241962) to see the usage. – SIM May 30 '18 at 11:34
  • @Topto Thanks. I think you can add it as an argument to the find can't you? Doesn't seem to help for first bit but I will have a play. – QHarr May 30 '18 at 11:41
  • @Topto In the end I went with something experimental which worked which was to loop until IsDisplayed. I added in the explicit waits elsewhere so many thanks for the reminder. Appreciated. – QHarr May 30 '18 at 11:48
  • I'm really glade QHarr that showed your interest but I've some limitations that I can't install anything on my PC. and I tried and don't know how to use Selenium and its seems bit complicated for me as I'm not a programmer. However I tried .findelementbyid command it didn't work then I changed it to queryselector("#ID). And I made this code wp.querySelector("#Nationality").Value = "India" wp.querySelector("td.ng-binding").Click but again the problem is same that web page is asking to select nationality. Please help. – Talal Z. Rana May 31 '18 at 07:48
  • Exactly IT doesn't Allow. So is there any other way around? – Talal Z. Rana May 31 '18 at 09:21
  • Nop, Nationality part of the code is incorrect always selecting the 1st option "AFGANISTAN". – Talal Z. Rana Jun 03 '18 at 08:35
  • This code works but I need cell reference Cells(x,y) instead of its value in code, thats my challenge, HTML.getElementById("Nationality").Focus For Each post In HTML.getElementsByClassName("ng-scope") With post.getElementsByClassName("ng-binding") For i = 0 To .Length - 1 If .Item(i).innerText = sht.Range("D" & i) Then ''you can change the country name here to select from dropdown .Item(i).Click Exit For End If Next i End With Next post – Talal Z. Rana Jun 03 '18 at 08:37
  • Please add Cells(2,3) for Passport, Cells(2,4) for nationality, and Cells(2,5) for Date. and please add for loop i=0 to lastrow. – Talal Z. Rana Jun 03 '18 at 08:40
  • It was working with me, check this link: https://stackoverflow.com/questions/50086005/ie-web-automation-how-to-auto-select-value-from-combo-box-using-excel-vba-xml – Talal Z. Rana Jun 03 '18 at 08:51
  • Sorry My mistake, Original code in the link was working but I tried to change the value to cell reference and converted into for loop thats why its not working and this is my challenge right now. – Talal Z. Rana Jun 03 '18 at 08:53
  • @TalalZ.Rana I have written an updated answer based on the link you provided. Please don't include personal details in questions. – QHarr Jun 03 '18 at 09:21
  • I have also upvoted SIM's answer as I have based the second version above on it. – QHarr Jun 03 '18 at 09:32
  • Run-Time error '-2147012894 (80072ee2)': The Operation Timed Out at .send QueryString, I don't have mozilla installed on my PC. – Talal Z. Rana Jun 03 '18 at 09:39
  • @TalalZ.Rana Just comment out that line and it should expect IE and let me know how it goes. – QHarr Jun 03 '18 at 12:55
  • now Run-time Error '9' Subscript out of range the error is coming at ID = Split(Split(Split(res, "Employees"":")(1), "ID"":""")(1), """,")(0) And instead of "Personal Number" I need "Work Permit Number". And I don't know how to change "Otherdata2" in code to get this.I checked on google didn't find any related article. Please recommend a link to learn this. Thanks you helped this far. – Talal Z. Rana Jun 04 '18 at 05:55
  • You should be using the number for Nationality e.g. 100 – QHarr Jun 04 '18 at 06:54
  • I have updated for the work id. For learning see https://codingislove.com/http-requests-excel-vba/ – QHarr Jun 04 '18 at 07:05
  • Everything is woking except this code: Permit = Replace(Split(Split(s, """OtherData"":""")(1), ",")(0), Chr$(34), vbNullString) its not splitting the work permit number properly. and can you recommend me any page to learn split function and how to use " inverted commas while creating query string. – Talal Z. Rana Jun 23 '18 at 07:07
  • Is this now correct? I changed it to return the item you requested. – QHarr Jun 23 '18 at 07:08
  • wow how quick you responded!. I removed extra " inverted commas from querystring and made this code which is not working can you explain whats wrong in this Code: QueryString = "{PersonPassportNumber:"" & sht.Cells(i, 3) & "",PersonNationality:"" & sht.Cells(i, 4) & "",PersonBirthDate:"" & sht.Cells(i, 5) & ""}" – Talal Z. Rana Jun 23 '18 at 07:18
  • Can you help me to resolve this problem as well. https://stackoverflow.com/questions/50999540/ie-web-automation-how-to-enter-catcha-while-using-new-xmlhttp-post-request-met – Talal Z. Rana Jun 23 '18 at 08:55