TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: OcCad on October 31, 2007, 03:08:21 PM

Title: ObjectDBX Xref for block
Post by: OcCad on October 31, 2007, 03:08:21 PM
[Backround] We typically xref all our details to paperspace as to ignore multiple scales on one sheet and creating lots of viewports in paper space. We keep each detail in a separate file, each of which we can paste on any drawing, copy to other projects, and manage as a separate component. It also makes it easy for multiple users to work on details that appear on the same sheet.

I am curious to find a way to create a lisp routine that will access a variable within the xref to scale it down from 1:1 to paperspace scale. I have done a lot of research and it seems as if there is no way (not even through ObjectDBX) to access the dimscale of an unopened drawing.

Also there has been mention of creating dictionaries/libraries that hold the dimscale value (whether it be xdata or xrecords) for all our details in our typical detail library so that they may be accessed later from a lisp routine but would that work for project specific details created later?

Lastly, there has been some light as to opening the xref through DBX, scanning it for a block's scale factor (detail border typically used) and then using that as my variable. Only thing is that I dont know how to, after inserting, find the scale of a nested block with a known name.

My desired result would be to browse for a drawing, attach it through the normal dialouge box (with options such as overlay or attach), after insertion the xref to scale down, then at completion for the command line to tell me what was inserted and to what scale. I'm open to all suggestions. Thank you in advance
Title: Re: ObjectDBX Xref for block
Post by: Guest on October 31, 2007, 04:10:35 PM
What about blocks that react to the drawing's annotations scale??

Oh....wait... what version of AutoCAD are you using??!?
Title: Re: ObjectDBX Xref for block
Post by: mkweaver on November 01, 2007, 07:15:29 AM
One thought I have had, since our workflow is similar, is to select a piece of text/mtext in the block/xref that has(is) the scale factor and scale it from there.  Not quite as nice as being able to scale it as it's attached.

Another method would be to have a block inserted in the detail xref that contains the scale factor, either as an attribute value, or possibly as xdata.  This scale could then be found and used by your insertion routine.
Title: Re: ObjectDBX Xref for block
Post by: Joe Burke on November 01, 2007, 08:40:29 AM

Lastly, there has been some light as to opening the xref through DBX, scanning it for a block's scale factor (detail border typically used) and then using that as my variable. Only thing is that I dont know how to, after inserting, find the scale of a nested block with a known name.


Here's some code which demonstrates use of the XrefDatabase object. It does not use ObjectDBX.

Program flow might be something like this.
1. Check the active drawing for any existing xrefs and make a list of xref names.
   Assign symbol exnamelst to that list.
2. Xref all the details.
3. Step through the blocks collection again looking new xrefs using the existing
   xref name list to eliminate those as below.

Totally untested, but I hope it offers some ideas.

Code: [Select]
  (setq blocks
    (vla-get-blocks
      (vla-get-activedocument
        (vlax-get-acad-object))))
  (vlax-for xref blocks
    (if
      (and
        (eq acTrue (vla-get-IsXRef xref))
        (not (vl-position (vlax-get xref 'Name) exnamelst))
      )
      (vlax-for blk (vla-get-blocks (vlax-get xref 'XrefDatabase))
        (if
          (and
            (eq "KnownBorderName" (vlax-get blk 'Name))
            (equal (setq xscale (vlax-get blk 'XScaleFactor))
                   (vlax-get blk 'YScaleFactor)
                   1e-4
            )
          )
          (progn
            (setq xscale (/ 1.0 xscale))
            (vlax-put xref 'XScaleFactor xscale)
            (vlax-put xref 'YScaleFactor xscale)
            (vlax-put xref 'ZScaleFactor xscale)
          )
        )
      )
    )
  )

If the "KnownBorderName" block is found in an xref, the xref in the active drawing should be scaled
by the inverse of its scale factor.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 12:21:08 PM
Matt W: We use AutoCAD2008 but our detail library has been compiled over the years so they have not been updated with annotative blocks.

Mkweaver: in our most updated typical details we do have a line of text within our detail border that has the scale factor within parenthesis. Only thing is that the entire detail library has yet to be completely updated so the older ones do not. Also our borders are either blocks or dynamic blocks so how would we scan for a line of text? If they were attriburtes, would seem a bit easier.

Joe: How am i to use this code? If i just insert it within what I have already "xscale" does not return me a value? May you please explain more?

Code: [Select]
(defun c:xrs ()
 (vl-load-com)
  (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")
 (INITDIA)
  (command "xattach" pause)

    (setq EntName (entlast))
    (setq EntData (entget EntName))
    (setq InsName (cdr (assoc 2 EntData)))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))
    (setq blocks
    (vla-get-blocks
      (vla-get-activedocument
        (vlax-get-acad-object))))

  (vlax-for xref blocks
    (if
      (and
        (eq acTrue (vla-get-IsXRef xref))
        (not (vl-position (vlax-get xref 'Name) exnamelst))
      )
      (vlax-for blk (vla-get-blocks (vlax-get xref 'XrefDatabase))
        (if
          (and
            (eq "Detail-Bdr" (vlax-get blk 'Name))
            (equal (setq xscale1 (vlax-get blk 'XScaleFactor))
                   (vlax-get blk 'YScaleFactor)
                   1e-4
            )
          )
          (progn
            (setq xscale (/ 1.0 xscale))
            (vlax-put xref 'XScaleFactor xscale)
            (vlax-put xref 'YScaleFactor xscale)
            (vlax-put xref 'ZScaleFactor xscale)
          )
        )
      )
    )
  )
   
   (command "scale" EntName "" InsPoint xscale)

;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)

And if anyone can shed some light on how I might ObjectDBX to search for "Detail-bdr" with if/thens for three possible names that would be great.
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 12:23:51 PM
Do you know how to use ActiveX controls within lisp?  You will need to know this to use ObjectDBX.

ps. Welcome to theSwamp.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 12:30:32 PM
T: No idea :-(
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 01:02:30 PM
T: No idea :-(
Check out the .doc file attached in the first post here. (http://www.theswamp.org/index.php?topic=6697.0)  This will help you get started, and once you do that then you can search for 'ObjectDBX' as there are a lot of examples here using it.  When you don't understand something post back and I'm sure someone will help you through those parts.

The theory to this community is to teach instead of give code.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 01:05:51 PM
Hey, I wanna live not eat for a day. Thanks a bunch!  :wink:
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 01:08:28 PM
Hey, I wanna live not eat for a day. Thanks a bunch!  :wink:
You will get along fine here then.  You're welcome.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 01:21:56 PM
Okay... I'm still pretty fresh to Lisp so with VBA and ActiveX and ObjectDBX things are getting a bit overwhelming. The post covers an example of copying a block from xref into current drawing and it seems as if all the "vla-... " commands are a whole other story. It leads me as far as acquiring my desired blocks but I'm confused about where to go from there. Is there another resource that can give me a list of possible commands like (vla-get-scale, vla-get-scalefactor)? Within Lisp I only know them as group codes like 41,42,43
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 01:30:42 PM
In the help, get to 'Developer Documentation' -> ActiveX and VBA reference -> Properties...

It can be a little confusing going from the help to lisp, but once you know what you are looking for the help is really nice.  For instance 'vla-get-ScaleFactor' is a call to 'get' the property 'ScaleFactor' of an object.  So in the help you would look under the property section for 'ScaleFactor'.

Here is a simple routine that will let you select an entity and will print out what ActiveX controls are available.

Code: [Select]
(defun c:DList ()

(vlax-dump-object
(vlax-ename->vla-object
(car
(entsel "\n Select entity to see all properties and methods: ")
)
)
T
)
(textscr)
(princ)
)
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 01:51:21 PM
Okay this is what i've put together so far but it is giving me a ; error: ActiveX Server returned an error: Parameter not optional."

Code: [Select]
(defun c:xrs ()
 
  (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")
 (INITDIA)
  (command "xattach" pause)

    (setq EntName (entlast))
    (setq EntData (entget EntName))
    (setq InsName (cdr (assoc 2 EntData)))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))   

 (vl-load-com)
    (setq dwgName InsName)
    (setq dbxDoc (vla-GetInterfaceObject (vlax-get-acad-object)
         ObjectDBX.AxDbDocument.16))
      (vlax-invoke dbxDoc "Open" dwgName)

    (setq dbxBlocks (vla-get-blocks dbxDoc))
      (setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))
    (setq dbxBscale (vla-get-xscalefactor dbxBlock))

    (vlax-release-object dbxDoc)
      (setq dbxDoc nil)
   
   (command "scale" EntName "" InsPoint (/ 1 dbxScale))

;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)


p.s. loved that code by the way
Title: Re: ObjectDBX Xref for block
Post by: CAB on November 01, 2007, 01:59:09 PM
OcCad,
Welcome to the swamp, been a busy day for me.
Looks like you are in good hands.
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 02:05:42 PM
This line is what I think is causing the problem.
Code: [Select]
(setq dbxBscale (vla-get-xscalefactor dbxBlock))
The reason is that you found the blocks definition, not where it is inserted, so it has no scale property.  To find out where it is inserted there are a few ways to go.  Here is one that might be easier for you at the moment.

Once you get the block here
Code: [Select]
(setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))Convert the object to an ename
Code: [Select]
(setq dbxEname (vlax-vla-object->ename dbxBlock))Now we want to get the dxf code information from it
Code: [Select]
(setq dbxEntData (entget dbxEname))Now all the codes 331 are the inserts associated with the block, so to get the scale use
Code: [Select]
(setq dbxBlockInsert (cdr (assoc 331 dbxEntData)))
(setq dbxScale (cdr (assoc 41 (entget dbxBlockInsert))))

Hope that makes sense.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 02:18:11 PM
I'm still getting the same return. When I try to see where it gets messed up it seems its as if its here:

Code: [Select]
    (setq dwgName InsName)

    ;create an ObjectDBX Document
    (setq dbxDoc (vla-GetInterfaceObject (vlax-get-acad-object)
         ObjectDBX.AxDbDocument.16))
      (vlax-invoke dbxDoc "Open" dwgName)

    ;get the desired block

"dwgName" will return a value however "dbxDoc" returns nil as does "dbxBlocks."
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 02:47:43 PM
is dbx server registered?
version of Acad?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 02:48:29 PM
See if this will get what you are looking for.  It's what I use courtesy of Jeff M.
Code: [Select]
(setq dbxApp
 (if (< (atoi (setq oVer (substr (getvar "acadver") 1 2))) 16)
  (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument")
  (vla-GetInterfaceObject (vlax-get-acad-object) (strcat "ObjectDBX.AxDbDocument." oVer))
 )
)

What version of Cad are you on?
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 02:49:40 PM
AC 2008
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 03:11:07 PM
if still getting an error, then register dbx server
Code: [Select]
((lambda (v)
   (if (not
(vl-registry-read
   (strcat "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument." v "\\CLSID")
)
       )
     (startapp "regsvr32.exe"
       (strcat "/s \"" (findfile (strcat "AxDb" v ".dll")) "\"")
     )
   )
 )
  (substr (getvar "ACADVER") 1 2)
)
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 03:14:02 PM
still...

"; error: ActiveX Server returned an error: Parameter not optional" :-(
Title: Re: ObjectDBX Xref for block
Post by: MP on November 01, 2007, 03:20:35 PM
If you're using 2008 object dbx should already be registered:

Code: [Select]
(   (lambda ( version )
        (vl-registry-read
            (strcat "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument"
                (if (eq 15 version)
                    "\\CLSID"
                    (strcat "." (itoa version) "\\CLSID")
                )
            )
        )
    )
    (atoi (getvar "acadver"))
)

=> "{49998808-648A-4A9C-A7A5-B1672775D9AB}"
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 03:24:01 PM
May you know what parameter is registering as not optional?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 03:29:53 PM
Copy/paste the last code I posted to the command line, and post back what it returns.
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 03:30:24 PM
put it this way
Code: [Select]
(setq dbxDoc (vla-GetInterfaceObject
(vlax-get-acad-object)
(strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2))
      )
  )
what value doe's (findfile dwgName) return?
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 03:36:46 PM
TW: #<VLA-OBJECT IAxDbDocument 11150390>

Code: [Select]
(defun c:xrs ()
 
  (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")
 (INITDIA)
  (command "xattach" pause)

    (setq EntName  (entlast))
    (setq EntData  (entget EntName))
    (setq InsName  (cdr (assoc 2 EntData)))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))   

 (vl-load-com)

     ;Register DBX Server
     (setq dbxApp
      (if (< (atoi (setq oVer (substr (getvar "acadver") 1 2))) 16)
       (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument")
       (vla-GetInterfaceObject (vlax-get-acad-object) (strcat "ObjectDBX.AxDbDocument." oVer))
      )
     )
    (setq dwgName InsName)

    ;create an ObjectDBX Document
    (setq dbxDoc (vla-GetInterfaceObject (vlax-get-acad-object)
         ObjectDBX.AxDbDocument.16))
      (vlax-invoke dbxDoc "Open" dwgName)

    ;get the desired block
    (setq dbxBlocks (vla-get-blocks dbxDoc))
    (setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))

    (setq dbxEname (vlax-vla-object->ename dbxBlock))
      (setq dbxEntData (entget dbxEname))
        (setq dbxBlockInsert (cdr (assoc 331 dbxEntData)))
        (setq dbxScale (cdr (assoc 41 (entget dbxBlockInsert))))

    (vlax-release-object dbxDoc)
      (setq dbxDoc nil)
   
   (command "scale" EntName "" InsPoint (/ 1 dbxScale))

;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 03:43:00 PM
In the code replace all the calls to 'dbxDoc' to 'dbxApp' and then remove (or comment out) the portion of the code that assigns 'dbxDoc' as you don't need it.  The way I show (or VovKa shows) is a better way to get it.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 03:48:11 PM
Thats closer. Now no nils up until "dbxblocks"
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 03:51:22 PM
Thats closer. Now no nils up until "dbxblocks"
Did you change the call to the new variable?  The easiest way is to do a find/replace on the whole file.  That is if you are using Notepad, or some other program that works like that.  How are you editing your file?
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 03:54:46 PM
one more error:
insted of
(setq InsName  (cdr (assoc 2 EntData)))
write
(setq InsName (cdr (assoc 1 (tblsearch "BLOCK"(cdr (assoc 2 EntData))))))
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 03:55:27 PM
Im using notepad and I used a find/replace. I even rewrote your code with Vovka's and then rereplaced dbxApp with dbxDoc. Still same error with a parameter not being optional and nils starting at dbxblocks

Is this line in the code correct?

"(vlax-invoke dbxDoc[or dbxAPP] "Open" dwgName)"

when entered into command line it returns nil (dbxDoc or dbxAPP used not both)
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 04:06:58 PM
Are you trying to open a drawing that someone already has open?  You can't use ODBX if the drawing is open by anyone.  Maybe the open isn't working.  To test type
Code: [Select]
(vla-get-Name dbxApp)
Upon looking at the code I don't think the file is being open since you don't give it a whole path, not even a drawing name.  You are getting the name of the block/xref, not the path to it.  If the name is the same as the file name, then try
Code: [Select]
(vla-Open dbxApp (findfile (strcat dwgName ".dwg")))
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 04:25:15 PM
I am the only one in the drawings that I am working with and no they are not open.

I thought the same about the full path and Vovka also posted
Code: [Select]
instead of
(setq InsName  (cdr (assoc 2 EntData)))
write
(setq InsName (cdr (assoc 1 (tblsearch "BLOCK"(cdr (assoc 2 EntData))))))

when
Code: [Select]
(vla-get-Name dbxApp) is entered i only get ""

and with
Code: [Select]
(vla-Open dbxApp (findfile (strcat dwgName ".dwg"))) i get "; error: ActiveX Server returned an error: Parameter not optional."
Title: Re: ObjectDBX Xref for block
Post by: CAB on November 01, 2007, 04:42:04 PM
Same error with this?
Code: [Select]
(vla-Open dbxApp (findfile (strcat dwgName ".dwg")) :vlax-false)The ".dwg" is not already added is it?
Title: Re: ObjectDBX Xref for block
Post by: CAB on November 01, 2007, 04:44:18 PM
Throwing darts, how about this?
Code: [Select]
(vlax-invoke-method 'open dbxApp (findfile (strcat dwgName ".dwg")))
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 05:10:34 PM
the whole code:
Code: [Select]
(defun c:xrs ()
  (command "-layer"
   "make"
   "S-ANNO-XREF"
   "color"
   "7"
   ""
   "ltype"
   "continuous"
   ""
   "s"
   ""
   ""
  )
  (INITDIA)
  (command "xattach" pause)
  (setq EntName (entlast))
  (setq EntData (entget EntName))
  (setq InsName (cdr (assoc 1 (tblsearch "BLOCK"(cdr (assoc 2 EntData))))))
  (setq InsScale (cdr (assoc 41 EntData)))
  (setq InsPoint (cdr (assoc 10 EntData)))
  (vl-load-com)
 
  (setq dwgName InsName)   ;create an ObjectDBX Document
  (setq dbxDoc (vla-GetInterfaceObject
(vlax-get-acad-object)
(strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2))
       )
  )
  (vlax-invoke dbxDoc "Open" dwgName)   ;get the desired block
  (setq dbxBlocks (vla-get-blocks dbxDoc))
  (setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))
  (setq dbxEname (vlax-vla-object->ename dbxBlock))
  (setq dbxEntData (entget dbxEname))
  (setq dbxBlockInsert (cdr (assoc 331 dbxEntData)))
  (setq dbxScale (cdr (assoc 41 (entget dbxBlockInsert))))
  (vlax-release-object dbxDoc)
  (setq dbxDoc nil)
  (command "scale" EntName "" InsPoint (/ 1 dbxScale))
  ;;after the insert
  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted "
  (cdr (assoc 2 EL))
  " at scale "
  (rtos (* 12 (cdr (assoc 41 EL))))
  " = 1' "
  )
  )
  (princ)
)
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 05:19:24 PM
"dbxBlockInsert" returns nil.

"(cdr (assoc 331 dbxEntData))" returns nil

And what was it that was stopping me from opening it in ODBX before?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 05:34:58 PM
Type '!dbxEntData' at the command line after the code is ran, and post what it returns.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 05:36:36 PM
Code: [Select]
((-1 . <Entity name: 78d61380>) (0 . "INSERT") (330 . <Entity name: 7ed8bc40>)
(5 . "5EA8") (100 . "AcDbEntity") (67 . 1) (410 . "TYPICAL STEEL DETAILS") (8 .
"S-ANNO-XREF") (100 . "AcDbBlockReference") (2 . "042200-0101-3") (10 15.3858
6.88422 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44
. 0.0) (45 . 0.0) (210 0.0 0.0 1.0))
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 05:39:47 PM
That isn't the correct block.  Try closing the current drawing, and then run the code again, and post what is returned again.
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 05:45:11 PM
i simulated your conditions: created the dwg with block "Detail Bdr", saved it, created new dwg a ran your program. all went with no errors.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 05:47:09 PM
tw:

Code: [Select]
((-1 . <Entity name: 7d763f18>) (0 . "BLOCK_RECORD") (5 . "63") (102 .
"{ACAD_XDICTIONARY") (360 . <Entity name: 7d763f20>) (102 . "}") (330 . <Entity
name: 7d763c08>) (100 . "AcDbSymbolTableRecord") (100 . "AcDbBlockTableRecord")
(2 . "Detail Bdr") (360 . <Entity name: 7d75a010>) (340 . <Entity name:
0>) (70 . 1) (280 . 1) (281 . 1))
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 05:52:01 PM
That makes it look like the block is not inserted in the drawing any place.  It should look like this.
Code: [Select]
((-1 . <Entity name: 7ed2d0c0>) (0 . "BLOCK_RECORD") (330 . <Entity name:
7ed10c08>) (5 . "C8") (100 . "AcDbSymbolTableRecord") (100 .
"AcDbBlockTableRecord") (2 . "Det-Bub") (360 . <Entity name: 7ed2d0e8>) (340 .
<Entity name: 0>) (102 . "{BLKREFS") [color=red](331 . <Entity name: 7ed2d118>) (331 .
<Entity name: 7ed2d240>) (331 . <Entity name: 7ed2d360>) (331 . <Entity name:
7ed2d380>) (331 . <Entity name: 7ed2d3a0>) (331 . <Entity name: 7ed2d400>) (331
. <Entity name: 7ed2d420>) (331 . <Entity name: 7ed2d440>) (331 . <Entity name:
7ed2d460>) (331 . <Entity name: 7ed2d480>) (331 . <Entity name: 7ed2d4f8>)[/color] (102
. "}"))
Notice all the code 331s.  Those are the inserted block entities.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 05:52:50 PM
Vovka: I ran the same test (test detail, test sheet) and it too worked for me. But for some reason when i went to go pull from the detail library it says "; error: bad argument type: lentityp nil"

I xopen the detail from the detail library (read only if that matters) and list the detail bdr and it lists fine...
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 06:00:59 PM
Entire list of Detail Bdr from within detail library

Code: [Select]
                  BLOCK REFERENCE  Layer: "0"
                            Space: Model space
                   Handle = 72bf
       Block Name: "Detail Bdr"
   Anonymous Name: "*U6"
                at point, X=    0'-0"  Y=    0'-0"  Z=    0'-0"
   X scale factor:   16.0000
   Y scale factor:   16.0000
   rotation angle:   0.00
   Z scale factor:   16.0000
         InsUnits: Inches
  Unit conversion:    1.0000
  Scale uniformly: Yes
  Allow exploding: Yes
           Height:     9'-4"
            Width:     9'-4"
       Visibility: Show Detail Bubble

                  ATTRIBUTE  Layer: "S-TEXT"
                            Space: Model space
                   Handle = 72c0
             Style = "Text"
        Annotative: No
             Font file = architxt.shx
             start point, X=1'-5 1/16"  Y=0'-2 3/16"  Z=    0'-0"
            height     0'-2"
             value
               tag REF
          rotation angle   0.00
             width scale factor    0.8500
         obliquing angle  15.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-LITE"
                            Space: Model space
                   Handle = 72c1
             Style = "Text"
        Annotative: No
             Font file = architxt.shx
               end point, X=    8'-3"  Y=0'-3 5/16"  Z=    0'-0"
Press ENTER to continue:
            height     0'-1"
             value MSNR-00_A (16)
               tag FILENAME
          rotation angle   0.00
             width scale factor    1.0000
         obliquing angle  15.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-TEXT"
                            Space: Model space
                   Handle = 72c2
             Style = "Text"
        Annotative: No
             Font file = architxt.shx
            center point, X=4'-10 1/4"  Y=0'-2 3/16"  Z=    0'-0"
            height     0'-2"
             value 3/4" = 1'-0"
               tag SCALE
          rotation angle   0.00
             width scale factor    0.8500
         obliquing angle  15.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-TEXT-TB"
                            Space: Model space
                   Handle = 72c3
             Style = "TEXTTB"
        Annotative: No
             Font file = archisel.shx
            center point, X=4'-10 1/4"  Y=1'-1 15/16"  Z=    0'-0"
            height     0'-4"
             value TYPICAL MASONRY WALL
               tag DETAILTOP
          rotation angle   0.00
             width scale factor    0.8500
         obliquing angle  15.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-TEXT-TB"
                            Space: Model space
Press ENTER to continue:
                   Handle = 72c4
             Style = "TEXTTB"
        Annotative: No
             Font file = archisel.shx
            center point, X=4'-10 1/4"  Y=0'-8 5/16"  Z=    0'-0"
            height     0'-4"
             value CONTROL JOINT
               tag DETAILBOTTOM
          rotation angle   0.00
             width scale factor    0.8500
         obliquing angle  15.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-ANNO-TEXT-TB"
                            Space: Model space
                   Handle = 72c5
             Style = "TEXTTB"
        Annotative: No
             Font file = archisel.shx
            center point, X=1'-0 1/2"  Y=0'-7 11/16"  Z=    0'-0"
            height     0'-2"
             value ?
               tag DETAILNO
          rotation angle   0.00
             width scale factor    1.0000
         obliquing angle   0.00
             flags normal
        generation normal

                  ATTRIBUTE  Layer: "S-TEXT-TB"
                            Space: Model space
                   Handle = 72c6
             Style = "TEXTTB"
        Annotative: No
             Font file = archisel.shx
       fit between point, X=    0'-9"  Y=0'-4 1/2"  Z=    0'-0"
               and point, X=    1'-4"  Y=0'-4 1/2"  Z=    0'-0"
            height     0'-2"
             value S?.??
               tag SHEETNO
          rotation angle   0.00
             width scale factor    1.0748
Press ENTER to continue:
         obliquing angle   0.00
             flags normal
        generation normal

                  END SEQUENCE  Layer: "0"
                            Space: Model space
                   Handle = 72c7
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 06:06:44 PM
Okay.  I see the problem.  It is a dynamic block, so the way I was using will not work.  You will have to search the whole drawing to find the correct block.  You will have to check the property 'EffectiveName' since that is the name of the block before you make any dynamic changes.

Code: [Select]
(vlax-for lo (vla-get-Layouts dbxDoc)
 (vlax-for obj (vla-get-Block lo)
  (if
   (and
    (= (vla-get-ObjectName obj) "AcDbBlockReference")
    (= (strcase (vla-get-EffectiveName obj)) "DETAIL BDR")
   )
   (setq dbxScale (vla-get-XScaleFactor obj))
  )
 )
)
This will replace all of this.
Code: [Select]
  (setq dbxBlocks (vla-get-blocks dbxDoc))
  (setq dbxBlock (vla-item dbxBlocks "Detail Bdr"))
  (setq dbxEname (vlax-vla-object->ename dbxBlock))
  (setq dbxEntData (entget dbxEname))
  (setq dbxBlockInsert (cdr (assoc 331 dbxEntData)))
  (setq dbxScale (cdr (assoc 41 (entget dbxBlockInsert))))
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 06:14:42 PM
TW: Hmmm... Strange because when I did the test detail/test sheet I spoke to Vovka about the detail was just a drawing containing that dynamic block. But i will try your recent post as well
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 06:17:08 PM
The problem is when you change the dynamic properties it changes the block to an anonymous block, so it does not really reference the block definition anymore.  It may, but not in the way the old style blocks referenced the block definition.  I just learned that by looking at what you posted since I haven't dug into '08 yet.
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 01, 2007, 06:21:32 PM
what is a dynamic block? :)
i use autocad 2004, so no dynamic blocks at all :0
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 06:24:07 PM
what is a dynamic block? :)
i use autocad 2004, so no dynamic blocks at all :0
A dynamic block is a block that change it's appearance.  So if you have blocks that are similar, you can create one block with different views.  They can get real complex, but that is a simple explanation.  Started in '06 I think.
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 06:26:59 PM
OcCad,
 
  If the block is inserted in paper space, then you have to use ObjectDBX to get this information, but if it is inserted into model space no need to go the ObjectDBX route since all objects in model space are brought over in the xref.  You just need to search the blocks definition for the block you want to check.  This will make the program faster, and won't matter if anyone has the xref'ed drawing open.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 06:33:40 PM
thanks guys! And if i wanted to expand the list of blocks to search for, would this be the correct way to do it?

Code: [Select]
    (vlax-for lo (vla-get-Layouts dbxDoc)
     (vlax-for obj (vla-get-Block lo)
      (if
       (and
        (= (vla-get-ObjectName obj) "AcDbBlockReference")
         (if(null (= (strcase (vla-get-EffectiveName obj)) "Detail Bdr"))
          (progn ;else
          (if (null (= (strcase (vla-get-EffectiveName obj)) "Detail Bdr2"))
           (progn ;else
           (= (strcase (vla-get-EffectiveName obj)) "Detail Bdr3")
          );if
         );if
        );and
       (setq dbxScale (vla-get-XScaleFactor obj))
      );if
     )
    )
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 06:42:23 PM
The way I would do it, is make a list of all the block names you want to search for, and then just test the block name against the list.
Code: [Select]
(vl-position (strcase (vla-get-Name blk)) '("DETAIL BDR" "DETAIL BDR2" "DETAIL BDR3")
Don't forget that lisp is case sensitive (most of the time).

You're welcome.  Hope you learned something along this first journey.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 06:54:57 PM
Perfect! Thank you everybody for all your contribution.

Vovka & T. Willey may I get your Names so that I may log it into the lisp
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 01, 2007, 07:03:13 PM
Perfect! Thank you everybody for all your contribution.

Vovka & T. Willey may I get your Names so that I may log it into the lisp
That is my name.  T. = Tim (in the signature) Willey = Willey.  :wink:

Glad you got something that works for you.  Now you should make all your variables local.  Very good idea.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 01, 2007, 07:35:12 PM
Yeah, I learned that I have a lot to learn  :-D
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 02, 2007, 01:29:49 PM
Okay, I'm having some trouble with older details and i feel its because of the fact that my detail borders are no longer dynamic blocks

Right now in DBX I'm looking for my desired block like this
Code: [Select]
    (vlax-for LO (vla-get-Layouts dbxDoc)
     (vlax-for Obj (vla-get-Block LO)
      (if
       (and
        (= (vla-get-ObjectName Obj) "AcDbBlockReference")
        (= (vl-position (strcase (vla-get-EffectiveName Obj)) '("Detail Bdr" "DTLTITLE" "DET-TITLE")))
       );and
       (setq dbxScale (vla-get-XScaleFactor Obj))
      ):if
     )
    )
   (princ)

but for some reason with this block even though my effective scale factor is 12.0 it scale my drawing up to 1'-4"=1'-0" (reading an effective scale factor of 0.75). with the properties listed below can you see why?

Code: [Select]
Command: dlist
 Select entity to see all properties and methods:
; IAcadBlockReference: AutoCAD Block Reference Interface
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00d74d3c>
;   Document (RO) = #<VLA-OBJECT IAcadDocument 01b95dc0>
;   EffectiveName (RO) = "DTLTITLE"
;   Handle (RO) = "3045"
;   HasAttributes (RO) = -1
;   HasExtensionDictionary (RO) = 0
;   Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 0f96c49c>
;   InsertionPoint = (51.6009 22.2771 0.0)
;   InsUnits (RO) = "Unitless"
;   InsUnitsFactor (RO) = 1.0
;   IsDynamicBlock (RO) = 0
;   Layer = "TITLINE"
;   Linetype = "BYLAYER"
;   LinetypeScale = 1.0
;   Lineweight = -1
;   Material = "ByLayer"
;   Name = "MSMTITLE"
;   Normal = (0.0 0.0 1.0)
;   ObjectID (RO) = 2105865832
;   ObjectName (RO) = "AcDbBlockReference"
;   OwnerID (RO) = 2107587600
;   PlotStyleName = "ByLayer"
;   Rotation = 0.0
;   TrueColor = #<VLA-OBJECT IAcadAcCmColor 0f952410>
;   Visible = -1
;   XEffectiveScaleFactor = 12.0
;   XScaleFactor = 12.0
;   YEffectiveScaleFactor = 12.0
;   YScaleFactor = 12.0
;   ZEffectiveScaleFactor = 12.0
;   ZScaleFactor = 12.0
; Methods supported:
;   ArrayPolar (3)
;   ArrayRectangular (6)
;   ConvertToAnonymousBlock ()
;   ConvertToStaticBlock (1)
;   Copy ()
;   Delete ()
;   Explode ()
;   GetAttributes ()
;   GetBoundingBox (2)
;   GetConstantAttributes ()
;   GetDynamicBlockProperties ()
;   GetExtensionDictionary ()
;   GetXData (3)
;   Highlight (1)
;   IntersectWith (2)
;   Mirror (2)
;   Mirror3D (3)
;   Move (2)
;   ResetBlock ()
;   Rotate (2)
;   Rotate3D (3)
;   ScaleEntity (2)
;   SetXData (2)
;   TransformBy (1)
;   Update ()
Title: Re: ObjectDBX Xref for block
Post by: Bob Wahr on November 02, 2007, 01:41:01 PM
Is the block annotative?
Title: Re: ObjectDBX Xref for block
Post by: VovKa on November 02, 2007, 01:53:27 PM
not
Code: [Select]
(= (vl-position (strcase (vla-get-EffectiveName Obj)) '("Detail Bdr" "DTLTITLE" "DET-TITLE")))
but
Code: [Select]
(vl-position (strcase (vla-get-EffectiveName Obj)) '("DETAIL BDR" "DTLTITLE" "DET-TITLE"))
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 02, 2007, 01:59:24 PM
But I thought Lisp was cAsE sensitive... And in our dynamic block "Detail Bdr" thats how it lists
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 02, 2007, 02:07:40 PM
But I thought Lisp was cAsE sensitive... And in our dynamic block "Detail Bdr" thats how it lists
It is, that is why we use this line
Code: [Select]
(strcase (vla-get-EffectiveName Obj))This tells it to make the name all capitol letters.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 02, 2007, 02:12:04 PM
Alright... one, there hasn't been a problem with the dynamic block so far that I list as "Detail Bdr" and two, would changing the case of the dynamic block fix the issue I'm having with "DTLTITLE" scaling by an xeffectivescale factor of 0.75 when it lists 12.0?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 02, 2007, 02:13:18 PM
Post the whole code you are using so we can see what you are working with.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 02, 2007, 02:17:47 PM
"DTLTITLE" & "DET-TITLE" are not dynamic blocks
Code: [Select]
(defun c:xas (/ EntName EntData InsName InsScale InsPoint DwgName dbxDoc LO Obj dbxScale EL)

   (command "-layer" "make" "S-ANNO-XREF" "color" "7" "" "ltype" "continuous" "" "s" "" "")

 (INITDIA)
  (command "xattach" pause)

    (setq EntName  (entlast))
    (setq EntData  (entget EntName))
    (setq InsName (cdr (assoc 1 (tblsearch "BLOCK"(cdr (assoc 2 EntData))))))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))
   (princ)   

 (vl-load-com)

    (setq dwgName InsName)
   
    (setq dbxDoc (vla-GetInterfaceObject
        (vlax-get-acad-object)
        (strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2))
      )
    )
    (vlax-invoke dbxDoc "Open" dwgName)
   (princ)

    (vlax-for LO (vla-get-Layouts dbxDoc)
     (vlax-for Obj (vla-get-Block LO)
      (if
       (and
        (= (vla-get-ObjectName Obj) "AcDbBlockReference")
        (= (vl-position (strcase (vla-get-EffectiveName Obj)) '("DETAIL BDR" "DTLTITLE" "DET-TITLE")))
       );and
       (setq dbxScale (vla-get-XScaleFactor Obj))
      ):if
     )
    )
   (princ)

    (vlax-release-object dbxDoc)
      (setq dbxDoc nil)

  (command "scale" EntName "" InsPoint (/ 1 dbxScale))
  (princ)

  (setq EL (entget (entlast)))
  (prompt (strcat "\nInserted " (cdr (assoc 2 EL)) " at scale " (rtos (* 12 (cdr (assoc 41 EL)))) " = 1' "))

 (princ)
)
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on November 02, 2007, 02:42:10 PM
This line is not correct
Code: [Select]
(= (vl-position (strcase (vla-get-EffectiveName Obj)) '("DETAIL BDR" "DTLTITLE" "DET-TITLE")))
It should be (like we posted before)
Code: [Select]
(vl-position (strcase (vla-get-EffectiveName Obj)) '("DETAIL BDR" "DTLTITLE" "DET-TITLE"))
'vl-position' searches a list for the item supplied, so here it is searching the list you supply for the the name of the block you supply.  If it finds it, then it returns the postion, if it doesn't find it it returns nil.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on November 02, 2007, 02:45:03 PM
Shveet! Thanks
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 12:20:38 PM
Hey Gurus,

This code seems to work fine on my computer but now when I try to load it onto other peoples computer I'm getting an "exception occured" when they try to run it and can't figure out from where or even why. Could it be because some settings are diff on mine than theirs?...

Code: [Select]
=======================================================================
;;;
;;;  XrefAttachScale.lsp
;;;
;;;  Created by Alex J. Ruiz
;;;  Help from Tim Willey & Vovka
;;;  11.01.2007
;;;
;;;  Tested on r2008
;;;
=======================================================================
;;;  Function to attach xref at a scale governed by nested title block
;;;  Type xas in commandline to run

=======================
;;;Error definition
=======================

;(defun xrperr (msg)
;   (if ce  (setvar "cmdecho" ce))
;   (if v_r (setvar "visretain" v_r))
;   (if r_a (setvar "regenmode" r_a))
;   (setq *error* orgerr)   ;reset previous error def.
;   (princ "\nCommand cancelled!")
;   (prompt "\n ")
;   (princ)
;
;);end defun

=================
;;;Main Program
=================

(defun c:xas (/ lyr lyrdata lyrlock EntName EntData InsName InsScale InsPoint DwgName dbxDoc LO Obj dbxScale EL)

 (setq orgerr *error* *error* xrperr)

=======================
;;;Test for layer Xref
=======================

 (setq lyr "S-ANNO-XREF")

 (if (tblsearch "LAYER" lyr)
  (progn
    (setvar "clayer" lyr)
    (setq lyrdata (entget (tblobjname "layer" lyr)))
    (setq lyrlock (cdr (assoc 70 lyrdata)))
  );progn   
  (command "-layer" "make" lyr "color" "7" "" "ltype" "continuous" "" "s" lyr "")
 );if
 (princ)

 (if (= lyrlock 4)
   (progn
     (initget 0 "Yes No")
     (setq lock (cond ((getkword "\nThe layer S-ANNO-XREF is locked. Would you like to unlock it now? <Yes>: "))
                      ("Yes")))
       (cond
         ((= lock "Yes")
           (command "-layer" "unlock" lyr "")
           )
         ((= lock "No")
           (setq lyrlock 4)
           )
       );cond
   );progn
 );if



============================
;;;Xattach command with Box
============================

 (INITDIA)
  (command "xattach" PAUSE)
   
    (setq EntName  (entlast))
    (setq EntData  (entget EntName))
    (setq InsName  (cdr (assoc 1 (tblsearch "BLOCK"(cdr (assoc 2 EntData))))))
    (setq InsScale (cdr (assoc 41 EntData)))
    (setq InsPoint (cdr (assoc 10 EntData)))
;      (if (= nil Inspoint)
;          (setq InsPoint "0,0,0")
;      );if
;    (setq InsPoint (getpoint "\nSpecify point of insertion: "))
 
  (princ)   

    (setq dwgName InsName)
   
====================
;;;Open Dwg in ODBX
====================

 (vl-load-com)

    (setq dbxDoc (vla-GetInterfaceObject
        (vlax-get-acad-object)
        (strcat "ObjectDBX.AxDbDocument." (substr (getvar "acadver") 1 2))
      )
    )
    (vlax-invoke dbxDoc "Open" dwgName)
   (princ)

==========================
;;;Get the Desired Blocks
==========================

    (vlax-for LO (vla-get-layouts dbxDoc)
     (vlax-for Obj (vla-get-Block LO)
      (if
       (and
        (= (vla-get-ObjectName Obj) "AcDbBlockReference")
        (vl-position (strcase (vla-get-EffectiveName Obj))
        '("MI DETAIL TITLE"
  "MSMTITLE"
  "MSMDTITLE"
  "MI-DET-TITLE"
  "MI DETAIL TITLE1"))
       )
       (setq dbxScale (vla-get-XScaleFactor Obj))
      )
     )
    )
   (princ)

=====================
;;;Close Dwg in ODBX
=====================

    (vlax-release-object dbxDoc)
      (setq dbxDoc nil)

==============
;;;Scale Xref
==============

      (command "scale" EntName "" InsPoint (/ 1 dbxScale))

  (princ)

====================
;;;After the Insert
====================

;  (if (= lyrlock 4)
;   (command "-layer" "lock" lyr "")
;   (setq lyrlock 0)
;  );if

  (setq EL (entget (entlast)))
  (prompt (strcat "\nAttached \"" (cdr (assoc 2 EL)) "\" at " (rtos (* 12 (cdr (assoc 41 EL)))) "=1'-0\" scale"))

;  (setq *error* orgerr orgerr nil)

 (princ)
)

;; / lyr lyrdata lyrlock EntName EntData InsName InsScale InsPoint DwgName dbxDoc LO Obj dbxScale EL
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 12:33:22 PM
The code isn't too long, so I would just test it piece by piece until I found what was giving the error.  Or you might be able to use vlide to watch it run on their computer, but I don't know how to do that, as I don't use vlide to code in.

If I have some time I will look through it a little more thorough.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 12:37:22 PM
Tim,

I did break it apart piece by piece and it got "nils" beginning at the variable LO. I did not check dbxDoc (which I really should have) but still around that area.
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 12:57:34 PM
LO will always be nil, unless you check it within the vlax-for loop.  It is kind of like a local variable.

I remember this routine now.  I would write it different, as there is not need to open the drawing with ObjectDBX since the blocks you are checking for are within model space, and therefor would be within the block definition (xref definition).
Title: Re: ObjectDBX Xref for block
Post by: CAB on December 19, 2007, 01:15:23 PM
I doubt this is the problem but FYI the dxf code 70 is a bit code value and therefore this test may fail.
Code: [Select]
(if (= lyrlock 4)When in fact the layer is locked.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 01:17:30 PM
CAB,

It's a direction I tested but took it out with the semi's
Title: Re: ObjectDBX Xref for block
Post by: CAB on December 19, 2007, 01:23:53 PM
You took this out?
Code: [Select]
(if (= lyrlock 4)
   (progn
     (initget 0 "Yes No")
     (setq lock (cond ((getkword "\nThe layer S-ANNO-XREF is locked. Would you like to unlock it now? <Yes>: "))
                      ("Yes")))
       (cond
         ((= lock "Yes")
           (command "-layer" "unlock" lyr "")
           )
         ((= lock "No")
           (setq lyrlock 4)
           )
       );cond
   );progn
 );if

Just change this
Code: [Select]
(if (= lyrlock 4)to this
Code: [Select]
(if (= (logand 4 lyrlock) 4)
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 01:25:43 PM
hehe... forgot about that :lol:
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 01:28:58 PM
See if this works for you.

Edit:  Updated code, shown in read.
Edit:  Updated code, shown in read. Tested and works, as long as the block that is being searched for is in model space.
Code: [Select]
(defun c:xas (/ ActDoc LayCol BlkCol xLay OldLay LayObj LockOpt Ent Obj BlkDefObj BlkDefLen cnt xScale tempObj Pos)

(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(setq LayCol (vla-get-Layers ActDoc))
(setq BlkCol (vla-get-Blocks ActDoc))
(setq xLay "S-ANNO-XREF")
(setq OldLay (getvar 'CLayer))

(if (vl-catch-all-error-p (setq LayObj (vl-catch-all-apply 'vla-Item (list LayCol xLay))))
(setq LayObj (vla-Add LayCol xLay))
)
(setvar 'CLayer xLay)
(if (equal (vla-get-Lock LayObj) :vlax-true)
(progn
(initget 0 "Yes No")
(setq LockOpt
(cond
((getkword "\nThe layer S-ANNO-XREF is locked. Would you like to unlock it now? <Yes>: "))
(T "Yes")
)
)
(if (= LockOpt "Yes")
(vla-put-Lock LayObj :vlax-false)
)
)
)

(InitDia)
(command "_.xattach" pause)
(if
(and
(setq Ent (entlast))
(setq Obj (vlax-ename->vla-object Ent))
(= (vla-get-ObjectName Obj) "AcDbBlockReference")
(equal (vla-get-IsXref (setq BlkDefObj (vla-Item BlkCol (vla-get-Name Obj)))) :vlax-true)
(setq BlkDefLen (vla-get-Count BlkDefObj))
(setq cnt 0)
)
(while
(and
(not xScale)
(< cnt BlkDefLen)
)
(setq tempObj (vla-Item BlkDefObj cnt))
(if
(and
(= (vla-get-ObjectName tempObj) "AcDbBlockReference")
[color=red](setq Pos (vl-string-search "|" (vla-get-EffectiveName tempObj)))[/color]
(vl-position
[color=red](strcase
(substr
(vla-get-EffectiveName tempObj)
(+ 2 Pos)
)
)[/color]
'("MI DETAIL TITLE"
  "MSMTITLE"
  "MSMDTITLE"
  "MI-DET-TITLE"
  "MI DETAIL TITLE1"
)
)
)
(setq xScale (vla-get-XScaleFactor tempObj))
(setq cnt (1+ cnt))
)
)
)
(if xScale
(progn
[color=red](vlax-invoke Obj 'ScaleEntity (vlax-get Obj 'InsertionPoint) (/ 1 xScale))[/color]
(prompt
(strcat
"\nAttached \""
(vla-get-Name Obj)
"\" at "
[color=red](rtos (* 12 (/ 1 xScale)))[/color]
"=1'-0\" scale"
)
)
)
)
(if (= LockOpt "Yes")
(vla-put-Lock LayObj :vlax-true)
)
(setvar 'CLayer OldLay)
(princ)
)
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 01:34:11 PM
Guys, I found it!

Apparantly there is an exception that occurs when one chooses relative path versus full path. When full path is selected the code works fine.  Tim I will see how the code above works and if it has the same issue
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 01:38:45 PM
Glad you found it, but the new one won't matter because it doesn't use the path for anything (which sould make it faster).  The problem was that if it's not a real path, then it doesn't know where to find the drawing, so it can't open it up in the ObjectDBX app.  That would be an easy fix, you would just need to add a 'findfile' call here.
Code: [Select]
(setq dwgName InsName)
Change to
Code: [Select]
(setq dwgName (findfile InsName))
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 01:44:36 PM
Tim,

Your code for some reason did not scale down. I will also look into it and see what I can find. Either way thank you for another great example on how to code. I also have a new function to read up on
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 01:50:50 PM
Tim,

Your code for some reason did not scale down. I will also look into it and see what I can find. Either way thank you for another great example on how to code.
You're welcome.  I have fixed what could be the problem (in the other post), as I didn't test it because I don't have your blocks, but I will here soon just to make sure what I posted works.  :-)

Edit:  After looking at the code, you may have to go the ObjectDBX route.  It looks like you are looking for title block blocks, and those are typically in a paper space layout, which wouldn't be in the block definition.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 02:06:43 PM
They are detail title blocks and are in the block definitions we use
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 02:10:53 PM
They are detail title blocks and are in the block definitions we use
But they would need to be inserted in model space in the xref, or the new code won't work.

ps.  I updated the code after testing it.  The problem was with searching for the name.  I forgot that when you search the way I do now it adds the xref to the name, so I had to change the way I looked at the blocks name.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 02:14:09 PM
Sorry, i wasn't very clear the first time. Everything within the detail xref is in model space. Wow, i can tell how much faster your code is. Probably fractions of a second but very noticible non-the-less. Terrific

Lisp now reads...

=======================
;;;   Overhauled by Tim Willey
;;;   12.19.2007
=======================

 :-D
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 03:29:30 PM
Sorry, i wasn't very clear the first time. Everything within the detail xref is in model space. Wow, i can tell how much faster your code is. Probably fractions of a second but very noticible non-the-less. Terrific

Lisp now reads...

=======================
;;;   Overhauled by Tim Willey
;;;   12.19.2007
=======================

 :-D
You're welcome.

ObjectDBX is fast, but you still have to load the drawing (but at least not in the editor), but if you don't have to load the drawing why should we, and if we don't then it will be faster, which is the route I took in the second version.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 04:22:49 PM
Now is there any way to bypass the scale or rotation setting in the xref dialogue box or even make sure those two are always unchecked?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 04:57:24 PM
Now is there any way to bypass the scale or rotation setting in the xref dialogue box or even make sure those two are always unchecked?
If this routine was for me, I wouldn't even use the command 'xattach', I would do it all with code, but I didn't know if you liked to see the options the command has to offer or not.  If you just want to attach a file at a certain point with almost all options always the same, then I would just code up something like that.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 05:01:25 PM
Only problem is that I have no idea how to do dialogue boxes yet.
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 05:02:25 PM
Only problem is that I have no idea how to do dialogue boxes yet.
You don't need a dialog box.  I would use the standard lisp function 'GetFiled'.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 05:15:42 PM
Schhhhhhhhvvvvvvvvvvveeeeeeeeeeet! Thats two today. I can have fun with this one. I'll see if i can learn how to incorporate it.


....wait. Actually I could of just went through the -xref command, no?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 05:47:04 PM
Schhhhhhhhvvvvvvvvvvveeeeeeeeeeet! Thats two today. I can have fun with this one. I'll see if i can learn how to incorporate it.


....wait. Actually I could of just went through the -xref command, no?
Yes if you knew where the file would be.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 05:56:44 PM
How would you use getfiled then to attach the drawing? And is there a way for the dia to remember the last folder that I was in?
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 06:07:30 PM
How would you use getfiled then to attach the drawing?
You don't use it to attach the file (xref), but to get the location of the file.  Once you have that, then you know what you are going to attach, and you can use the 'AttachExternalReference' method on the space (tab) you want to add the xref.  This might be a little more advance stuff than what you are using right now, but it isn't that hard.  I would go that ActiveX route.

And is there a way for the dia to remember the last folder that I was in?
Depends on what you want it to remember, and how you want it to remember.  If you want it to remember within the same drawing, then you just make the directory a global variable.  If you want it to be know in all drawings that are opened, or going to be opened, then you make it a global variable, and use the 'vl-propagate' function to send it to all drawings.  These are both ways to keep it known in the current Acad session.  If you want it to be known past that, then you have to write it to a file or the registry.
Title: Re: ObjectDBX Xref for block
Post by: OcCad on December 19, 2007, 06:10:25 PM
Okay, and one more question.

What about the option to make the xref relative?

Make it two... How long have you being writing code? (gives me something to look foward to)
Title: Re: ObjectDBX Xref for block
Post by: T.Willey on December 19, 2007, 06:13:43 PM
Okay, and one more question.

What about the option to make the xref relative?
From what I have seen about that, it is how the path is stored within the drawing.  So it depends on how far you want the relative path to go.  If you want it one folder back, I think you would just put the path like

..\Xrefs\Xref.dwg

But you may need to test to make sure.