Results 1 to 10 of 10

Thread: Create Field to DB Param - Pragramatically

  1. #1
    Certifiable AUGI Addict irneb's Avatar
    Join Date
    2007-07
    Location
    Jo'burg SA
    Posts
    4,344

    Default Create Field to DB Param - Pragramatically

    I'm trying to write some code to place a field which shows the value of a DB Parameter. E.g. say the block's name is "BlockX" and the Parameter is "Lenght1". If I have an instance of this block and get its Com Object, I can get the following:
    Code:
    (setq BlockRefID (vla-get-ObjectID BlockRefObj)) ;Get the ID number, e.g. 2124660792
    (setq PropList (vlax-Invoke BlockRefObj "GetDynamicBlockProperties")) ;Get list of Parameters
    (setq n 0 ;Initialize counter
          PropObj nil ;Initialize object
    )
    ;; Step through list
    (while (or (not PropObj) ;Until found, or
               (< n (length PropList)) ;Till end of list
           )
      ;; Check for prop's name
      (if (= (strcat (vla-get-PropertyName (nth n PropList))) "LENGTH1")
        (setq PropObj (nth n PropList)) ;Set the found object, else
        (setq n (1+ n)) ;Increment counter
      )
    )
    Now the Com Object of the parameter saved in the PropObj variable has the value and some properties available. There's nothing like an ObjectID or such. If I do a manual field of this DB+Param I get the following field code:
    Code:
    %<\AcObjProp Object(%<\_ObjId 2124660792>%).Parameter(42).UpdatedDistance>%
    Now clearly the ObjectID is the block reference's ID as saved in the BlockRefID variable. However, how do I get hold of the 42 number to identify which Parameter?

    A vlax-dump-object of the ParamObj gives:
    Code:
    ; IAcadDynamicBlockReferenceProperty: AutoCAD Dynamic Block Property Interface
    ; Property values:
    ;   AllowedValues (RO) = (1210.0 1510.0 1615.0 1790.0 1990.0)
    ;   Description (RO) = ""
    ;   PropertyName (RO) = "Length1"
    ;   ReadOnly (RO) = 0
    ;   Show (RO) = -1
    ;   UnitsType (RO) = 2
    ;   Value = 1510.0
    ; No methods
    It's the 1st (i.e. index number 0) of the Parameters in the PropList ... so that's not it.

    Trying to get the DXF values of the Param using:
    Code:
    (setq PropEname (vlax-vla-object->ename PropObj))
    This returns nil, so there's no way of doing this either.

    Even looking through the ObjectARX & DotNet Managed help files I can't find anywhere which would give me this index code. Anyone got a clue?
    Knowledge is proportional to experience, but wisdom is inversely proportional to ego!
    My little bit of "wisdom": Hind-sight is useless, unless used to improve the next forethought!

  2. #2
    Administrator RobertB's Avatar
    Join Date
    2001-08
    Location
    Dallas TX USA
    Posts
    5,825

    Default Re: Create Field to DB Param - Pragramatically

    Would Length1 happen to be the 43rd property in the property collection?
    R. Robert Bell
    Design Technology Manager
    S P A R L I N G
    Opinions expressed are mine alone and do not reflect the views of Sparling.

  3. #3
    Certifiable AUGI Addict irneb's Avatar
    Join Date
    2007-07
    Location
    Jo'burg SA
    Posts
    4,344

    Default Re: Create Field to DB Param - Pragramatically

    Nope, I think I stated it's the 1st in the list returned from that collection using vlax-Invoke -> GetDynamicBlockProperties. It's also the 1st in the safe array if I use vlax-Invoke-Method or vla-GetDynamicBlockProperties instead. I.e. I'd have expected the 42 to be 0 instead.

    Just now saw an error in my original post. The strcat should have been strcase, but that's not solving the issue though
    Knowledge is proportional to experience, but wisdom is inversely proportional to ego!
    My little bit of "wisdom": Hind-sight is useless, unless used to improve the next forethought!

  4. #4
    AUGI Addict
    Join Date
    2005-08
    Posts
    1,043

    Default Re: Create Field to DB Param - Pragramatically

    This seems to get them, but you will have to do more research, as I don't see how it gets the function names; ie ' UpdateDistance '. Mine only showed three that were allowed in the field dialog box, and they have the correct numbers associated with them in the list returned, but as you can see there are more than three returned. You will have to figure out exactly what to do. Sorry. Hope it helps some.

    Code:
    (defun GetParameterNumber ( blkName / EntData BlkRecData DictData tempData DataList )
        
        (setq EntData (entget (tblobjname "block" blkName)))
        (setq BlkRecData (entget (cdr (assoc 330 EntData))))
        (setq DictData (dictsearch (cdr (assoc 360 BlkRecData)) "ACAD_ENHANCEDBLOCK"))
        (while (setq tempData (car DictData))
            (if
                (and
                    (equal (car tempData) 95)
                    (equal (caadr DictData) 360)
                    (wcmatch (strcase (cdr (assoc 0 (entget (cdadr DictData))))) "*PARAMETER")
                )
                (progn
                    (setq DataList (cons (cons (cdr tempData) (cdadr DictData)) DataList))
                    (setq DictData (cddr DictData))
                )
                (setq DictData (cdr DictData))
            )
        )
        DataList
    )
    Returned
    Code:
    (225 . <Entity name: 7ed75508>)
    (212 . <Entity name: 7ed754f0>)
    (194 . <Entity name: 7ed754d0>)
    (182 . <Entity name: 7ed754a0>)
    (158 . <Entity name: 7ed75478>)
    (125 . <Entity name: 7ed75468>)
    (29 . <Entity name: 7ed75440>)
    (9 . <Entity name: 7ed75420>)

  5. #5
    Certifiable AUGI Addict irneb's Avatar
    Join Date
    2007-07
    Location
    Jo'burg SA
    Posts
    4,344

    Default Re: Create Field to DB Param - Pragramatically

    Thanks Tim ... I never thought about looking at the dictionaries

    This really works, I made a bit of a change so it would work in my code:
    Code:
    ;;; Function to obtain a list of DynamicBlock (ParameterName . ParameterNumber) pairs.
    (defun GetParameterNumber    (blkName / EntData BlkRecData DictData tempData DataList ParamData)
        (setq EntData (entget (tblobjname "block" blkName))) ;Get the block definition's DXF list
        (setq BlkRecData (entget (cdr (assoc 330 EntData)))) ;Get the BlockRecord's DXF list
        (setq DictData (dictsearch (cdr (assoc 360 BlkRecData)) "ACAD_ENHANCEDBLOCK")) ;Get the EnhacedBlock Dictionary
        (while (setq tempData (car DictData)) ;Step through the dictionary one list item at a time
            (if
                (and
                    (equal (car tempData) 95) ;Check for 95 DXF code
                    (equal (caadr DictData) 360) ;And 360 code
                    (wcmatch (strcase (cdr (assoc 0 (setq ParamData (entget (cdadr DictData)))))) ;Get the Dictionary Entry's Type
                                     "*PARAMETER" ;And if it's a Parameter
                    ) ;_ end of wcmatch
                ) ;_ end of and
                 (progn
                     (setq DataList    (cons ;Add to the Data List
                                                        (cons    (cdr (assoc 300 ParamData)) ;Parameter Name
                                                                    (cdr tempData) ;Parameter Number
                                                        ) ;_ end of cons
                                                        DataList
                                                    ) ;_ end of cons
                     ) ;_ end of setq
                     (setq DictData (cddr DictData)) ;Step to next item in dictionary
                 ) ;_ end of progn
                 (setq DictData (cdr DictData)) ;Step to next item in dictionary
            ) ;_ end of if
        ) ;_ end of while
        (reverse DataList) ;Return the Data List in original order
    ) ;_ end of defun
    Now a simple assoc with the Parameter Name gives you the number to use in a field code! Thanks again! This really stumped me!
    Knowledge is proportional to experience, but wisdom is inversely proportional to ego!
    My little bit of "wisdom": Hind-sight is useless, unless used to improve the next forethought!

  6. #6
    AUGI Addict
    Join Date
    2005-08
    Posts
    1,043

    Default Re: Create Field to DB Param - Pragramatically

    Glad you were able to make it work for you. You're welcome.

  7. #7
    Certifiable AUGI Addict irneb's Avatar
    Join Date
    2007-07
    Location
    Jo'burg SA
    Posts
    4,344

    Default Re: Create Field to DB Param - Pragramatically

    Quote Originally Posted by T.Willey View Post
    This seems to get them, but you will have to do more research, as I don't see how it gets the function names; ie ' UpdateDistance '. Mine only showed three that were allowed in the field dialog box, and they have the correct numbers associated with them in the list returned, but as you can see there are more than three returned. You will have to figure out exactly what to do. Sorry. Hope it helps some.
    OK, did some more research. Phew! It wasn't easy. Had to export all the dictionary's DXF data to CSV to compare just what is where and how. Anyhoo, here's the modified function:
    Code:
    ;;; Utility to get a list of Dynamic Block Properties for inclusion into Fields
    (defun Tags:GetDBProperties (blkName / EntData BlkRecData DictData tempData DataList ParamData)
      (setq EntData (entget (tblobjname "block" blkName))) ;Get the block definition's DXF list
      (setq BlkRecData (entget (cdr (assoc 330 EntData)))) ;Get the BlockRecord's DXF list
      (setq DictData (dictsearch (cdr (assoc 360 BlkRecData)) "ACAD_ENHANCEDBLOCK")) ;Get the EnhacedBlock Dictionary
      (while (setq tempData (car DictData)) ;Step through the dictionary one list item at a time
        (if    (and
          (equal (car tempData) 95) ;Check for 95 DXF code
          (equal (caadr DictData) 360) ;And 360 code
          (wcmatch ;Get the Dictionary Entry's Type
            (strcase (cdr (assoc 0 (setq ParamData (entget (cdadr DictData))))))
            "*PARAMETER" ;And if it's a Parameter
          ) ;_ end of wcmatch
        ) ;_ end of and
          (progn
        (cond
          ((= (cdr (assoc 0 ParamData)) "BLOCKROTATIONPARAMETER") ;Rotation Parameter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 305 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedAngle" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKFLIPPARAMETER") ;Flip Parapeter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 305 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedFlip" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKLINEARPARAMETER") ;Linear Parameter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 305 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedDistance" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKLOOKUPPARAMETER") ;Lookup Parameter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 303 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "lookupString" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKPOINTPARAMETER") ;Point Parameter - XY
           (setq DataList (cons ;Add to the Data List
                    (list (strcat (cdr (assoc 303 ParamData)) " X") ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedX" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
           (setq DataList (cons ;Add to the Data List
                    (list (strcat (cdr (assoc 303 ParamData)) " Y") ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedY" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKPOLARPARAMETER") ;Polar Parameter - Dist + Ang
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 307 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedAngle" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 305 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedDistance" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKVISIBILITYPARAMETER") ;Visibility Parameter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 301 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "VisibilityState" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
          ((= (cdr (assoc 0 ParamData)) "BLOCKXYPARAMETER") ;XY Parameter
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 306 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedDistanceX" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
           (setq DataList (cons ;Add to the Data List
                    (list (cdr (assoc 305 ParamData)) ;Parameter Label
                      (cdr tempData) ;Parameter Number
                      "UpdatedDistanceY" ;Field Function
                    ) ;_ end of list
                    DataList
                  ) ;_ end of cons
           ) ;_ end of setq
          )
        ) ;_ end of cond
        (setq DictData (cddr DictData)) ;Step to next item in dictionary
          ) ;_ end of progn
          (setq DictData (cdr DictData)) ;Step to next item in dictionary
        ) ;_ end of if
      ) ;_ end of while
      (reverse DataList) ;Return the Data List in original order
    ) ;_ end of defun
    It gets a list of Parameter labels (as you'd see in the field dialog) {ignoring parameters like Base Point & Alignment}, followed by the parameter number, and finally the Field's function.
    Knowledge is proportional to experience, but wisdom is inversely proportional to ego!
    My little bit of "wisdom": Hind-sight is useless, unless used to improve the next forethought!

  8. #8
    AUGI Addict
    Join Date
    2005-08
    Posts
    1,043

    Default Re: Create Field to DB Param - Pragramatically

    How did you get what you are calling ' field function '? Did you grab that through the field dialog box for your specific block? Or are they the same always? I don't use dy. blocks really, so this is more for my understanding.

    Thanks in advance.

  9. #9
    Certifiable AUGI Addict irneb's Avatar
    Join Date
    2007-07
    Location
    Jo'burg SA
    Posts
    4,344

    Default Re: Create Field to DB Param - Pragramatically

    I created a test block with one of each parameter type. Named each to something distinct. Then (as mentioned in my previous post extracted all the dictionary's data to csv). Created a field for each parameter and noted the "Function" at the end of each's field code. E.g. a linear parameter gives:
    Code:
    %<\AcObjProp Object(%<\_ObjId 2130435584>%).Parameter(42).UpdatedDistance>%
    Basically the code checks the entity type (code 0) of each dictionary entry. Then from that I noted which 30# code held the Field's label, and in some cases (like XY Parameters) the same dictionary item holds 2x labels - thus I create 2 items in the list to be returned for those.
    Knowledge is proportional to experience, but wisdom is inversely proportional to ego!
    My little bit of "wisdom": Hind-sight is useless, unless used to improve the next forethought!

  10. #10
    AUGI Addict
    Join Date
    2005-08
    Posts
    1,043

    Default Re: Create Field to DB Param - Pragramatically

    Thanks. I thought that was how you did it, just wanted to make sure.

Similar Threads

  1. Why not a param on a closestpoint ?
    By devitg.89838 in forum AutoLISP
    Replies: 2
    Last Post: 2012-01-05, 07:30 PM
  2. How to Param. a Polygon
    By ljupadhyay in forum Revit Architecture - Families
    Replies: 2
    Last Post: 2009-12-02, 06:11 PM
  3. Assign a string to an instance param based on a yes/no param
    By Eric Stewart in forum Revit Architecture - Families
    Replies: 2
    Last Post: 2008-01-28, 03:46 PM
  4. Yes / No param
    By gwnelson in forum Revit Architecture - Families
    Replies: 1
    Last Post: 2007-06-22, 06:10 PM
  5. Replies: 0
    Last Post: 2007-04-03, 04:35 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •