VBA XMLHTTP Pagination Issue - Can't get past the second page of search results

北慕城南 提交于 2019-12-08 07:07:15

问题


I'm developing VBA code to help keep an Excel workbook synced with a web invoicing service at https://www.fel.mx/CFDI33/Presentacion/Usuario/Ingreso.aspx

I developed some working functionality using an Internet Explorer object and decided to try my luck migrating it to XMLHTTP to hopefully get better performance and reliability. The functionality I'm working on right now is simply to login to the web service and get a list of all the cancelled invoices

As of now, I'm able to get past the login screen, navigate to the invoice registry, filter the list of invoices by "Cancelled" state and navigate to the second page of results. The problem I'm having (as silly as it sounds) is making it to the third page and beyond (I know for a fact there are more pages, I can even get to the last page using the 'last page' button, but not to pages 3 to 'last - 1').

For context, this bit of code will get me past the login screen:

'Define xmlhttp request and html response objects
Dim xmlhttp_request As Object
Dim html_response As HTMLDocument

Set xmlhttp_request = CreateObject("Msxml2.XMLHTTP")
Set html_response = CreateObject("htmlFile")

'Get FEL login website html. We need this to later URL encode our POST data including the _EVENT params and our login credentials
With xmlhttp_request: .Open "GET", FEL_WEBSITE_LOGIN, False: .send: End With

'Put the xmlhttp responsetext in our html object
html_response.body.innerHTML = xmlhttp_request.responseText

'URL encode our password
encoded_password = WorksheetFunction.EncodeURL(FEL_PASSWORD)

'Prepare our POST data string
'We include the encoded _EVENT params, our login credentials and the login button item
post_data = _
    "__VIEWSTATE=" & WorksheetFunction.EncodeURL(html_response.getElementById("__VIEWSTATE").Value) & _
    "&__EVENTVALIDATION=" & WorksheetFunction.EncodeURL(html_response.getElementById("__EVENTVALIDATION").Value) & _
    "&txtUsuario=" & FEL_USERNAME & _
    "&txtCuenta=" & FEL_USERNAME & _
    "&txtContrena=" & encoded_password & _
    "&btnInicioSesion=Iniciar sesión"

'POST our xmlhttp request including our post data
With xmlhttp_request
    .Open "POST", FEL_WEBSITE_LOGIN, False
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    .setRequestHeader "Content-Length", Len(post_data)
    .send (post_data)
End With

Then this will get me to the first page of results filtering invoices by every month of 2017 in "Cancelled" state:

With xmlhttp_request: .Open "GET", FEL_WEBSITE_CFDI_REGISTRY, False: .send: End With
html_response.body.innerHTML = xmlhttp_request.responseText

post_data = _
    "__VIEWSTATEENCRYPTED=" & _
    "&__VIEWSTATE=" & WorksheetFunction.EncodeURL(html_response.getElementById("__VIEWSTATE").Value) & _
    "&__EVENTVALIDATION=" & WorksheetFunction.EncodeURL(html_response.getElementById("__EVENTVALIDATION").Value) & _
    "&ctl00$ContentPlaceHolder1$ddlMes=Todos" & _
    "&ctl00$ContentPlaceHolder1$ddlAno=2017" & _
    "&ctl00$ContentPlaceHolder1$ddlEstadoComprobante=1"

With xmlhttp_request
    .Open "POST", FEL_WEBSITE_CFDI_REGISTRY, False
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    .setRequestHeader "Content-Length", Len(post_data)
    .send post_data
End With

Then, after that I can do this to get to the second page:

(In fact I think what I'm doing here is filtering results again and then going to the next page, rather than just going to the next page from the previously filtered results. Herein I think lies part of the problem; read on for more details)

html_response.body.innerHTML = xmlhttp_request.responseText

post_data = _
    "ctl00$ContentPlaceHolder1$ddlDia=Todos" & _
    "&ctl00$ContentPlaceHolder1$ddlMes=Todos" & _
    "&ctl00$ContentPlaceHolder1$ddlAno=2017" & _
    "&__VIEWSTATE=" & WorksheetFunction.EncodeURL(html_response.getElementById("__VIEWSTATE").Value) & _
    "&__PREVIOUSPAGE=" & WorksheetFunction.EncodeURL(html_response.getElementById("__PREVIOUSPAGE").Value) & _
    "&__EVENTVALIDATION=" & WorksheetFunction.EncodeURL(html_response.getElementById("__EVENTVALIDATION").Value) & _
    "&__VIEWSTATEENCRYPTED=" & _
    "&ctl00$ContentPlaceHolder1$pagCFDI$btnSiguiente="

With xmlhttp_request
    .Open "POST", FEL_WEBSITE_CFDI_REGISTRY, False
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    .setRequestHeader "Content-Length", Len(post_data)
    .send post_data
End With

And that's as far as I get. After that I can't for the life of me get to the third page. I thought I could just resend the same POST request but that just returns page 2 again.

As you can imagine I am just starting to dabble in XMLHTTP so this is still a little unfamiliar to me.

It feels to me that what I need is either:

  1. To send that same POST request but to the response URL of the previous POST request instead of to FEL_WEBSITE_CFDI_REGISTRY again (There doesn't seem to be a responseURL property in the XMLHTTP object), or
  2. Perhaps I need to handle some kind of cookie to help the XMLHTTP object keep track of the current page.

Can anyone see what I'm missing?

来源:https://stackoverflow.com/questions/50189303/vba-xmlhttp-pagination-issue-cant-get-past-the-second-page-of-search-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!