Author Topic: insert value into attribute  (Read 8061 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: insert value into attribute
« Reply #15 on: November 13, 2012, 12:09:52 PM »
I would like to not have to select the block, but to indicate it programmatically.  Have not had much success in that regard.

Bruce

When you say "it" do you mean that there is only one INSERT in the drawing of that block?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #16 on: November 17, 2012, 01:39:18 PM »
CAB,

That is correct, there will only be one instance of the block in the drawing.  All attributes in the block is set to invisible, and the block consist of nothing but attributes, so the user will not know the block exist.  I am experimenting with using blocks in this way to store information, I need to be able to retrieve this information (not an issue) and update the information.  I was using the attedit command, however there seems to be issues when using symbols (the "@" symbol for example) and the attedit command.  So I am looking for a way to update attributes in the block in other ways.  There are approximately 70 bits of information I would like to save in each drawing (design criteria for running automated functions).

I have been storing the information in external data files, very cumbersome and prone to synchronization issues, as undo commands do not reflect in the external files.  Also leads to issues when the user tries to perform a "Save As" command. 

Thanks,

Bruce


CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: insert value into attribute
« Reply #17 on: November 17, 2012, 07:04:08 PM »
Maybe this will help.
Code - Auto/Visual Lisp: [Select]
  1. ;;=======================[ AttUpdate.lsp ]=======================
  2. ;;; Author: Charles Alan Butler
  3. ;;; Version:  1.1 May 20, 2006
  4. ;;; Purpose: To update attributes in a drawing, nested blocks & xref
  5. ;;;          Ignores locked or Frozen layers
  6. ;;; Sub_Routines: -None
  7. ;;; Requirements: -set var to your block name & tag list to update
  8. ;;; Returns: -None
  9. ;;;==============================================================
  10. ;;
  11. (defun c:attupdate ()
  12.   ;;  preset variables for automatic mode
  13.   (or blkname (setq blkname "MyBlockName"))
  14.   (or taglist (setq taglist '(("TagName" "New text")("TagName" "New text"))))
  15.   (global_atts blkname taglist)
  16.   (princ)
  17. )
  18. (prompt "\nAttUpdate Loaded, Enter AttUpdate to run.")
  19.  
  20.  
  21. ;; CAB 01/20/2006
  22. ;; Function to update selected attributes of a given block
  23. ;; only those included in the list will be updated **
  24. ;; usage- (global_atts "BlockName" ((tag_name new_value)...))
  25. ;;
  26. ;; Arguments
  27. ;;  bname    block text label
  28. ;;  attlist list as described above
  29. ;; Returns the block count if successful or nil
  30. (defun global_atts (bname attlist / blk ename hit idx ss)
  31.   (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 bname) '(66 . 1))))
  32.     (progn
  33.       (prompt "\n***  Updating Blocks, Please wait. ***\n")
  34.       ;;  force tag name to upper case
  35.       (setq attlist (mapcar '(lambda(x) (list (strcase (car x)) (cadr x))) attlist))
  36.       (setq idx -1)
  37.       (while (setq ename (ssname ss (setq idx (1+ idx))))
  38.         (setq blk (vlax-ename->vla-object ename))
  39.         (foreach att (vlax-invoke blk 'getattributes)
  40.           (if (setq hit (assoc (strcase (vla-get-tagstring att)) attlist))
  41.             (vla-put-textstring att (cadr hit))
  42.           )
  43.         )
  44.         (vla-update blk)
  45.       )
  46.       (if (not (minusp idx)) (1- idx))
  47.     )
  48.   )
  49. )
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #18 on: November 18, 2012, 12:16:39 PM »
CAB,

Thanks for the reply, both sets of code supplied work great.   8-)

Bruce

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: insert value into attribute
« Reply #20 on: November 19, 2012, 03:20:16 PM »
Danger Will Robinson, Danger!

Invisible blocks like these can turn into a royal PITA follwing the "out of sight, out of mind" principle.  I've seen these types of blocks get nested several deep into symbol blocks, such as doing touch-ups on symbol block DWGs where the invisible data block is automatically added.  Those blocks get copied, exploded, re-blocked, selectively WBLOCK'd elsewhere.  Those drawings get inserted wholesale into others.  Within a very short period of time you can get thousands of instances of these in your drawings; some are resident in the drawing, others are nested into various other blocks.

So seconded on the recommendation for XDATA or XRECORDs.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #21 on: November 19, 2012, 07:22:15 PM »
Dgorsman & CAB,

Thanks for the xdata advice, I have never tried working with xdata or dictionaries in the past.  Any idea on limitations i.e.; string lengths, real or integers ?  I have the need to store all types of information strings, reals & integers.  I will look into this since I really only want to fix this issue once (dispose of the external files). 

Thanks,

Bruce


irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: insert value into attribute
« Reply #22 on: November 20, 2012, 05:51:21 AM »
XData has a size limit per entity. Dictionaries have no limit at all. XData only accepts certain data types in certain code groups, dictionaries can accept nearly any data type anywhere.
Personally I think dictionaries is the way to go in your case - since you can "attach" a dictionary to the DWG and need not attach it to something "inside" the DWG. Actually the simplest built-in method of using dictionaries is through the vlax-ldata-* functions.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #23 on: November 22, 2012, 05:23:56 PM »
CAB,
I have taken your advise and decided to use "XRECORDS",  I have been successful in creating a sub-dictionary within the main dictionary and an XRECORD within my sub-dictionary.  I have successfully placed data into this dictionary and can read the data.  My issue is with modifying the data, see structure below and function I am working on to modify the data.

>Main Dictionary
    >Sub-Dictionary (SADATA_DICT)
        >XRECORD (LDATA_VARS)

I am currently using the 410-419 DXF Group codes for testing.

Code: [Select]
(defun update_Xrecord ( DATA_VARS DXF_VAL MOD_VAL / xRecVar)
  (setq xRecVar (get-or-make-Xrecord DATA_VARS))
  (entmod (subst (cons DXF_VAL MOD_VAL)(assoc DXF_VAL xRecVar) xRecVar))
  )

(update_Xrecord "LDATA_VARS" 410 "Update test successful !")
 
(setq DATA_VARS "LDATA_VARS")

I am getting the following error "; error: bad argument type: listp <Entity name: 7eb4aa60>"

Any help or advise would be appreciated.

Thanks,

Bruce

Happy Thanksgiving to all......
 

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #24 on: November 23, 2012, 06:48:12 AM »
Well the entmod function was working erratically, seemed to be appending to the end of the xrecord instead of modifying it.  So I ended up doing the following;
    1.- Create list of the existing xrecord, in a Sub-Dictionary within the NOD.
    2.- Substitute values in the list for new values based on their DXF Group Codes.
    3.- Delete the original Xrecord.
    4.- Create a New Xrecord based on the Substituted List.

Thanks CAB for the advice to go this route, it will definitely make it difficult for the Users to mess up the data saved withing the Drawing..   8-)



irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: insert value into attribute
« Reply #25 on: November 23, 2012, 07:08:09 AM »
Have you seen the help on XRecords: http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7970.htm
You can only use codes from 1 through 369 (excluding 5 and 105).
And to see which code takes what type of data: http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a64.htm
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: insert value into attribute
« Reply #26 on: November 23, 2012, 08:31:13 AM »
Well the entmod function was working erratically, seemed to be appending to the end of the xrecord instead of modifying it.  So I ended up doing the following;
    1.- Create list of the existing xrecord, in a Sub-Dictionary within the NOD.
    2.- Substitute values in the list for new values based on their DXF Group Codes.
    3.- Delete the original Xrecord.
    4.- Create a New Xrecord based on the Substituted List.

Thanks CAB for the advice to go this route, it will definitely make it difficult for the Users to mess up the data saved withing the Drawing..   8-)

That's the ticket. Replace and not update.
http://www.theswamp.org/index.php?topic=5003.0
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: insert value into attribute
« Reply #27 on: November 23, 2012, 05:03:09 PM »
irned,

I was hoping to use a different DXF Group Code for each of my string variables, however due to the limit of 10 (300-309) DXF Group Codes for strings that line of thought will not work.  In my experimenting to date I have used 410-412 group codes in the XRECORD entity without issue.  Even after shutting the machine down and restarting the values are still intact. 

It appears I will need to use a single group code for 20 different strings.  I have been experimenting and researching how to call say the 3rd instance of group code 300.  I have not had much luck in accomplishing this task.  Since I may not have any idea on the contents of the string, I would really like to use say the 3rd instance of Group Code 300.

Here is my line of code to substitute the new text string (MOD_VAL)  in the (xRecFile) XRECORD entity.  This line will modify the 1st instance of the Group Code (DXF_VAL) found.

Code: [Select]
  (setq Values (subst (cons DXF_VAL MOD_VAL)(assoc  DXF_VAL xRecFile)xRecFile))

Any thoughts on how to perform the "subst" function on the 3rd instance of the group code.

Please correct me if I am wrong, if the drawings containing the xrecords with group codes over the 369 limit are not exported to dxf format and subsequently imported from dxf format then the 410-409  & 470-479 string type series of group codes will work fine.

Thanks,

Bruce

« Last Edit: November 24, 2012, 02:12:11 AM by snownut2 »

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: insert value into attribute
« Reply #28 on: November 24, 2012, 08:09:47 AM »
I have been experimenting and researching how to call say the 3rd instance of group code 300.

Consider the use of a 'mAssoc' function, (there are many variations* of this function):

Code - Auto/Visual Lisp: [Select]
  1. ;; mAssoc  -  Lee Mac
  2. ;; Returns all associations of a key in an association list
  3.  
  4. (defun LM:mAssoc ( key lst / item )
  5.     (if (setq item (assoc key lst))
  6.         (cons (cdr item) (LM:mAssoc key (cdr (member item lst))))
  7.     )
  8. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (setq l '((300 . "A") (123 . "B") (300 . "C") (123 . "D") (300 . "E")))
  2. ((300 . "A") (123 . "B") (300 . "C") (123 . "D") (300 . "E"))
  3. _$ (LM:mAssoc 300 l)
  4. ("A" "C" "E")


Any thoughts on how to perform the "subst" function on the 3rd instance of the group code.

Substituting one value for another:
Code - Auto/Visual Lisp: [Select]
  1. _$ (setq l (subst '(300 . "F") (cons 300 (nth 1 (LM:mAssoc 300 l))) l))
  2. ((300 . "A") (123 . "B") (300 . "F") (123 . "D") (300 . "E"))


*variations:

Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc1 ( key lst / rtn )
  2.     (foreach x lst
  3.         (if (= key (car x))
  4.             (setq rtn (cons (cdr x) rtn))
  5.         )
  6.     )
  7.     (reverse rtn)
  8. )
Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc2 ( key lst )
  2.     (apply 'append
  3.         (mapcar
  4.             (function
  5.                 (lambda ( x ) (if (= key (car x)) (list (cdr x))))
  6.             )
  7.             lst
  8.         )
  9.     )
  10. )
Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc3 ( key lst )
  2.     (mapcar 'cdr
  3.         (vl-remove-if-not
  4.             (function (lambda ( x ) (= key (car x))))
  5.             lst
  6.         )
  7.     )
  8. )
Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc4 ( key lst / item rtn )
  2.     (while (setq item (assoc key lst))
  3.         (setq rtn (cons (cdr item) rtn) lst (cdr (member item lst)))
  4.     )
  5.     (reverse rtn)
  6. )
Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc5 ( key lst )
  2.     (mapcar 'cdr (acet-list-m-assoc key lst))
  3. )
Code - Auto/Visual Lisp: [Select]
  1. (defun mAssoc6 ( key lst )
  2.     (if lst
  3.         (if (= key (caar lst))
  4.             (cons (cdar lst) (mAssoc6 key (cdr lst)))
  5.             (mAssoc6 key (cdr lst))
  6.         )
  7.     )
  8. )
« Last Edit: November 24, 2012, 08:15:34 AM by Lee Mac »

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: insert value into attribute
« Reply #29 on: November 24, 2012, 08:35:08 AM »
And for subst'ing the 3rd 300 code (even if some of them might be exactly the same), try some of these: http://www.theswamp.org/index.php?topic=41680.0
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.