Invalid Procedure call

Discussion in 'AutoCAD' started by Irfan, Jun 16, 2004.

  1. Irfan

    Irfan Guest

    error : Invalid Procedure call, Run time Error5

    With acad.ActiveDocument
    For cntr = 0 To .Layouts.Count - 1
    If .Layouts(cntr).Name = "Layout1" Or .Layouts(cntr).Name =
    "Layout1" Then
    .Layouts(cntr).Delete
    End If
    Next cntr
    End With

    I know what the problem is: cntr exceeds the range.
    I have 5 layouts, Ideally for loop should not be executed when cntr is 5 (it
    should stop after 4) but it DOES. I dont understand why, Am doing some basic
    thing wrong ?

    TIA
    irfan
     
    Irfan, Jun 16, 2004
    #1
  2. Most likely so but in the opposite direction. VBA collections tend to be
    1-based rather than 0-based.

    In any event, you can iterate strongly-typed collections with For Each
    which is a bit cleaner and more readable:

    Dim layout As AcadLayout

    For Each layout in ThisDrawing.Layouts
    ...
    Next

    Also, I noticed that you're trying to delete layouts while enumerating
    them at the same time. That's a no-no. Loop through the collection and
    gather your positive hits. Once out of the loop, delete the matching
    layouts.
     
    Frank Oquendo, Jun 16, 2004
    #2
  3. Irfan

    MP Guest

    aside from the problems Frank helped you with re: deleting from a
    collection, I was curious about this line:

    If .Layouts(cntr).Name = "Layout1" Or .Layouts(cntr).Name =
    "Layout1" Then

    why the redundant test?
     
    MP, Jun 16, 2004
    #3
  4. Consider taking a closer look at your code.

    You are using integer indices to reference
    elements of a collection. If you delete an
    element, the index of each element past it
    decrements by one. So, each time you delete
    an element, you skip over the next element.



    AutoCAD based Security Planning Solutions:
    http://www.caddzone.com/securityplanning
     
    Tony Tanzillo, Jun 16, 2004
    #4
  5. Irfan

    Irfan Guest

    what i effectively wanted is to delete the layouts named layout1 and layout2
    from layouts collection.
    Is their a nicer why than what i am doing? although i agree with using for
    each.....

    irfan
     
    Irfan, Jun 16, 2004
    #5
  6. Irfan

    Jeff Mishler Guest

    Then you should have layout1 & layout2 in the OR condition. What you posted
    lists layout1 twice.

    Jeff
     
    Jeff Mishler, Jun 16, 2004
    #6
  7. Why not just use the Item method?

    On Error resume Next
    Thisdrawing.Layouts("Layout1").Delete
    Thisdrawing.Layouts("Layout2").Delete
    On Error Goto 0




    AutoCAD based Security Planning Solutions:
    http://www.caddzone.com/securityplanning
     
    Tony Tanzillo, Jun 16, 2004
    #7
  8. Think. If you delete a layout in this loop, you are
    changing the index of all subsequent layouts. It
    should be perfectly obvious that you can't do this.

    You can use:

    For cntr = Layouts.Count - 1 To 0 Step -1

    This will process the layouts in reverse order and
    let you delete layouts in the loop.
     
    Tony Tanzillo, Oct 28, 2004
    #8
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.