I built a very complex SeleniumBasic via VBA via Excel Addin setup that interacts with one of the leading ticketing system websites to scrap and populate data. The system interacts with 90+ different fields/clickables with 3 different pages, 6 different tabs, and nested popups...deployed to 120 users who use the automations about 20 times per day.
And it has been working flawlessly for over a year...
We have just provisioned 20 more users on the same system, and their automations refuse to work.
Here is where I am at with my research:
I am able to manually step through code on the new system and have it successfully go through the entire automation, so the issue probably has something to do with the speed VBA/Selenium is trying to interact with the website.
Once the system is unable to find a field or clickable, it refuses to find any other ones after that.
The way the system is built in order to go as fast as possible is via standard VBA error handling. It fails to find something, it goes to the error handler, the error handler says to wait for one second then try again. Again, this system has been working flawlessly for over a year and is currently working on 120 user's systems.
To see if maybe Selenium was refusing to reload the clickable, I broke out the error handling from a Resume to a Resume Next, and then had a do while loop with a boolean flag to keep trying until it was successful, but after the first failure, it refused to find anything else, including different fields
The one thing the 20 new users have in common is that they are all using v66 of Chrome, whereas all of the systems that are working have old copies of Chrome that are at least 9 months old
Thinking this might be an issue, I grabbed all of the ChromeDrivers and systematically went through one by one to test if we got a different performance with a different ChromeDriver, but all of the ChromeDrivers had the same error
So that is where I stand. I'm wondering if there is some key insight I am missing or a workaround that will get newer versions of Chrome to retry the fields. Or...do I need to try a VBA/Selenium tool other than SeleniumBasic to fix this. Or...do I need to roll back these 20 users to older versions of Chrome.
Thanks for sharing your expertise.
''''Check to see if there are any aliases=================================
For AliasCheck = 2 To AliasCounter + 1
If Hash = Sheets("Temp Subjects & Locations").Range("AY" & AliasCheck) Then
AliasName = Sheets("Temp Subjects & Locations").Range("AY" & AliasCheck)
AliasCount = AliasCount + 1
AliasDisplayName = Sheets("Temp Subjects & Locations").Range("AZ" & AliasCheck)
temp1 = ""
temp2 = ""
Call countryDictionary
'drops the country back into Excel to later remove the dupes
temp1 = Sheets("Temp Subjects & Locations").Range("BA" & AliasCheck)
temp2 = dict(temp1)
Sheets("Temp Subjects & Locations").Range("BG" & AliasCount + 1) = temp2
''''Click to add AKA's names
iframeText = "iframe_win_" & AddParty
robot.SwitchToDefaultContent
robot.SwitchToFrame iframeText
iframeTracker = iframeTracker + 1
iframeText = "iframe_win_" & iframeTracker
robot.SwitchToDefaultContent
robot.SwitchToFrame iframeText
robot.FindElementById("X_SUBJECT_ALTERNATE_NM.X_ALTERNATE_NM").SendKeys (AliasDisplayName)
robot.FindElementById("dijit_form_Button_0").Click
End If
Next AliasCheck
The AddParty variable is a way to track the number of the pop-up we came from.
The iFrameTracker variable is a way to track the number of the pop-up we are going to...the system sequentially numbers its pop-ups...instead of legible names...
The newer systems will make it down to the SendKeys and then decide not to work. On a resume next, it will then refuse to find the OK button ("dijit_form_Button_0")
Here is the code I was playing around with to see if I could get it to retry using a "Resume Next" instead of a "Resume"
robot.FindElementById("X_SUBJECT_ALTERNATE_NM.X_ALTERNATE_NM").SendKeys (AliasDisplayName)
Do While FailRetry = True
FailRetry = False
robot.FindElementById("X_SUBJECT_ALTERNATE_NM.X_ALTERNATE_NM").SendKeys (AliasDisplayName)
Loop
errHandler4:
If errorCounter < 21 Then
Application.wait (Now + TimeValue("00:00:01"))
errorCounter = errorCounter + 1
FailRetry = True
Resume Next
Else
MsgBox "Reached 20 second timeout. Stopping processing."
Exit Sub
End If
Related
I am looking for a way to determine if a user current has multiple instances of an Access database open on their machine. The purpose of this check would be to ensure better session handling.
It is perfectly fine for a user to open multiple instances. There are some elements of our work where this is a necessity, to browse existing records while entering a new one.
I came across this old forum post where a function is given to output a list of the currently open databases in the Workspace. I thought I may be able to adapt this to determine if the same database is open more than once on their machine. However, in testing the function (removing the part that opens a separate database), it always outputs the name of our database twice, regardless of whether I have just one instance open, or two or three.
Here's the adapted code I am using:
Public Sub listDBs()
Dim wrkCurrentWorkSpace As Workspace
Dim i As Integer
Dim strDatabases As String
Set wrkCurrentWorkSpace = DBEngine.Workspaces(0)
For i = 0 To wrkCurrentWorkSpace.Databases.Count - 1
If (i = 0) Then
strDatabases = wrkCurrentWorkSpace.Databases(i).Name
Else
strDatabases = strDatabases & Chr$(13) & Chr$(10) & wrkCurrentWorkSpace.Databases(i).Name
End If
Next
MsgBox strDatabases
Set wrkCurrentWorkSpace = Nothing
End Sub
Am I doing something wrong here?
I have a typical “CDO gmail Email send” macro. It has worked reliably for a couple of years now.
I use a spare gmail account as the address it uses to send from. I want to share the macro with some people. So I will use a different gmail address as the sender.
I have some other spare gmail accounts and also some of the people have registered an account and given me the Username and Password to add to the macro as the sending address.
I have 10 accounts, seven of mine and three registered by others. All work in normal manual use. Three work with the macro, seven don’t.
As far as I can tell. all have identical settings. This includes the unsafe setting of On for “Less secure app access”.
The accounts have been registered at different times over the last two years.
One of the accounts that does not work was registered recently by someone having no previous accounts. One of the accounts that does work has been used almost daily for two years both manually and with the macro.
Two accounts were registered at the same time by two people in my family. They have been used normally/ manually to approximately the same extent for two years, but not previously with my macro. One account works in the macro, the other doesn’t.
These facts suggest to me that the non working accounts have not been blocked for suspected spamming. It seems random which accounts work and which don’t.
Below is a simplified version of the macro. (I can mostly use 465 or 25 as the smtpserverport. The results are almost always identical with either. Only very rarely, one will work whilst the other doesn’t. This seems to depend on the location from which the attempt is made).
The results I get are fairly consistent, including using the macro from different locations and different IP addresses.
I occasionally get security warnings for all accounts when I use the accounts from new locations but I always confirm that “it was me”. After taking this action, I never get security warnings again when using the account at that location. Immediately after such a warning, the account is temporarily blocked but the block is removed after I confirm “it was me”.
Three of the addresses almost always work with the macro. On the rare occasions that they don’t work, a second attempt is usually successful. (Those working addresses have been registered by me sometime in the last two years.)
Seven of the addresses never work with the macro. The error message at the .Send point is always the same:
-2147220975:
Die Nachricht konnte nicht an den SMTP-Server gesendet werden. Der Transportfehlercode lautet 0x80040217. Die Serverantwort lautet not available
An approximate English translation:
-2147220975:
The message could not be sent to the SMTP server. The transport error code is 0x80040217. The server response is not available
(To run the macro below, you must edit to give a real gmailAddress#gmail.com , a real gmailPassword , and real places to send the Email to at the .To and .cc)
Sub Run_gMail_Send_Simplified() ' Run this macro with a valid gmailAddress#gmail.com and gmailPassword and real places to send the Email to at the .To and .cc place
Call gMail_Send_Simplified("gmailAddress#gmail.com ", "gmailPassword")
End Sub
Sub gMail_Send_Simplified(ByVal UsrNme As String, ByVal PsWd As String) '
With CreateObject("CDO.Message") ' ' -------------------* with LCDCW Library ( Linking Configuration Data Cods Wollups) which are used and items configured for the Exchange at Microsoft's protocol therof
Dim LCD_CW As String: Let LCD_CW = "http://schemas.microsoft.com/cdo/configuration/"
.Configuration(LCD_CW & "smtpusessl") = True '
.Configuration(LCD_CW & "smtpauthenticate") = 1
' ' Sever info
.Configuration(LCD_CW & "smtpserver") = "smtp.gmail.com" '
' The mechanism to use to send messages.
.Configuration(LCD_CW & "sendusing") = 2
.Configuration(LCD_CW & "smtpserverport") = 25 ' or 465
.Configuration(LCD_CW & "sendusername") = UsrNme '
.Configuration(LCD_CW & "sendpassword") = PsWd
' Optional - How long to try ( End remote SMTP server configuration section )
.Configuration(LCD_CW & "smtpconnectiontimeout") = 30 '
' Intraction protocol is Set/ Updated
.Configuration.Fields.Update '
'End With ' -------------------* End with LCDCW Library ( Linking Configuration Data Cods Wollups) which are used and items configured for the Exchange at Microsoft's protocol therof
' Data to be sent
.To = "mrlotus123#somemail.com"
.cc = "billandben#someuveremail.com"
.BCC = ""
.from = """gMail_Send_Simplified"" <""" & UsrNme & """>"
.Subject = "Hello from " & UsrNme & " using gMail_Send_Simplified" '
.TextBody = "Hi" & vbNewLine & vbNewLine & "Testing. Please ignore this EMail"
' Do it
On Error GoTo Bed ' Intended to catch a possible predicted error in the next line when running the routine
.send
On Error GoTo 0
Debug.Print "Done " & Format(Now(), "hh mm") & " with Username: " & UsrNme & vbCr & vbLf
End With ' End With CreateObject("CDO.Message") (Rem 1 Library End =======#
Exit Sub
Bed:
Debug.Print "Fail " & Format(Now(), "hh mm") & " with Username: " & UsrNme & vbCr & vbLf & " " & Err.Number & ": " & Err.Description & vbCr & vbLf
End Sub
Any suggestions other than registering accounts and picking out the ones that work?
Is there some setting I may have missed?
Question also posted here:
https://support.google.com/mail/thread/17437986?hl=en&authuser=5
I have the problem solved so I am sharing the solution.
I have now improved the situation from 3 out of 10 accounts working to 11 out of 11 accounts working.
Here are the solution details for anyone else that has a similar problem. I would recommend starting with the solution _4) , as that is the quickest. If that does not solve the problem you will need to look at the others. The others may involve some laborious work.
_1 A strange thing in an old account, which was recently not working in my program and which I had definitely checked many times for Less Secure Apps On.
This account still had in the InBox many old typical Email Warnings from when I had attempted to do things such as logging in different places. ( Often this causes a temporary block, or resetting of Less Secure Apps Off , until you confirm something like “yes, that was me” ). All had been answered by me with “yes it was me”, at least I am 98% sure about that –they all been read, so it is very unlikely that I had ignored them
Never the less , I laboriously re read the Email warnings, and followed the link which almost always confirmed that I had answered, and any given link to the setting showed that it was indeed set to On.
There was one exception : the link showed that the Setting was off. Still looking at any other link or looking in that account settings showed it to be On. But I switched it on anyway, after which the account worked again in my program.
I note that all links in warnings are unique, as they contain information specific to the occurrence which sets off the warning. One explanation of the possible bug is that somehow an answer warning gets set back to unanswered, which blocks the account. The check for validation might be based for some reason on a dynamic process that has all the warnings in a chain, such that all must be answered with yes. This make sense since you can change your answer at a later date. The work around is to re answer all old warnings. In some old accounts I had trashed old Email warnings anymore, so I thought that I could not answer again answer, such that the account would remain blocked, despite showing that it isn’t. But strangely, in the trash folder all old warnings were there despite the default setting of only holding trash for 30 days… https://imgur.com/thNdDaV … very strange, in that screenshot there are entries going back to early 2018, despite the fact that it clearly states there that trash is deleted after 30 days. Other stuff that I trashed is gone.
In future , to be on the safe side, I will archive rather than delete warning Emails, or at least store the link given in it for checking and re setting Less Secure Apps.
_2 Setting suddenly showing (correctly) Off, allowing it to be set to On. Another old account, which was recently not working in my program and which I had definitely checked many times for Less Secure Apps On, suddenly showed Less Secure Apps Off. I then switched it On, and the account worked in my program. This may have been caused indirectly by some of the “cross wire” effects whilst I was looking at effects in other accounts. The moral of this one is not to rely on checking the setting just once, as later it might change for no apparent reason.
_ 3) I mentioned in the original post that my personal telephone cant be used any more to verify a new account, (gmail only allow a few uses for SMS confirmation – they deliberately do not say how many). Mostly that is still the case. On one random attempt during my experiments it worked. The new account then also worked in my program. – Hence I have 11 out of 11 now working, rather than 10 out of 10.
Similar conclusion again here: Don’t rely on the situation being static, some external thing may have some effect giving you a short period to do something that is generally not possible.
_4) Links going to wrong accounts. This mostly happens when I have other accounts open, but occasionally it also happens when I only have one account open.
As example: I get a valid warning based on some activity that I do on an account: https://imgur.com/VTAJOWc , I give it the OK, https://imgur.com/mKskkzx , and I then see a notice informing me that the Less Secure Apps has been set to Off, https://imgur.com/9bNePXf . So I follow the link for further info: https://imgur.com/LpGQYlj , and there after I follow a link to turn Less Secure Apps back on, https://imgur.com/WuMjPml . So far so good – note the account shown in the coloured ball top right is the correct one: https://imgur.com/yj09MsX
Now it gets interesting: I end up at the wrong account: https://imgur.com/T050wP4
That is easy to overlook. The solution here was to ignore links given and go directly to settings on the correct account, preferably soon after you get the warning. If you do not do that, then not only will you possibly not get to set the correct account, but also you possibly get another undesirable effect: sometimes the act of following the ( “crossed” ) link seemed to set off sporadic warnings and setting changes on other accounts !!!
This is all suggesting to me that there is some “cross wire type” bugs somewhere in Google.
_ 5 ) Rogue account getting other accounts warnings. This is related to _4) , but in particular one of my accounts not only got effected by following the “cross wired links” , but also frequently gets the warnings that should go to the other accounts. This happens even when I am not using that account anywhere. Once again this suggests some “cross wiring / leakage” caused by Google tracking what I , personally , am doing
_.______________
The short answer to what the problem was/is, is possibly that Less Safe App access was being blocked/ temporarily tuned Off, but for varied reasons it was not easy to switch it back On, since the obvious way to do that via settings was no use since it was often indicated as already On, and in some cases , just looking at it caused other account settings to change!!
I am slightly put off using gmail in my program. I have some concern that Google in its “spying” has got “cross wires / leakage” and it has grown into an uncontrollable monster that will probably break out of its server and appear in front of me and try kill me …… I actually registered the particular account discussed in _5) when I was away from home in India!!! ………… “…You are experiencing a car accident … The hell I am..” -- https://www.youtube.com/watch?v=L0Fw8TVYBKg
_.__________________-
I think we have all experienced at one time or another that adverts seem to pop up which obviously have got some “inside information” about us, which amongst other sources, may come from some Google “spying” on you . I use the word “spying” loosely – most likely we have agreed to it when agreeing to something without fully reading all the small print.
My recent experience is showing that I can follow links to change settings on one of my Google accounts, and then actually change settings on other accounts, even if I am not logged into these accounts. Further, I can change setting in one of my accounts, and it will cause changes in other accounts. I am not sure if that is supposed to happen. But it certainly does happen to me on some of my computers.
The common thing that is causing this cross wiring may be Google chrome browser. I should say finally that I am using a very old version often , in Vista. Possibly these issues do not arise if you only use a newer version..
Alan
I'm trying to automate T-Code-VA03.
I enter the PO number in PO number text box and press F8.
This prompts a window which contains multiple rows of labels.
My requirement is, I want to select the one with latest date. I tried to record the script for it and below the code.
session.findById("wnd[0]/usr/txtRV45S-BSTNK").text = "123456789"
session.findById("wnd[0]/usr/txtRV45S-BSTNK").setFocus
session.findById("wnd[0]/usr/txtRV45S-BSTNK").caretPosition = 8
session.findById("wnd[0]").sendVKey 8
session.findById("wnd[1]/usr/lbl[49,6]").setFocus
session.findById("wnd[1]/usr/lbl[49,6]").caretPosition = 0
I can see there are labels with indexes. How can I iterate through whole window and take the focus to row with latest date?
With VB script you could try the following:
. . .
session.findById("wnd[0]").sendVKey 8
for i = 6 to 99
on error resume next
session.findById("wnd[1]/usr/lbl[49," & cstr(i) & "]").setFocus
if err.number <> 0 then Exit for
on error goto 0
session.findById("wnd[1]/usr/lbl[49," & cstr(i) & "]").caretPosition = 0
next
Regards,
ScriptMan
If you really need to do something like iterating through window and taking the focus to row with latest date, do not do it with VBA, because you may get into lots of problems.
Having said the one above, try with sendkeys https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-sendkeys-method-excel and send TAB. Then make a code searching for "Item" in your form. After this, send tab 8 times to go to the PO Date. Write the date on a list. Send TAB again 11 times to the next date. Write it on a list. And so, until there are no more dates.
Anyhow, as I mentioned, this is not a great solution. The best way is simply to ask the DB Admin for read-only access to the DB or a customized view. With it, you can make a robust solution, which reads the latest date.
I'm having an issue with some of my SQLite code, 99% of the time the below code works perfectly, but the 1% it doesn't work is leaving me totally baffled.
At times I need to make a copy of all the records in one of my tables to another database, so I run the below code.
Dim DataSet As New DataSet
Dim DataAdapter As SQLite.SQLiteDataAdapter
DataAdapter = New SQLite.SQLiteDataAdapter("SELECT ALL * FROM " & tableName, SQLconnect) 'No Where clause, so we are grabbing ALL the records in the table'
DataAdapter.Fill(DataSet, tableName)
Dim ParamList As New Hashtable
Dim Table As DataTable = DataSet.Tables(tableName) 'tableName is a string sent to the sub where this code is located'
Dim Row As DataRow = Nothing
If Table.Rows.Count > 0 Then 'Skip if there are no records to copy'
Row = Table.Rows(0)
Dim InsertString As String = ""
For n As Integer = 0 To Table.Rows.Count - 1
ParamList.Clear()
InsertString = "INSERT INTO " & tableName & " VALUES("
For i As Integer = 0 To Table.Columns.Count - 1
InsertString = InsertString & "#" & Table.Columns(i).ColumnName
If i <> Table.Columns.Count - 1 Then InsertString = InsertString & ", "
ParamList.Add("#" & Table.Columns(i).ColumnName, Table.Rows(n).Item(i))
Next
InsertString = InsertString & ")"
RunSQLiteCode(InsertString, , DBConnectionNumber, ParamList) 'This runs the SQLite query we just assembled above'
Next
End If
Normally this code works perfectly. But 1% of the time, for some reason not all of the records are getting copied over. Most recently for example I had 23,800 records in a table to copy over, but only 19,567 of them actually made it over to the other database.
Whatever is causing this issue, it seems much more likely to happen when I have thousands of records in a table, though I have had this problem occur when copying as few 43 records, only 15 of them made it over.
There's no reliable way to duplicate this error, which is only making debugging it even more difficult. Even after this issue pops up, if I try doing the exact same steps 10+ times I can't get it to happen again. I've never gotten this error to occur when I'm using break points so that I can investigate it closer.
Nothing else in my code is even touching the databases, or connections to the databases while this code is run either. I haven't had any luck searching the web, or looking very closely at my code for something that could be messing it up and causing records to be forgotten.
I know I didn't accidentally delete all the missing records when this occurs either, because if I look at the table that I'm copying the records from, all the missing records are still there.
So, bottom line, I'm stumped, what could be causing this problem?
Edit: I think I've made some progress at figuring out how to duplicate this issue. It seems if I hover my mouse over the menu item that triggers this event, and click multiple times very rapidly on my mouse, this bug happens about 2/3's of the time.
Now I'm even more baffled how this isn't causing my program to either crash or hit a catch in a try catch statement if attempting to run my click events multiple times is causing this issue.
After more playing around with my code and researching the problem, I'm certain that the issue is caused by double clicking my mouse rapidly when triggering this code.
I'm still not entirely sure how SQLite queries are causing the errors I get, but somehow double clicking fast enough on the button to trigger this code makes it run multiple times, which I'm guessing interrupts my SELECT loop because I'm reusing that data connection before I finish with it.
I added a few lines of code at the very beginning of the click event that triggers all this to run.
Dim oldState As Boolean = Enabled
Enabled = False
If oldState = False Then Exit Sub
The above code seems to fix the double clicking problem by disabling the entire form while the code is running, and causing any extra clicks that run the sub twice to exit the sub immediately. Without the above code I can get this bug to occur about 2/3's of the time by clicking fast enough. With the above code I haven't been able to get the error to occur once after dozens of attempts.
I am writing a macro that will scrape my company's internal SAP site for vendor information. For several reasons I have to use VBA to do so. However, I cannot figure out why I keep getting these three errors when I attempt to scrape the page. Is it possible that this has something to do with the UAC integrity model? Or is there something wrong with my code? Is it possible for a webpage using http can be handled differently in internet explorer? I am able to go to any webpage, even other internal webpages, and can scrape each of those just fine. But when i attempt to scrape the SAP page, i get these errors. The error descriptions and when they occur are:
800706B5 - The interface is unknown (occurs when I place breakpoints before running the offending code)
80004005 - Unspecified error (occurs when I don't place any errors and just let the macro run)
80010108 - The Object invoked has disconnected from its clients. (I can't seem to get a consistent occurrence of this error, it seems to happen around the time that something in excel is so corrupted that no page will load and i have to reinstall excel)
I have absolutely no idea what is going on. The Integrity page didn't make much sense to me, and all the research I found on this talked about connecting to databases and using ADO and COM references. However I am doing everything through Internet Explorer. Here is my relevant code below:
Private Sub runTest_Click()
ie.visible = True
doScrape
End Sub
'The code to run the module
Private Sub doTest()
Dim result As String
result = PageScraper.scrapeSAPPage("<some num>")
End Sub
PageScraper Module
Public Function scrapeSAPPage(num As Long) As String
'Predefined URL that appends num onto end to navigate to specific record in SAP
Dim url As String: url = "<url here>"
Dim ie as InternetExplorer
set ie = CreateObject("internetexplorer.application")
Dim doc as HTMLDocument
ie.navigate url 'Will always sucessfully open page, regardless of SAP or other
'pauses the exection of the code until the webpage has loaded
Do
'Will always fail on next line when attempting SAP site with error
If Not ie.Busy And ie.ReadyState = 4 Then
Application.Wait (Now + TimeValue("00:00:01"))
If Not ie.Busy And ie.ReadyState = 4 Then
Exit Do
End If
End If
DoEvents
Loop
Set doc = ie.document 'After implementation of Tim Williams changes, breaks here
'Scraping code here, not relevant
End Function
I am using IE9 and Excel 2010 on a Windows 7 machine. Any help or insight you can provide would be greatly appreciated. Thank you.
I do this type of scraping frequently and have found it very difficult to make IE automation work 100% reliably with errors like those you have found. As they are often timing issues it can be very frustrating to debug as they don't appear when you step through, only during live runs To minimize the errors I do the following:
Introduce more delays; ie.busy and ie.ReadyState don't necessarily give valid answers IMMEDIATELY after an ie.navigate, so introduce a short delay after ie.navigate. For things I'm loading 1 to 2 seconds normally but anything over 500ms seems to work.
Make sure IE is in a clean state by going ie.navigate "about:blank" before going to the target url.
After that you should have a valid IE object and you'll have to look at it to see what you've got inside. Generally I avoid trying to access the entire ie.document and instead use IE.document.all.tags("x") where 'x' is a suitable thing I'm looking for such as td or a.
However after all these improvements although they have increased my success rate I still have errors at random.
My real solution has been to abandon IE and instead do my work using xmlhttp.
If you are parsing out your data using text operations on the document then it will be a no-brainer to swap over. The xmlhttp object is MUCH more reliable. and you just get the "responsetext" to access the entire html of the document.
Here is a simplified version of what I'm using in production now for scraping, it's so reliable it runs overnight generating millions of rows without error.
Public Sub Main()
Dim obj As MSXML2.ServerXMLHTTP
Dim strData As String
Dim errCount As Integer
' create an xmlhttp object - you will need to reference to the MS XML HTTP library, any version will do
' but I'm using Microsoft XML, v6.0 (c:\windows\system32\msxml6.dll)
Set obj = New MSXML2.ServerXMLHTTP
' Get the url - I set the last param to Async=true so that it returns right away then lets me wait in
' code rather than trust it, but on an internal network "false" might be better for you.
obj.Open "GET", "http://www.google.com", True
obj.send ' this line actually does the HTTP GET
' Wait for a completion up to 10 seconds
errCount = 0
While obj.readyState < 4 And errCount < 10
DoEvents
obj.waitForResponse 1 ' this is an up-to-one-second delay
errCount = errCount + 1
Wend
If obj.readyState = 4 Then ' I do these on two
If obj.Status = 200 Then ' different lines to avoid certain error cases
strData = obj.responseText
End If
End If
obj.abort ' in real code I use some on error resume next, so at this point it is possible I have a failed
' get and so best to abort it before I try again
Debug.Print strData
End Sub
Hope that helps.