Jump to content

Entmake Table with AutoLISP


ksperopoulos

Recommended Posts

I have searched on here and The Swamp for any information on the minimum amount of information needed to create a table using an existing table style that is already in the drawing file. It seems like most everyone is using Visual LISP instead of AutoLISP to do this. Is there a reason? It seems cumbersome finding any information in the help file about VisualLISP functions and I am better at AutoLISP anyway (but not that great). Has anyone used dxf codes to create a table and what are the minimum ones needed to do this?

Link to comment
Share on other sites

Kyle,

 

Myself, I find that VisualLISP is much better suited to creating or modifying table entities, whereas for simple extracting data I do like the association list.

 

What I would suggest is download and have a close look at Lee's Polyline Information Routine. http://www.lee-mac.com/polyinfo.html

 

In it he has an add table sub-function (LM:AddTable). What is REALLY good about that function is it shows how to make sure all of the column widths are neatly sized for the data.

 

All you need to supply to the function as variables is the layout you want to put it in, the insert point, an optional title, the list of data, and a Boolean flag to determine if all columns are made equal width or sized to match the maximum width for the column. It will get you achieving what you want quickly, but it's also a really good (and easy) introduction to visual lisp for you as well. And again, we all thank Lee for generously sharing. :)

Link to comment
Share on other sites

Nevertheless, you got me curious. You can actually create the table without the cell data with the entmake through to group code 92 - but then you are faced with the problem of filling the table with data programmatically.

With the experimenting I did, this seemed to be the minimum data required per cell (a text only cell) to work successfully...

 

(defun table ( inspt lst )
 (entmakex
   (append
     (list
       '(0 . "ACAD_TABLE")
       '(100 . "AcDbEntity")
       '(100 . "AcDbBlockReference")
       (cons 10 inspt)
       '(100 . "AcDbTable")
       (cons 91 (length lst))
       (cons 92 (apply 'max (mapcar '(lambda ( x ) (length x)) lst)))
       )
     (apply
       'append
       (mapcar
         (function
           (lambda ( a )
             (apply
               'append
               (mapcar
                 (function
                   (lambda ( b )
                     (list
                       '(171 . 1)
                       '(173 . 0)
                       '(175 . 0)
                       '(176 . 0)
                       '(145 . 0.0)
                       '(301 . "CELL_VALUE")
                       '(90 . 4)
                       (cons 1 b)
                       (cons 302 b)
                       '(304 . "ACVALUE_END")
                       )
                     )
                   )
                 a
                 )
               )
             )
           )
         lst
         )
       )
     )
   )
 )

 

By the way, this assumes (as I recall that Lee's does also) that the list of data provided is a list of lists in which each list represents a ROW of data.

Link to comment
Share on other sites

Making a table using VL requires about 3 variables and 1 line of VL code if you just accept default table settings compared to entmakex above, not at work now for code, putting values in cells is a row,column answer very easy,

 

The example is for a dwgindex table. http://www.cadtutor.net/forum/showthread.php?83991-Populate-Table&highlight=index

Link to comment
Share on other sites

You convinced me with the minimalist approach to use VL. But, I can't find any help files on vla-addtable in the help files. I would like to try to attack this myself, but without the proper documentation I doubt I will get very far understanding what I can and can't do. Where can I get this information for vla-addtable?

Link to comment
Share on other sites

A full code example includes filling in cells you can basicly change nearly anything in a table its colour, borders, different txt size in cells.

 

; example of creating a table
(defun c:sct (/ colwidth numcolumns numrows objtable rowheight sp vgad vgao )
(vl-load-com)
(setq sp (vlax-3d-point '(0 0 0)))
;(setq vgao (vlax-get-acad-object))
;(setq vgad (vla-get-activedocument vgao))
;(setq vgms (vla-get-paperspace vgad))
(setq doc  (vla-get-activedocument (vlax-get-acad-object) ))
(setq vgms (vla-get-paperspace doc))
(setq numrows 5)
(setq numcolumns 5)
(setq rowheight 0.5)
(setq colwidth 30)
(setq objtable (vla-addtable vgms sp numrows numcolumns rowheight colwidth))
; RetVal = object.AddTable(InsertionPoint, NumRows, NumColumns, RowHeight, ColWidth)
(vla-settext objtable 0 0 "TABLE title")
(vla-settext objtable 1 0 "A") 
(vla-settext objtable 1 1 "B") 
(vla-settext objtable 1 2 "C")
(vla-settext objtable 1 3 "D")
(vla-settext objtable 1 4 "E")
(vla-settext objtable 2 0 "1")
(vla-settext objtable 3 0 "2")
(vla-settext objtable 4 0 "3")
(vla-setcolumnwidth objtable 0 15) ; 0 is first column
(vla-setcolumnwidth objtable 1 30)
(vla-setcolumnwidth objtable 2 60)
(command "_zoom" "e")
(princ)
)
(C:sct)

 

; example of creating a table style
(vl-load-com)
(defun c:CreateTableStyle()
   ;; Get the AutoCAD application and current document
   (setq acad (vlax-get-acad-object))
   (setq doc (vla-get-ActiveDocument acad))
   ;; Get the Dictionaries collection and the TableStyle dictionary
   (setq dicts (vla-get-Dictionaries doc))
   (setq dictObj (vla-Item dicts "acad_tablestyle"))
   
   ;; Create a custom table style
   (setq key "MyTableStyle"
         class "AcDbTableStyle")
   (setq custObj (vla-AddObject dictObj key class))
   ;; Set the name and description for the style
   (vla-put-Name custObj "MyTableStyle")
   (vla-put-Description custObj "This is my custom table style")
   ;; Sets the bit flag value for the style
   (vla-put-BitFlags custObj 1)
   ;; Sets the direction of the table, top to bottom or bottom to top
   (vla-put-FlowDirection custObj acTableTopToBottom)
   ;; Sets the supression of the table header
   (vla-put-HeaderSuppressed custObj :vlax-false)
   ;; Sets the horizontal margin for the table cells
   (vla-put-HorzCellMargin custObj 0.22)
   ;; Sets the supression of the table title
   (vla-put-TitleSuppressed custObj :vlax-false)
   ;; Sets the vertical margin for the table cells
   (vla-put-VertCellMargin custObj 0.22)
   ;; Set the alignment for the Data, Header, and Title rows
   (vla-SetAlignment custObj (+ acDataRow acTitleRow) acMiddleLeft)
   (vla-SetAlignment custObj acHeaderRow acMiddleCenter)
   ;; Set the background color for the Header and Title rows
   (setq colObj (vlax-create-object "AutoCAD.AcCmColor.19"))
   (vla-SetRGB colObj 98 136 213)
   (vla-SetBackgroundColor custObj (+ acHeaderRow acTitleRow) colObj)
   ;; Clear the background color for the Data rows
   (vla-SetBackgroundColorNone custObj acDataRow :vlax-true)
   ;; Set the bottom grid color for the Title row
   (vla-SetRGB colObj 0 0 255)
   (vla-SetGridColor custObj acHorzBottom acTitleRow colObj)
   ;; Set the bottom grid lineweight for the Title row
   (vla-SetGridLineWeight tableStyle acHorzBottom acTitleRow acLnWt025)
   ;; Set the inside grid lines visible for the data and header rows
   (vla-SetGridVisibility custObj acHorzInside  (+ acDataRow acHeaderRow) :vlax-true)
   ;; Set the text height for the Title, Header and Data rows
   (vla-SetTextHeight custObj acTitleRow 1.5)
   (vla-SetTextHeight custObj (+ acDataRow acHeaderRow) 1.0)
   ;; Set the text height and style for the Title row
   (vla-SetTextStyle custObj (+ acDataRow acHeaderRow acTitleRow) "Standard")
   ;; Release the color object
   (vlax-release-object colObj)
 (princ)
)

Link to comment
Share on other sites

Lee - Thank you for the links. I read your tutorial on how to use the reference, and then I tried to use the reference..........maybe I should stick with vanilla LISP. That tutorial is not as helpful as I was hoping (at least in my eyes). Probably because I just dont understand it. I appreciate the links and maybe I can use them some time in the future when I am a little more experienced.

 

BIGAL - I appreciate your example you posted. Although I do not understand the VL, I can somewhat follow the guidlines you have laid out.

 

With the guidelines BIGAL gave, I am able to build the table, place in the correct location, and fill in the title and headers. I am able to get the values I am looking for from a selection set, and now I am trying to put these values into the first column of the table - one value per cell. The only value I am able to get into the table is the last string in the list. I am thinking I need to use the FOREACH function or something along those lines. What are your thoughts?

 

(defun c:WMT ( / *error* ss1 int dec ename att ots doc ps pt numr numc rowht colwd tbl cell)
 (defun *error* (msg)
   (if (not (member msg '("Function cancelled" "quit / exit abort")))
       (princ (strcat "\nError: " msg))
   )
   (princ)
 )
 (defun massoc ( key lst / item )
   (if (setq item (assoc key lst))
       (cons (cdr item) (massoc key (cdr (member item lst))))
   )
 )
 (if (setq ss1 (ssget "x" '((0 . "MULTILEADER"))))
   (progn
     (setq int (sslength ss1)
           dec (1- int)
     )
     (while (<= 0 dec)
       (setq ename (ssname ss1 dec)
               att (nth 1 (massoc 302 (entget ename)))
               dec (1- dec)
       )
       (print att)
     )
   )
 )
 (vl-load-com)
 (setq ots (getvar "ctablestyle"))
 (setvar "ctablestyle" "MMC-Weld Map Table")
 (setq doc (vla-get-activedocument (vlax-get-acad-object))
        ps (vla-get-paperspace doc)
        pt (vlax-3d-point '(15.0 10.5 0.0))
      numr (+ 2 int)
      numc 2
     rowht 0.25
     colwd 0.75
       tbl (vla-addtable ps pt numr numc rowht colwd)
      cell 2
 )
 (repeat int
   (vla-settext tbl 0 0 "WELD MAP TABLE")
   (vla-settext tbl 1 0 "WELD ID")
   (vla-settext tbl 1 1 "WELDER")
   (vla-settext tbl cell 0 att)
   (setq cell (+ cell 1))
 )
 (setvar "ctablestyle" ots)
 (princ)
)

WELD MAP TABLE.dwg

Link to comment
Share on other sites

Here is an example of the code you need I didn't look at your drawing I have two lists say = column a, column b the, Y variable is the first column known as 0 hence the Y 0, Y 1 increment Y, Y 0 Y 1 and so on.

2 0, 2 1, 3 0, 3 1,

 

(SETQ X 0)
(SETQ Y 2)
(REPEAT (sslength ss1)
 (vla-settext objtable Y 0 (NTH X LIST1)) ; 
 (vla-settext objtable Y 1 (NTH X LIST2))
  (SETQ X (+ X 1))
 (SETQ Y (+ Y 1))
)

Link to comment
Share on other sites

Your Y is my CELL. I start CELL in column A (0) and in row 3 (2). I only need to fill out the 1st column. The second column will be empty. I am trying to get my list of values att to fill all the way down column one, but the only thing I get is Z all the way down.

Link to comment
Share on other sites

Looking at code above and you have one list, the example code has two heading line so we need to start at 3rd line down, so Y=0 would be 1st heading cell, y=1 would be 2nd heading cell y=2 is the next available cell.

 

(SETQ X 0)
(SETQ Y 2)
(REPEAT (length list1)  
; fills in a single cell starting with 1st row and column 
; note 1st column is known as 0
; puts in cell value in list1
; y 0 1st column 3rd row
(vla-settext objtable Y 0 (NTH X LIST1))  
(SETQ X (+ X 1)) ; add 1 to x so we can ge next value in list1 to put in cell
(SETQ Y (+ Y 1)) ; add 1 to 1 go down 1 row in table
)

Edited by BIGAL
Link to comment
Share on other sites

That is what I have. I am starting in the 3rd row of the 1st column. I think my issue is the values are not returning as a list. So it is placing the last string returned in "att" in each cell.

 

Edit: Come to find out, this was the case. My list wasn't really a list of multiple values. It was only a single character - "Z". Once I got some help from CWAKE in another thread, he showed me my mistakes and gave me the solution. If you want the results, here is the thread.

Edited by ksperopoulos
Link to comment
Share on other sites

  • 1 year later...

I used the LM:addtable, despite not understanding visual lisp at all. Bravo for the code being that simple! I My most urgent matter is: How do I control which paperspace tab the table is created on?

After that, and probably too complicated for me: 1) It creates the table with 1 row of Title and 1 of Header. How do I make the 2nd and 3rd row Headers (1st row being the title)? This one might be obvious, but I'm not seeing it. I can do it with AutoCAD, just not lisp. 2) There's a few Headers here and there I'd like to merge. Can I merge them with lisp?

Great work here, thanks in advance for the help.

Link to comment
Share on other sites

I thought I had, so I just looked harder. I'm assuming the answer is 'no' then, because I see you using (setvar 'ctab curlayout) with regens and such to change the actual tab of the drawing. I have a program that outputs information from the drawing to multiple tabs at once (in mtext) seamlessly without regen. It would be better if the information was displayed in a table, we've always known that. Now I can generate beautiful tables in a flash, but they are on my current tab, or seems to be on the last tab if I'm currently in model space. I just tried to brute force subst, entmod, entupd dxf 410 to get the tables to move, but it didn't work. If setvar 'ctab is the best solution, I guess that's the route I'll take. Thanks much.

 

Edit: I don't see that working. Like I said, I don't understand visual lisp. The answer could be right in front of me, but I don't see it.

 

Edit 2: I found it in another thread about mtext, from Lee Mac:

 

(vla-get-block
	  (vla-item
	    (vla-get-layouts
	      (vla-get-activedocument
		(vlax-get-acad-object)
		)
	      )
	    (cdr (assoc 410 tabl))
	    )
	  )

 

Where tabl is the name of tab I extracted from the program location. I use this as the spc variable call in the vla-add-table. It seems to cause a fast regen, but the job is done. Sorry for asking when the solution is out there, but that's true of about everything.

 

Now long term, if I could understand lisp to merge cells, etc.

Edited by Quest for Peace
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...