Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Table(2129762560)

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
pjkPA
1541 Views, 17 Replies

Table(2129762560)

Table(2129762560)   ... I have one cell tables ...

how do I get..   Table(2129762560)   ... to show up so I can reference that table?

I need that (2129762560) number.

 

I have several one cell tables ... I want to have one table get the sum of several other one cell tables.

17 REPLIES 17
Message 2 of 18
Lee_Mac
in reply to: pjkPA

The number that you require is the Object ID of the Table object.

 

Here is my function for returning the Object ID of a VLA-Object, compatible with both 32-bit & 64-bit environments:

 

;; ObjectID  -  Lee Mac
;; Returns a string containing the ObjectID of a supplied VLA-Object
;; Compatible with 32-bit & 64-bit systems

(defun LM:objectid ( obj )
    (eval
        (list 'defun 'LM:objectid '( obj )
            (if
                (and
                    (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
                    (vlax-method-applicable-p (vla-get-utility (LM:acdoc)) 'getobjectidstring)
                )
                (list 'vla-getobjectidstring (vla-get-utility (LM:acdoc)) 'obj ':vlax-false)
               '(itoa (vla-get-objectid obj))
            )
        )
    )
    (LM:objectid obj)
)

;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object

(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (LM:acdoc)
)

 

You will need to supply the above function with the VLA-Object corresponding to your Table, and concatenate the resulting Object ID with the remainder of your Field expression.

 

Here is an example program to demonstrate how to correctly call the function:

 

(defun c:test ( / ent )
    (if (setq ent (car (entsel)))
        (print (LM:objectid (vlax-ename->vla-object ent)))
    )
    (princ)
)
(vl-load-com) (princ)

 

Lee

Message 3 of 18
pjkPA
in reply to: Lee_Mac

Thank you Lee for the detailed response.

 

I have to tell you I'm not a programmer. I'm a Electrical designer who when I have some time I do some Autocad customization.

I'm building a Panel schedule that totals the wattage from all the breakers.

 

I've put one cell tables at each breaker that the user can input a wattage.

At the bottom I have a one table cell that sums all these tables for 1 , 2, or 3 phases.

 

The total one cell table has =Table(2129762544).Evaluate(Sum(A1:A1))+Table(2129762216).Evaluate(Sum(A1:A1))+   etc etc...

   

The way I just found to get the "Object ID" to put in my totals cell sum... is to

select a dummy table then select sum then it will ask for cell.. select cell in table you want to reference .. this will give you the Object ID that you can copy and paste into the total table with a + in front of it... you can string these along and add as many as you want ...

Then when a user puts in a wattage the totals are automatically tallied in the "TOTAL" table.

 

 

 

Message 4 of 18
Lee_Mac
in reply to: pjkPA

Try the following -

 

;; Sum Single-Cell Tables  -  Lee Mac

(defun c:sumtables ( / *error* all ftr idx ins lst sel tab tmp )

    (defun *error* ( msg )
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )
    
    (cond
        (
            (null
                (setq tmp
                    (ssget "_X"
                        (setq ftr
                            (list '(0 . "ACAD_TABLE")
                                (if (= 1 (getvar 'cvport))
                                    (cons 410 (getvar 'ctab))
                                   '(410 . "Model")
                                )
                            )
                        )
                    )
                )
            )
            (princ "\nNo tables found in the active layout.")
        )
        (   (progn
                (repeat (setq idx (sslength tmp))
                    (setq all (cons (vlax-ename->vla-object (ssname tmp (setq idx (1- idx)))) all))
                )
                (setq sel (ssget ftr))
            )
            (repeat (setq idx (sslength sel))
                (setq lst
                    (vl-list*
                        " + "
                        "Table(%<\\_ObjId "
                        (LM:objectid (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
                        ">%).A1"
                        lst
                    )
                )
            )
            (while
                (and
                    (setq ins (getpoint "\nPick cell for result: "))
                    (null (setq tab (LM:getcell all (trans ins 1 0))))
                )
                (princ "\nNo cell found.")
            )
            (if tab
                (apply 'vla-settext
                    (append tab
                        (list
                            (strcat
                                "%<\\AcExpr ("
                                (apply 'strcat (cdr lst))
                                ")>%"
                            )
                        )
                    )
                )
            )
        )
    )
    (princ)
)

;; Get Cell  -  Lee Mac
;; If the supplied point lies within a cell boundary,
;; returns a list of: (<VLA Table Object> <Row> <Col>)

(defun LM:getcell ( lst pnt / dir )
    (setq dir (vlax-3D-point (trans (getvar 'viewdir) 1 0))
          pnt (vlax-3D-point pnt)
    )
    (vl-some
       '(lambda ( tab / row col )
            (if (= :vlax-true (vla-hittest tab pnt dir 'row 'col))
                (list tab row col)
            )
        )
        lst
    )
)

;; ObjectID  -  Lee Mac
;; Returns a string containing the ObjectID of a supplied VLA-Object
;; Compatible with 32-bit & 64-bit systems

(defun LM:objectid ( obj )
    (eval
        (list 'defun 'LM:objectid '( obj )
            (if
                (and
                    (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
                    (vlax-method-applicable-p (vla-get-utility (LM:acdoc)) 'getobjectidstring)
                )
                (list 'vla-getobjectidstring (vla-get-utility (LM:acdoc)) 'obj ':vlax-false)
               '(itoa (vla-get-objectid obj))
            )
        )
    )
    (LM:objectid obj)
)

;; Active Document  -  Lee Mac
;; Returns the VLA Active Document Object

(defun LM:acdoc nil
    (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (LM:acdoc)
)

(vl-load-com) (princ)

 

Select your set of single-cell tables and then pick the relevant table cell to contain the formula field result.

 

Lee

Message 5 of 18
dbroad
in reply to: Lee_Mac

Lee,

I am curious how your functionLM:acdoc is better than

(vlax-get-activedocument(vlax-get-acad-object))

 

or perhaps

(defun acdoc ()

 (vlax-get-activedocument(vlax-get-acad-object))

)

 

and how your function LM:objectid is better than 

(vla-get-objectid obj) ;;if you want a number

or

(itoa (vla-get-objectid obj)) ;;if you want a string.

 

It would seem a function like below would be simpler

(defun objectidstring (obj)

(itoa(vla-get-objectid obj))

)

 

Forgive me if I am missing something.  I just looked briefly.

 

Architect, Registered NC, VA, SC, & GA.
Message 6 of 18
dbroad
in reply to: pjkPA

pjkPA,

Why use single cell tables?  I don't get it.  I use excel spreadsheets for my panelboards and OLE for putting them into a drawing.  But you could just use a single table for the panel.  If you want to show the breakers graphically, you might be able to use tinsert a breaker symbol into each cell and/or merge some cells for multiple breakers

 

AutoCAD MEP also has some nice panel features that work directly with circuits.

 

Can you post a drawing of one of your panels?

Architect, Registered NC, VA, SC, & GA.
Message 7 of 18
pjkPA
in reply to: dbroad

We do have a XLS spreadsheet Panels .. but we have many users and they are all not that familiar with XLS and ACAD... I have come up with this because it's all autocad .. no external files and in the clients format for the panel.

 

Yes .. XLS is my preferred method.. but its not as easy to use for many people who are not  XLS and Acad seasoned experts... they have to be linked or copy and paste info.

 

When you are using hundreds of drawings which involve many people.. things have to be simple... not everyone who inputs to these panels are seasoned CAD personnel.

 

And clients want things all on one drawing... and in their format.  It's easy to adapt to their format with these one cell tables.

 

Thanks.

 

 

Message 8 of 18
Lee_Mac
in reply to: dbroad


@dbroad3 wrote:

Lee,

I am curious how your function LM:acdoc is better than

 

(vlax-get-activedocument(vlax-get-acad-object))

 

or perhaps

(defun acdoc ()

    (vlax-get-activedocument(vlax-get-acad-object))

)

 

and how your function LM:objectid is better than 

(vla-get-objectid obj) ;;if you want a number

or

(itoa (vla-get-objectid obj)) ;;if you want a string.

 

It would seem a function like below would be simpler

(defun objectidstring (obj)

    (itoa(vla-get-objectid obj))

)

 

Forgive me if I am missing something.  I just looked briefly.


Hi Doug,

 

The use of defun-q should help to explain the difference between the two constructs:

 

Consider the following functions:

 

(defun-q f1 nil
    (vla-get-activedocument (vlax-get-acad-object))
)
(defun-q f2 nil
    (eval (list 'defun-q 'f2 'nil (vla-get-activedocument (vlax-get-acad-object))))
    (f2)
)

 

Before function evaluation, the respective function definitions are as follows:

 

_$ f1
(nil (vla-get-ActiveDocument (vlax-get-acad-object)))
_$ f2
(nil (EVAL (LIST (QUOTE DEFUN-Q) (QUOTE F2) (QUOTE nil) (vla-get-ActiveDocument (vlax-get-acad-object)))) (F2))

 

When evaluated, both functions will return the Active Document object:

 

_$ (f1)
#<VLA-OBJECT IAcadDocument 0ceb5b6c>
_$ (f2)
#<VLA-OBJECT IAcadDocument 0ceb5b6c>

 

However, observe the respective function definitions following function evaluation:

 

_$ f1
(nil (vla-get-ActiveDocument (vlax-get-acad-object)))
_$ f2
(nil #<VLA-OBJECT IAcadDocument 0ceb5b6c>)

 

Note that function f2 now no longer retrieves the Application Object (vlax-get-acad-object) before retrieving the Active Document Property (vla-get-activedocument), but simply returns the Active Document object directly. The method is similar to setting a global variable pointing to the Active Document Object.

 

However, by using self-redefining functions we are not limited to global constants and the functions will be optimised for repeated calls - as demonstrated by my Object ID function.

 

Since the scope of AutoLISP is limited to the document namespace, I can confidently instruct the LM:acdoc function to be redefined to return the Active Document object, since this object will not change for the lifetime of the function.

 

Similarly, with the Object ID function: after the first call to this function, the function automatically redefines itself for optimisation for either a 32-bit or 64-bit environment - another setting that will not change for the lifetime of the function definition. Following the first call, the Object ID function will no longer test whether the system is 32-bit or 64-bit, and furthermore if 64-bit, the function will no longer retrieve the Utility object since this object becomes a defined constant in the self-optimised version of the function.

 

I use this technique frequently to achieve function optimisation for functions performing an operation which only need be performed once for the lifetime of the function definition.

 

To cite several other examples, see the following from my site:

 

GrText - 'LM:GrText' function

Extract Nested Block - 'enb:copy' function

Nested Move - 'LM:blockname' function

 

Lee

Message 9 of 18
dbroad
in reply to: Lee_Mac

Lee,

Thank you for that excellent explanation.  I had forgotten about defun-q and now better understand your intentions with both functions.  I did some testing on my 64bit system and found that there was no significant difference in the timings between your optimized functions and the simplified forms in AutoCAD 2014.

Given that source code that is simple to read is easier to maintain and given that independent functions, when no larger, are easier to maintain, I would probably continue to use the simpler though less optimized approach.

For example, the use of LM:acdoc within LM:objectid, crashed my tests of LM:objectid until I had both functions loaded.  I used to do the same thing in all my programs, using special functions to save primarily a few coding keystrokes. Example:

(defun cda (e)(cdr(assoc e))); This function saved me a few keystrokes but made all my functions dependent on my libraries.  It also made it harder for others to tell what I was doing.

Disclaimer:  I used Robert Bell's bench program to test.  In that test program, it appeared that the order of the elements in the test list affected the results more than the differences between the programs.

Sample:

(bench '(LM:objectid oidstring) (list o) 10000)

LM:OBJECTID
Elapsed: 328
Average: 0.0328

OIDSTRING
Elapsed: 436
Average: 0.0436

(bench '(oidstring LM:objectid) (list o) 10000)

OIDSTRING
Elapsed: 281
Average: 0.0281

LM:OBJECTID
Elapsed: 484
Average: 0.0484

 

Architect, Registered NC, VA, SC, & GA.
Message 10 of 18
Lee_Mac
in reply to: dbroad

You're welcome Doug Smiley Happy

 


I did some testing on my 64bit system and found that there was no significant difference in the timings between your optimized functions and the simplified forms in AutoCAD 2014.


 

Out of interest, could you possibly post the code for the 'simplified' function used in the comparison?

 

For example, without the optimisation, the functions would become:

 

(defun objectid ( obj )
    (if
        (and
            (vl-string-search "64" (getenv "PROCESSOR_ARCHITECTURE"))
            (vlax-method-applicable-p (vla-get-utility (acdoc)) 'getobjectidstring)
        )
        (vla-getobjectidstring (vla-get-utility (acdoc)) obj :vlax-false)
        (itoa (vla-get-objectid obj))
    )
)

(defun acdoc ( )
    (vla-get-activedocument (vlax-get-acad-object))
)

 

When performance testing the above code against my optimised functions posted earlier, I receive a 77% increase in performance (using benchmark.lsp by Michael Puckett):

 

_$ obj
#<VLA-OBJECT IAcadLine 19fac0fc>
_$ (LM:objectid obj)
"2129673096"
_$ (objectid obj)
"2129673096"
_$ (benchmark '((LM:objectid obj) (objectid obj)))
Benchmarking .................Elapsed milliseconds / relative speed for 16384 iteration(s):

    (LM:OBJECTID OBJ).....1171 / 1.77 <fastest>
    (OBJECTID OBJ)........2074 / 1.00 <slowest> 

 

Therefore, when obtaining the Object ID for every object in a selection set (potentially containing hundreds or thousands of objects), the 77% improvement for each function call soon adds up.

 

Lee

Message 11 of 18
pjkPA
in reply to: dbroad

You two have this really worked out...thanks...

 

  Here is what I have done as a novice programmer... I have 14 tables being summed and it seems instant to me...

 I have to regen to force it to operate which isn't a problem ... but if there is a way to eliminate the regen it would be nice to know... Thanks again!

Message 12 of 18
Lee_Mac
in reply to: pjkPA

Did you not try the program I posted in messsage #4?

Message 13 of 18
pjkPA
in reply to: Lee_Mac

Thanks Lee .. I did try your lsp and it worked perfect .. should have tried before I did it long hand...

you're years ahead of me!

I only get to do this every year or so for a day or two... in between jobs.

 

 

Thanks!

Message 14 of 18
Lee_Mac
in reply to: pjkPA


@pjkPA wrote:

Thanks Lee .. I did try your lsp and it worked perfect .. should have tried before I did it long hand...

you're years ahead of me!

I only get to do this every year or so for a day or two... in between jobs.

 

 

Thanks!


Thank you pjkPA Smiley Happy

 

You probably learnt a great deal about the structure of formula field expressions by performing the task manually, and now you also have the opportunity to compare the manual method to the automated solution demonstrated by the program.

 

Lee

Message 15 of 18
dbroad
in reply to: Lee_Mac

Lee,

Thanks for the link to Michael's benchmark program.  What I was comparing your LM:objectid function to was:

 

(defun oidstring (o)(itoa(vla-get-objectid o))) ;which works in 32 and 64 bit.

 

I was comparing that to the LM:objectid function in your first post.  I hope the two functions are comparable since they take the same arguments and seem to provide the same return values. I tested it on a single line object.

 

On my Dell T3400 Windows 7 3GB ram 2014 AutoCAD setup, the performance is as follows. I admit this is a relatively modest computer.

 

$ (benchmark '((LM:objectid o) (oidstring o)))
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

(OIDSTRING O).......1731 / 1.10 <fastest>
(LM:OBJECTID O).....1904 / 1.00 <slowest>
_$ (benchmark '((oidstring o)(LM:objectid o)))
Benchmarking ..................Elapsed milliseconds / relative speed for 32768 iteration(s):

(OIDSTRING O).......1732 / 1.07 <fastest>
(LM:OBJECTID O).....1856 / 1.00 <slowest>

 

Thanks for the interesting conversation. BTW I was really impressed by your website.

 

Architect, Registered NC, VA, SC, & GA.
Message 16 of 18
Lee_Mac
in reply to: dbroad


@dbroad3 wrote:

 

Thanks for the link to Michael's benchmark program.


 

You're most welcome Doug -

That is the benchmark utility that I (and many others who frequent the Swamp) use for AutoLISP performance testing.

 


@dbroad3 wrote:

 

What I was comparing your LM:objectid function to was:

 

(defun oidstring (o)(itoa(vla-get-objectid o))) ;which works in 32 and 64 bit.


 

As far as I am aware, the ActiveX objectid property only works in 32-bit environments (or at least, only returns meaningful results in 32-bit environments); the objectid32 property will return the corresponding 64-bit Object ID, however, since the AutoLISP itoa function only supports 32-bit signed integers, this 64-bit Object ID cannot be converted to a string for use with Field expressions. Hence the reason that the getobjectidstring method of the Utility object must be used instead.

 


@dbroad3 wrote:

 

Thanks for the interesting conversation. BTW I was really impressed by your website.


 

Thank you, I've enjoyed discussing this with you too.

 

Thank you also for your flattering compliments for my website, that's high praise indeed coming from such a respected member of the Autodesk community as yourself.

 

Message 17 of 18
dbroad
in reply to: Lee_Mac

Very interesting. I aslo see other threads in other newsgroups that assert the same thing about 32bit and 64bit integers. I am sure what am about to say is of almost no importance but the following statements seem to work for me in a 64 bit environment even up to 400,000 entities (haven't tested higher) file size: 8MB

 

"

_$ (setq o (vlax-ename->vla-object(car(entsel))))
#<VLA-OBJECT IAcadLine 000000003048ad98>
_$ (setq oid (vla-get-objectid o))
46 ;;apparent overflow of integer
_$ (itoa oid)
"8796057198128" ;;apparently the actual value is retained.
_$ (atof (itoa oid))
8.79606e+012 ;;apparently it is a valid float

$ (atoi(itoa oid))
2147483647;;apparently not reversable back to an integer

_$ (setq o2 (vla-objectidtoobject (vla-get-activedocument (vlax-get-acad-object)) oid))
#<VLA-OBJECT IAcadLine 000000003048ad98> ;;apparently the process works backward.

I cannot say whether this will work on larger drawings or whether this behavior is the same in earlier version of autocad. But I can say that I have never had an issue creating fields from 

(itoa oid) fragments.

 

Signing off for the evening.

Architect, Registered NC, VA, SC, & GA.
Message 18 of 18
Lee_Mac
in reply to: dbroad


@dbroad3 wrote:

 

Very interesting. I also see other threads in other newsgroups that assert the same thing about 32bit and 64bit integers. I am sure what am about to say is of almost no importance but the following statements seem to work for me in a 64 bit environment even up to 400,000 entities (haven't tested higher) file size: 8MB

 

_$ (setq o (vlax-ename->vla-object(car(entsel))))
#<VLA-OBJECT IAcadLine 000000003048ad98>
_$ (setq oid (vla-get-objectid o))
46 ;;apparent overflow of integer
_$ (itoa oid)
"8796057198128" ;;apparently the actual value is retained.
_$ (atof (itoa oid))
8.79606e+012 ;;apparently it is a valid float
$ (atoi(itoa oid))
2147483647;;apparently not reversable back to an integer
_$ (setq o2 (vla-objectidtoobject (vla-get-activedocument (vlax-get-acad-object)) oid))
#<VLA-OBJECT IAcadLine 000000003048ad98> ;;apparently the process works backward.

 

I cannot say whether this will work on larger drawings or whether this behavior is the same in earlier version of autocad. But I can say that I have never had an issue creating fields from (itoa oid) fragments.

 

Signing off for the evening.


 

That is interesting Doug, thank you for sharing your findings.

 

I personally work in a 32-bit environment and hence cannot verify your findings, however, my methods in the area of field expressions have been dictated and refined entirely by an overwhelming amount of feedback indicating that the use of the objectid property in conjunction with itoa to construct field expressions does not operate correctly in a 64-bit environment.

 

Perhaps it is a unique characteristic of your operating system setup, hardware configuration, or AutoCAD environment which appears to overcome the overflow issues when manipulating a 64-bit integer using 32-bit memory allocations, but in my experience in distributing programs which create field expressions compatible in both 32-bit & 64-bit environments, your results are certainly surprising as previous use of this method has been met by substantial feedback reporting problems in 64-bit environments.

 

Personally, I would rather err on the side of caution and will continue to use the stable getobjectidstring method for field expressions where 64-bit environments are concerned, but I would be interested to know whether you have been successful in using the objectid / itoa combination to construct field expressions in 64-bit systems other than your own.

 

That's all for now!

 

Lee

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost