Link to home
Start Free TrialLog in
Avatar of TOC-Fried
TOC-Fried

asked on

Trim$ Permission Denied Error

I'm having a problem with this line of code, its in a for.. next loop and produces the stock standard Err 70: Permission Denied.

The page this is referring to has already loaded and should be all well and good. It does work for the first instance, and then fails after that.

Heres the code:
removeme = True
Do While removeme = True

If InStr(1, Trim(ie.Document.documentElement.innerText), "Remove Me", vbTextCompare) <> 1 Then

   For Each link In ie.Document.links
    pagecomplete = False

' THIS IS WHERE I AM GETTING MY ERROR
     If Trim$(link.innerText) = "Remove Me" Then
' WORKS ONCE AND NOT TWICE?
        oldurl = link.href
        link.Click
         Do While ie.Busy <> False
            DoEvents
         Loop
     End If
   
    If ie.Document.links(6).href = oldurl Then
          removeme = False
            Exit Do
   End If
Next

Else
removeme = False
    Exit Do
    End If
Loop



Ok, so the purpose of the program is to click "remove me" all the way down each page one after the other, unless the next link is exactly the one just clicked, Or there is no more Remove Me on that page. So the loop covers for that.

Any ideas as to why Trim$(link.innertext) is causing a permission denied? I know it works without having to set it to Nothing and the words it searches for appears > 40 Times on the one page so that's not an issue.

Googled for hours, at my end with this, I'll give it a boost up depending on the answers, starting at 250.

Avatar of Robberbaron (robr)
Robberbaron (robr)
Flag of Australia image

how about setting the following to find / localise the error

sTemp=link.innertext
    If IsNull(stemp) Then
        'skip
        debug.print "!null!"
      ElseIf stemp = Nothing Then
        'skip
        debug.print "!nothing!"
      Else
         'all ok ?
          debug.print "!" & sTemp & "!"
         If Trim$(link.innerText) = "Remove Me" Then
             debug.print "==OK"
         end if
   end if

may help define what causes the problem
I think that by clicking on the "Remove Me" link once, the Internet Explorer object changes, so that the "Document" would be different:

    For Each link In ie.Document.links


...and then "link" no longer refers to a valid object, so referencing:

    link.innerText

...causes an error.

That's my theory.


Alternatively, what version of Internet Explorer do you have? I've noticed other seemingly-random "Permission Denied" errors on certain versions, that have been resolved in the later service packs.
Avatar of TOC-Fried
TOC-Fried

ASKER

IE 6 SP1 - Only the best for my PC.

robberbaron, will attempt to put your theory into play, seems like it is the only way to find the error.

The page reloads, so For Each Link in ie.document.links, it sends off a link and comes back to the page, and the next link it has to click is the same name, just a different category.
If IsNull(link) Then
    'skip
    Debug.Print link
    Debug.Print "!NULL!"
    Else
    'allok
    Debug.Print link
    Debug.Print "!" & link.innerText & "!"
    If Trim$(link.innerText) = "Remove Me From Interest List" Then
    Debug.Print "==ALL OK==="
    End If
    End If
   

That's what I did do, and it errors out at the first instance of doing anything with the link object
    'allok
    Debug.Print link

That gave the same permission denied error, what permission could it be missing? I am Administrator, does the same error on any other PC as well. It is definitely something to do with referencing link, but if you all have some spare time, I have another open question (related to this) that I also want to get sorted. Maybe someone could at least give me some advice as to wether anything could be done differently, if I am going the wrong way about it. Otherwise, what could be the problem? I have used this same method and five other applications and it has not failed. Always has worked a treat.
link is an object. you cant print it.
thats why i created a string variable to hold link.innertext which is a string property.

you can then print this.   or alteranively, make sure u use debug.print link.innertext

I have a suspicion that burbble is onto something as well......
Hmm I never dismissed that one either, but it has worked in other cases where the page has changed, it goes past two URLs in this case though, one to actually remove, then the next one shows the actual page.

Any ideas on a way around his suggestion then?
what happens when u remove the debug.print link statement ?
Do you get meaningfull results ?
I changed it to innerText, same result.
Commented it out, the next link, Debug.Print "!" & link.innerText & "!" same error.
Commented it out, and end up with "If Trim$(link.innerText) = "Remove Me" Then " saying its a Permission Denied error, and this is only happening after the first one successfully loops through without a problem.

Any more info? Any other way of acheiving the same result?
Increase in points due to the constant responses robberbaron has been providing. I do hope there is at least another way of doing this, the URL's themselves are too complex and consist of changing value to just navigate directly to the remove URL.
something seems to be wrong with the link item.  try to make sure link is not a reserved word... MS have done this before
a few cuts from MSDN....
    For A objects to appear in the collection, they must have a name and/or id property.


try .....
   msgbox "Link count=" & ie.document.links.length

   For Each xx In ie.Document.links
    msgbox "link id:" & xx.innerhtml
    msgbox "link id:" & xx.innertext
   
  Next

... this gets rid of everything u want to do but should show the details of all A & AREA tags.

i'm scratching the bottom of the barrel :-<
where do you put yor routine?

Have you put in DocumentComplete event?

ie


Private Sub ie_DocumentComplete(ByVal pDisp As Object, URL As Variant)

If (pDisp = ie) Then
'check you link here
End If
End Sub
Ok, I'll release most of the source for you, but remember all values have been edited to better protect the whole applications true purpose.


Public WithEvents ie As InternetExplorer
Public tstart As Date
Public tend As Boolean
Public dbMyDB As Database
Public rsMyRS As Recordset
Public removeme As Boolean
Public oldurl As String
Public link As Object

Public Sub Form_Load()
txtcount = ""
Me.Visible = True
Set dbMyDB = OpenDatabase("DatabaseName.mdb")
Set rsMyRS = dbMyDB.OpenRecordset("MyTable")
Set ie = New InternetExplorer
ie.Visible = True
rsMyRS.MoveFirst
While Not rsMyRS.EOF
  Text1.Text = rsMyRS!MyField
ie.Navigate2 ("First URL to logout") <--- The site its for allows logouts even if you are not logged in.
tend = False
tstart = Now
Do While tend = False
    DoEvents
        If (DateDiff("s", tstart, Now) > 30) Then  <----------Wait Until Ie_documentComplete event fires that Tend is true or 30 seconds has passed.
            Exit Do
       End If
Loop
ie.Navigate2("Next URL to login page") <--- Login
 tstart = Now
 tend = False
 Do While tend = False
            DoEvents
                If (DateDiff("s", tstart, Now) > 20) Then
                    Exit Do
            End If
 Loop
 ie.Document.All.Item("login").Value = Text1.Text
 ie.Document.All.Item("enter").Click


<WAIT LOOP HERE>

For Each thing In ie.Document.All
   If thing.tagName = "IMG" Then
        If thing.src = "URL OF IMG" Then
            thing.Click
        End If
    End If
Next

Yeh, yeh, thing isn't a programmatic term, but I searched for ages for a method of doing this.

removeme = True
Do While removeme = True
'I search the current document for any instance of Remove Me, so that if the page in view does not have remove me on it, the application can skip ahead.
If InStr(1, Trim(ie.Document.documentElement.innerText), "Remove Me", vbTextCompare) <> 1 Then
        If Trim$(link.innerText) = "Remove Me" Then <-- Find the first instance of "remove me"
                 link.Click <--- and click it
<WAIT CODE HERE>

If ie.Document.links(1).href = oldurl Then
My first attempt at comparing the link to oldurl to see if it's the same, but that's not an issue at this time due to the Permission denied error, I have a 500 Point question still open and awaiting an answer, but can't continue til this is done.
   removeme = False
   Exit Do
   End If
Next
Else
Continuing our InStr above, if it can't find "Remove Me" It goes to this here and Exits the loop for now.
removeme = False
    Exit Do
    End If
Loop

Wend <-- Loops while EOF is false (Exactly what I want.)

End Sub

Private Sub ie_DocumentComplete(ByVal pDisp As Object, URL As Variant)

   If (pDisp Is ie.Application) Then
   oldurl = URL
   tend = True
End Sub

BTW folks, with your answers, what's pDisp's purpose? What does it do exactly?


The other thing to consider with this application is that mWait is a module that I have included to allow the application to stop executing after a set time has been reached, I don't want a google bot, just a bot to do a lot of work for me, slowly. But, still doing it! I don't employ quitters, why should I deploy one?
This is also rather urgent, I would give more points if I could...
>>BTW folks, with your answers, what's pDisp's purpose? What does it do exactly?

That's will make sure entire html are downloaded and loaded
Ok. Ta, Just waiting on a response to my code.
It's been a fair while since I have had any helpful responses to this, please, if you have the spare time, post your responses in relation to the above code.. Anything not so obvious that I have forgotten?
Instead of :
   For Each link In ie.Document.links

can you use?:
for i = ie.Document.links.Count to 1 step -1
What does that do differently?
The ".document" object changes after the "click" is processed, so, the loop and all the references to ".document" need to be restablished.

Your loop:

For Each thing In ie.Document.All
   If thing.tagName = "IMG" Then
        If thing.src = "URL OF IMG" Then
            thing.Click
        End If
    End If
Next
will work only the first time, after the thing.Click(), ie.document will be obsolete and not good.
fc:0

fc:)
I've used that heaps of times tho, but none the less you could be right.

What can be done about it?
as  JR2003 suggests, one of the old ways is to work backwards through the loop. This means that changes/deletions to the end dont really effect the items at the top of the list.

to do this you would have to use for i = ie.Document.links.Count to 1 step -1  rather than for each, which is much more elegant.

otherwise, you may have to do refresh after each update. then restart until no updates.
ie process may be...

marker=true                'set a marker to know that a change has been done
do while marker =true
  get document          'get latest copy of document
  marker=false
  for each thing in document
     do click
     marker=true             'set a marker to know that a change has been done
     exit for                     'quit the loop to do a refresh on document
  next thing
loop
Option one:
I think that you need a new outer loop that will process tha page again each time you click a "link", veryfing that no more "remove me" link are in the page.

ie.navigate2("the first original page")
do
     wait for the page to load
     no more  "remove me"?  exit do
     click the first link
loop

Option two:
I'm not sure how smart is the web page you are automating, buy another option is to open a new window with the link, taking the link HREF and navegating a new instance of IE like IE_aux.Navigate2(link.href) (Make sure that the link contains enough info like http://.... for the navigate2  and the link is not  is not just a  "remove.asp") selecting all the links in the first page.

fc:)
Any ideas how I would go about this.. I don't need it to be fast as I want it to be accurate, but rather then doing all that, how about I get around it this way, need some coding help though folks ( :-( )

One loop goes through, finds all the remove me links on that page.

Then, it creates a new ie instance, then:

using the new instance, it navs to each remove me url, waiting on doc complete to fire each time, then when the end is done closes the new IE instance, and from original I get back to what I want..

Now I can assume a lot as you can see how far I have come, is my theory possible? and if so, all I need to know is..

How to get all the remove me links into one single list..

How to set a new ie window for nav to those links,

how to destroy that instance, unless it's ie1.quit set ie1 = Nothing...

How to determine that the list is at the end and get an event back to continue the rest of my application..

give me what is easiest for you, and the next question I see you all in, I will definitely give you a lot more credit! - Poinx for all!!!

Thanks to all for your helps, I await just some help on the major items in my rather mixed list!
Cheers!
I sorted that out, I opened a new project and copy and pasted all my controls and code, and whoaa.. it worked.

Maybe it was a VB6 bug.

Anyways, you have all helped so much, I don't think any of you should go empty handed and this question had some valid answers, so I'll give the points to the person who can answer this one for me!

I want to limit the amount it clicks, by causing it to wait after 10 clicks, give me that, and they are as good as yours.
ie:

If its clicked Remove Me 10 times, it's gotta wait about 900 using the mWait module I have. All I need is a way of counting the clicks.

Thanks to all your help too!
ASKER CERTIFIED SOLUTION
Avatar of Robberbaron (robr)
Robberbaron (robr)
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
okies sorry for the delay, my other question is opened, and since then I have solved this error using parts of robberbaron's suggestion, so it'll go to him.

My other question is still open for those of you who might have an idea on what we can do to sort that out.