Author Topic: Jeff_M or anyone familiar with ObjectDBX  (Read 4730 times)

0 Members and 1 Guest are viewing this topic.

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« on: January 11, 2005, 07:02:52 PM »
Hi Jeff,
Recently you helped me with adding/deleting a block to/from an dwg [not open] via dbx http://theswamp.org/phpBB2/viewtopic.php?t=1821&highlight=objectdbx Thanx. Now, i've cooked this code to attach an attribute to a block in active drawing:
Code: [Select]
;;;(AddAttrib (car ent1) 2.5 acAttributeModeInvisible "Enter a description:" pWs "LGND" "Blah")
(setq *adoc* (vla-get-activeDocument (vlax-get-acad-object)))
(defun AddAttrib (eInsert height mode prompt insPt tag value / )
  (vla-addAttribute
    (vla-item (vla-get-blocks *adoc*)(vla-get-name (vlax-ename->vla-object eInsert)))
     height mode prompt (vlax-3d-point insPt) tag value
  )
  (command "_.ATTSYNC" "_s" (car ent1) "_y")
)

Can you - or anyone up to the task - help with modifying the code using dbx to a attach attr to a block in an unopen dwg? No need to check if block exists - I know it does, but it might need to test if the attribute already exists and even return it!
Thanks for any help.

Jeff_M

  • King Gator
  • Posts: 4100
  • C3D user & customizer
Re: Jeff_M or anyone familiar with ObjectDBX
« Reply #1 on: January 11, 2005, 07:18:32 PM »
Quote from: Serge J. Gianolla
Hi Jeff,
Recently you helped me with adding/deleting a block to/from an dwg [not open] via dbxThanx. Now, i've cooked this code to attach an attribute to a block in active drawing:

Thanks for any help.

Youre welcome! I'm glad you found it useful.
Now you are getting into the fun stuff! As you know, you can't call a command in a dbxDoc so first you need to add the attribute to the block definition, which your code would do just fine using a dbxDoc in place of the ActiveDoc.

Next, step through ALL objects on ALL layouts, checking to see if the object is an Insert, and if it is, is it the block of interest to you. If it is, there are a couple of ways to attack the next part.

Option 1: collect the insertion point, layer, layout block it reides in, rotation angle, etc., and most importantly the attributes in the blockreference, create a list of dotted pairs ("tagstring" . "textstring"), delete the block and re-insert it setting all of the data you saved from the original, then reset the new attribute values to match the old using the list you created. Finally change the new attribute to the desired value.

Option 2: Nevermind, I can't think of an option 2...resort to option 1 :roll:

If you need help with the code for this just say so.

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« Reply #2 on: January 11, 2005, 11:17:54 PM »
Quote
As you know, ...

Well, that's the problem Jeff, I do not know :oops: Been using AutoCAD for almost 20 years, and LISP which was not called lisp at the time. Recently, went to VLisp, which was hard to adjust to! Sort of to grasp it , but I cannot make sense of dbx connectivity - at this stage - funny enough, I sort of got acquainted with reactors pretty easily. Go figure! So, I am afraid of hitting a wall as re: with writing the code. Tried the things you mentioned - Thanks for being prompt -  but so far, I must be stupid; :wink:  can get my head 'round it! So, i'd like to take up on your offer of help in writing it! Merci beaucoup.

Jeff_M

  • King Gator
  • Posts: 4100
  • C3D user & customizer
Jeff_M or anyone familiar with ObjectDBX
« Reply #3 on: January 12, 2005, 02:58:02 PM »
OK Serge, you asked for it  :shock:

Here's one that handles just about everything. I didn't include options for setting the textstyle of the new attribute, nor did I provide any error handling. This is mainly for you to see how I would go about doing this. I tested it with 2 drawings using different blocks & attributes in each. My test is at the bottom. I've commented it so you can, hopefully, follow along and you can modify it as you see fit.

Just so you know, you cannot do the following to documents opened via ObjectDBX: use any (command) call, obtain or set system variables, get objects to work with by using a selection set, save the drawing with the preview bitmap,

Note that this code was put together rather quickly, and as such may not be as optimal as it should be. Feel free to play with it and adjust as desired.
Enjoy!
Code: [Select]

;| Add an attribute to a block in unopened drawing and update
   existing references to include that attribute.
   Jan. 2005 by Jeff Mishler
   Arguments needed:
   source - valid path to file to work with
   bName - Block name to modify
   height - attribute text height
   mode - valid values:acAttributeModeInvisible
                       acAttributeModeConstant
                       acAttributeModeVerify
                       acAttributeModePreset
                       or 0 for none of these
   prmt - Prompt string
   insPt - insertion point relative to the Block's insertion Point '(0.0 0.0 0.0)
   tag - the Tag string
   defvalue - The default value for the attribute, can be "" for nothing
   value - the value for the attribute to use in the block inserts
   |;

(defun att_insert (source bName height mode prmpt insPt tag defvalue value /
  *acad* blk_prop_list doc doctest foundblks ins lblk newatt
  newblk oblk oblocks odbx old-atts x)
  (vl-load-com)
  (setq *acad* (vlax-get-acad-object)
doc (vla-get-activedocument *acad*)
blk_prop_list '("Color"
"InsertionPoint"
"Layer"
"Linetype"
"LinetypeScale"
"Lineweight"
"Normal"
"Rotation"
"Visible"
"XScaleFactor"
"YScaleFactor"
"ZScaleFactor"
)
)
  ;;**** Check if source file is open
  (vlax-for oDoc (vla-get-documents *acad*)
    (if (= (vla-get-fullname oDoc) source)
      (setq Doctest t)))
  (if (and (not Doctest) (findfile source))
      (progn ;; Ensure that ObjectDBX is available
(if (> (atoi (getvar "AcadVer")) 15)
 (setq oDBX (vla-GetInterfaceObject
      *acad* "ObjectDBX.AxDbDocument.16"))
 (progn
   (if (not (vl-registry-read
      "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"))
     (startapp "regsvr32.exe"
(strcat "/s \"" (findfile "axdb15.dll") "\""))
     );;if
   (setq oDBX (vla-GetInterfaceObject
*acad* "ObjectDBX.AxDbDocument"))
   );;progn
 );;if
(vla-open oDBX source);; "opens" source for our use
;;get the blocks collection
(setq oBlocks (vla-get-blocks oDBX))
;;make sure the block is in the drawing
(if (not (vl-catch-all-error-p
  (setq oBlk (vl-catch-all-apply
'vla-item
(list oBlocks bname)
)
)
  )
)
 (progn
   ;add the attribute
   (setq newAtt (vlax-invoke oBlk 'addattribute
  height mode prmpt insPt tag defvalue
  )
 )
   ;;may want to adjust layer, textstyle, etc. of the att here
   ;;cycle through all layouts
   (vlax-for layout (vla-get-layouts oDBX)
     ;;cycle through all entities in the layout's block
     (vlax-for obj (setq lBlk (vla-get-block layout))
;;check if it's an insert and if it's our block's name
(if (and (eq "AcDbBlockReference" (vla-get-objectname obj))
(eq bname (vla-get-name obj)))
 (progn
   ;;it is so make reference to it
   (setq foundBlks (cons obj foundBlks))
   )
 )
)
     ;;now that we've checked for inserts, add new inserts to replace the old
     (foreach ins foundBlks
;;insert with bogus data
(setq newBlk (vlax-invoke lBlk 'insertblock '(0.0 0.0 0.0) bname 1.0 1.0 1.0 0.0))
;;set data to match original
(mapcar '(lambda (x)
  (vlax-put newblk x (vlax-get ins x)))
blk_prop_list)
(if (eq (vla-get-hasattributes ins) :vlax-true)
 (progn
   (setq old-atts (vlax-invoke ins 'getattributes))
   (foreach att (vlax-invoke newBlk 'getattributes)
     (foreach old-att old-atts
(if (eq (vla-get-tagstring old-att)(vla-get-tagstring att))
 (vla-put-textstring att (vla-get-textstring old-att))
 )
)
     (if (eq (vla-get-tagstring att) tag)
(vla-put-textstring att value)
);if
     );for att
   );progn
 );if
;;remove old insert
(vla-delete ins)
                (setq foundblocks nil)
);for inserts
     );for layout
   );progn
 );if block
(vla-saveas oDBX source)
(vlax-release-object oDBX)
);progn
    );if
  (princ)
  );defun


(defun c:test ()
  (princ "\nTesting.....")
  (att_insert "c:/test2000.dwg" "TDG" 0.08 0 "Test attribute" '(1.0 2.0 0.0)
    "TestTag" "XXX" "ZZZZZZ")
  )

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« Reply #4 on: January 12, 2005, 05:33:24 PM »
Thanks Jeff, gonna go home to try it. In meantime, this is what I worked on last night:
Code: [Select]
(defun att2Blk (sDwgName sBlkName / blocs dbxDoc)

  ;;**** Check if source file is open
  (vlax-for oDoc (vla-get-documents *acad*)
    (if (= (vla-get-fullname oDoc) sDwgName)
      (setq Doctest t)
    )
  )
      (if (> (atoi (getvar "AcadVer")) 15) ;Ensure that ObjectDBX is available
(setq dbxDoc (vla-GetInterfaceObject
    *acad*
    "ObjectDBX.AxDbDocument.16"
  )
)
(progn
 (if (not (vl-registry-read
    "HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"
  )
     )
   (startapp "regsvr32.exe"
     (strcat "/s \"" (findfile "axdb15.dll") "\"")
   )
 )  ;;if
 (setq dbxDoc (vla-GetInterfaceObject
      *acad*
      "ObjectDBX.AxDbDocument"
    )
 )
) ;;progn
      )      ;;if

  (vla-open dbxDoc sDwgName)
  (vla-addAttribute
    (vla-item (vla-get-blocks dbxDoc)
     sBlkName
    )
    2.5
    acAttributeModeInvisible
    "prompt"
    (vlax-3d-point (list 0 0 0))
    "tag"
    "value"
  )

  (vlax-release-object dbxDoc)
;;  (vla-item blocs sBlkName)
)

If I understand your code, it appears that you are dis-assembling a block then re-build it with attribute added, and re-insert it! Is it needed? Is there a way to approach it like above - which by the way does not work; so I might have my answer :(. In my drawings, a block will be listed in table of record but not necessarily inserted! I appreciate your help Jeff, as well as explanations at what not to use. Regards.

Jeff_M

  • King Gator
  • Posts: 4100
  • C3D user & customizer
Jeff_M or anyone familiar with ObjectDBX
« Reply #5 on: January 12, 2005, 05:50:00 PM »
Hi Serge,
No, I am not dis-assembling the block. I just make sure it exists in the block table, add the attribute to the definition, step through all entities in all layouts (I just realized I didn't check for and handle locked layers), if the block is inserted anywhere all of the data for it (layer, linetype, color, attributes, etc.) is copied into a new insertion of that block. This forces the insert to include the new attribute we added.

If the block has not been inserted yet, then only the block def is modified.

HTH

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« Reply #6 on: January 13, 2005, 06:28:59 PM »
Hi Jeff,
Sent a message to your pm box, but there is no trace in my sent, so would assume you have not received it! Upon investigating your code, I noticed (vla-saveas and added to mine and presto it works:
 (vla-saveas dbxDoc sBlkName)
  (vlax-release-object dbxDoc)
There might be some differences, they will come up upon further testing. I know for a fact that my requirements are not so strict, using ObjectDCL, there is a function reading blocks inside a drawing - no need for testing it exists... Still I wanna study yours because it looks for attributes, it'll help me checking if a particular attrib. is already there. And, yes, your code works regardles if the block is inserted or not. Thanks again.

Jeff_M

  • King Gator
  • Posts: 4100
  • C3D user & customizer
Jeff_M or anyone familiar with ObjectDBX
« Reply #7 on: January 13, 2005, 08:05:54 PM »
Nope, no PM's recently.....
I'm glad you can put it to use, even if it's only for educational purposes!

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« Reply #8 on: January 14, 2005, 05:04:57 PM »
Hi again Jeff,
Forgot to ask you a question yesterday about the field:
Quote
value - the value for the attribute to use in the block inserts.
"XXX" "ZZZZZZ") <<-- What is ZZZZZZ for?

What is the difference between the default value and that one?

Jeff_M

  • King Gator
  • Posts: 4100
  • C3D user & customizer
Jeff_M or anyone familiar with ObjectDBX
« Reply #9 on: January 15, 2005, 03:33:24 AM »
Hi Serge,
Sorry for the delay...today was my 'commute' day (500 miles each way to the office only gets done twice a month).

I used a second value to fill in the inserted attribute since an attribute will usually not be a consistent value and mine are almost never the same as the default.

Serge J. Gianolla

  • Guest
Jeff_M or anyone familiar with ObjectDBX
« Reply #10 on: January 15, 2005, 09:58:49 PM »
Man,
That's a harsh company to make you go and get your pay cheque like this! :lol:  Ah well, I suppose the plus side is the old cliche, travelling broadens your horizon.