How to write (if /= with vb

Discussion in 'AutoCAD' started by T.Willey, Jan 27, 2005.

  1. T.Willey

    T.Willey Guest

    I use lisp mostly, and am looking to increase my knowledge of programming within AutoCad, so this is my first attempt on my own.

    How can you write /= (not equal) in vba? I have seen some methods like

    If Lay <> Document.ActiveLayer Then

    But it doesn't seem to work for me. Any tips and or comments on the code is appreciated as I am still learning.

    Thanks in advance.
    Tim

    Sub ChangeAll2Layer0()
    Dim BlkCol As Object
    Dim BlkObj As Object
    Dim Obj As Object
    Dim LayCol As Object
    Dim Lay As Object

    Set LayCol = ThisDrawing.Layers
    For Each Lay In LayCol
    Lay.Lock = False
    Lay.LayerOn = True
    If Lay = Document.ActiveLayer Then
    Lay.Freeze = False
    End If
    Next


    Set BlkCol = ThisDrawing.Blocks
    For Each BlkObj In BlkCol
    For Each Obj In BlkObj
    Obj.Layer = 0
    Next
    Next

    AcadApplication.ZoomExtents
    ThisDrawing.PurgeAll


    End Sub
     
    T.Willey, Jan 27, 2005
    #1
  2. "<>" is indeed "/=" but only for values. You're comparing objects. VB
    uses the Is operator for that:

    If Not Lay Is Document.ActiveLayer

    Have you considered getting a reference to the active layer or its name
    before entering the loop? That's more efficient.
     
    Frank Oquendo, Jan 27, 2005
    #2
  3. T.Willey

    VBA Guest

    Here is your code tighten up a bit.

    Public Sub ChangeAll2Layer0()
    Dim BlkObj As AcadBlock
    Dim Obj As AcadObject
    Dim Lay As AcadLayer

    For Each Lay In ThisDrawing.Layers
    Lay.Lock = False
    Lay.LayerOn = True
    If Lay = ThisDrawing.ActiveLayer Then
    Lay.Freeze = False
    End If
    Next Lay

    For Each BlkObj In ThisDrawing.Blocks
    For Each Obj In BlkObj
    Obj.Layer = 0
    Next Obj
    Next BlkObj

    Application.ZoomExtents
    ThisDrawing.PurgeAll
    End Sub


    within AutoCad, so this is my first attempt on my own.
    is appreciated as I am still learning.
     
    VBA, Jan 27, 2005
    #3
  4. T.Willey

    T.Willey Guest

    No I didn't think of doing that, but that would be no problem to add. Will test now.

    Thanks.
    Tim
     
    T.Willey, Jan 27, 2005
    #4
  5. T.Willey

    T.Willey Guest

    Thanks for the help all.

    Now I have a different question. The way it is now working is ok, but it doesn't change the attributes of blocks. How can I write an If and statement? I didn't see anything in the help topics with vba or autocad, and couldn't find anything with a quick search of the ng.

    What I'm look for is something like
    If And Obj.ObjectName = "AcDbBlockReference" Obj.HasAttributes = True then

    I tried it this way also, and it doesn't like it.

    If Obj.ObjectName = "AcDbBlockReference" And Obj.HasAttributes = True Then

    Then once that is working, to envoke the method to get the attributes is it just
    Obj.GetAttributes ??

    Here is what I am trying to do, but can't get it to work.
    Set BlkCol = ThisDrawing.Blocks
    For Each BlkObj In BlkCol
    For Each Obj In BlkObj
    If Obj.ObjectName = "AcDbBlockReference" And Obj.HasAttributes = True Then
    For Each AttObj In Obj.GetAttributes
    AttObj.Layer = 0
    Next
    End If
    Obj.Layer = 0
    Next
    Next

    Thanks again.
    Tim
     
    T.Willey, Jan 27, 2005
    #5
  6. This is a collection of block definitions, not block inserts.

    Grab all the blocks in your drawing using a filtered selection set. Then
    you can step through the set as expected.
     
    Frank Oquendo, Jan 27, 2005
    #6
  7. T.Willey

    T.Willey Guest

    I thought that within the block collection the model and paper space blocks resided? If that is true, then wouldn't what I have written search through all model/paper space. Once it comes across a block, then it will test if it has attributes, and if so then it will change them to layer 0 also. That is why I did the double for each call.

    Am I totally off base?
    Thanks for your help, and patience.
    Tim
     
    T.Willey, Jan 27, 2005
    #7
  8. Yes but you're looking for attributed block inserts, not blocks with
    attribute definitions. That's why "AcDbBlockReference" and HasAttributes
    are not working for you.
    No. You'd have to iterate the contents of each layout block. Your
    current code doesn't delve into the layouts at all. It simply asks if
    the layout is a block reference with attributes and moves along when the
    answer comes back "No".
    No, you're just not looking at the right thing. Try this:

    Dim fType(1) As Integer, fData(1) As Variant
    Dim ss As AcadSelectionSet, blkRef As AcadBlockReference

    fType(0) = 0 : fData(0) = "INSERT"
    Set ss = new AcadSelectionSet("ss")
    ss.Select , , fType, fData

    For Each blkRef In ss
    If blkRef.HasAttributes Then
    'Do your thing
    End If
    Next

    Fair warning: this simplistic approach has a couple of gotchas.

    1) You must test for the presence of the selection set or the second run
    will crash.

    2) HasAttributes returns False if the insert has only constant attributes.

    You might consider calling GetAttributes and GetConstantAttributes on
    every block in the selection set. Using a For Next loop to iterate the
    attribute entities will cause your processing code to be called only if
    something is actually returned by those functions, thus alleviating the
    need for error trapping.
     
    Frank Oquendo, Jan 27, 2005
    #8
  9. T.Willey

    fantum Guest

    If Obj.ObjectName = "AcDbBlockReference" And Obj.HasAttributes = True Then

    Please note that the VB "And" operator does not short-circuit. If Obj.ObjectName <> "AcDbBlockReference" then it will still try to evaluate Obj.HasAttributes resulting in a run-time error.
     
    fantum, Jan 27, 2005
    #9
  10. T.Willey

    T.Willey Guest

    For Each AttObj In Obj.GetAttributes

    It doesn't like this line now. I guess it is because Obj.GetAttributes returns as a variant. How would I step though a variant?

    Thanks again.
    Tim
     
    T.Willey, Jan 27, 2005
    #10
  11. T.Willey

    T.Willey Guest

    Thanks for letting me know. I guess I'm to used to lisp.

    Tim
     
    T.Willey, Jan 27, 2005
    #11
  12. T.Willey

    T.Willey Guest

    Here is what I got so far. I found a post that showed one way I'm guessing to work with variants, but when I plugged it in it's not working still.

    Tim

    Set BlkCol = ThisDrawing.Blocks
    For Each BlkObj In BlkCol
    If BlkObj.IsLayout = True Then
    For Each Obj In BlkObj
    If Obj.ObjectName = "AcDbBlockReference" Then
    If Obj.HasAttributes = True Then
    Set AttObj = Obj.GetAttributes
    'For Each AttObj In Obj.GetAttributes
    'above didn't work
    For i = LBound(AttObj) To UBound(AttObj)
    AttObj(i).Layer = 0
    'AttObj.Layer = 0
    Next
    Set AttObj = Obj.GetConstantAttributes
    For i = LBound(AttObj) To UBound(AttObj)
    AttObj(i).Layer = 0
    'For Each AttObj In Obj.GetConstantAttributes
    'above didn't work
    'AttObj.Layer = 0
    Next
    End If
    End If
    Obj.Layer = 0
    Next
    Else
    For Each item In Obj
    item.Layer = 0
    Next
    End If
    Next
     
    T.Willey, Jan 27, 2005
    #12
  13. Drop the 'Set'.
     
    Frank Oquendo, Jan 27, 2005
    #13
  14. T.Willey

    Jeff Mishler Guest

    With all due respect, Frank, IMHO Tim was on the right track. Looping
    through the Blocks collection DOES indeed include the layout blocks. It's
    just his approach to checking the object to see if it is an Insert and, if
    it is, accessing the attributes, was flawed. This code does exactly what Tim
    wanted to do, without the need for selection sets, which is mandatory if
    working with ObjectDBX documents.

    Sub PutAll2Layer0()
    Dim BlkCol As AcadBlocks
    Dim BlkObj As AcadBlock
    Dim Obj As AcadEntity
    Dim BlkRef As AcadBlockReference
    Dim AttRef As AcadAttributeReference
    Dim AttCol As Variant
    Dim I As Integer

    Set BlkCol = ThisDrawing.Blocks
    For Each BlkObj In BlkCol
    For Each Obj In BlkObj
    If TypeOf Obj Is AcadBlockReference Then
    Set BlkRef = Obj
    If BlkRef.HasAttributes Then AttCol = BlkRef.GetAttributes
    For I = 0 To UBound(AttCol)
    Set AttRef = AttCol(I)
    AttRef.Layer = "0"
    Next I
    End If
    Obj.Layer = "0"
    Next
    Next

    End Sub
     
    Jeff Mishler, Jan 29, 2005
    #14
  15. That much was already stated along with why his code did not perform the
    intended task.
    No mention was made of ObjectDBX so I see no need to code for its use.
    Given that, I avoid crawling all of model space and paper space as a
    general rule when I know exactly what I'm looking for.
     
    Frank Oquendo, Jan 29, 2005
    #15
  16. T.Willey

    Jeff Mishler Guest

    ....snip....
    You are correct that no mention was made of ObjectDBX. I just have a habit
    of looking at things for a broader use, and based on Tim's input in the lisp
    customization group he utilizes ODBX so I felt I should point it out.

    However, the next part is where you are throwing an admitted newbie some bad
    information, IMHO. You see, if you go back and look at his original code,
    Tim is changing EVERY entity in EVERY block to layer 0. So he is already
    'crawling' through all of model & paper space, I just showed how he could
    add a check for blockrefs/attributes and change them along the way without
    having to do a selection set AFTER he's already gone through them.

    Now if he was only wanting attributed blocks, then I would agree with you.
    But that is not what he was after.

    Jeff
     
    Jeff Mishler, Jan 29, 2005
    #16
  17. Indeed that may have been the case. I simply answered the question asked
    rather than trying to intuit his purpose.
     
    Frank Oquendo, Jan 29, 2005
    #17
  18. T.Willey

    T.Willey Guest

    I just want to say thanks to everyone who posted. I learned a lot reading what you all said. I like the discussion because I can learn how other people write there code, since I'm only used to writing in lisp format.

    Thanks for all the lessons. ;D
    Tim
     
    T.Willey, Jan 31, 2005
    #18
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.