How to simulate a keyboard tab? ("\t" is not recognized)

How to simulate a keyboard tab? ("\t" is not recognized)

scooberu
Enthusiast Enthusiast
1,402 Views
15 Replies
Message 1 of 16

How to simulate a keyboard tab? ("\t" is not recognized)

scooberu
Enthusiast
Enthusiast

I am trying to make a table, then populate that table using lisp. Manually I can use "tabledit", select the first cell, type, then press the tab key to go to the next cell, and so on. The table will even add lines until I press return.

 

I can create a table with a simple line of lisp:

 first set filedia to zero

(command "_table" 3 1 "S" "Standard" "W" "0.74" "H" 1 "6,-2") ; last argument is coordinates to place table

 

But here the wheels come off, as I am unable to force the table to recognize a tab. The following command is one of many I have tried, and comes closest to working... but it interprets the \t as 2 spaces INSIDE THE FIRST CELL, not as a command to jump to the next cell!

(command "_tabledit" "6.5,-2.1" (princ "TITLE\tHEADING1\tHEADING2"))

 

Is there any way to make CAD recognize a keyboard tab? Or is there a variable format that expresses itself as tab delimited? If not, do I need to select and populate each cell individually? Thanks in advance.

0 Likes
Accepted solutions (1)
1,403 Views
15 Replies
Replies (15)
Message 2 of 16

ec-cad
Collaborator
Collaborator

You might try the (chr 9) to simulate a Tab. I don't know what the default # of spaces it will do, 4 or 8 ?

Try: (princ (strcat TITLE (chr 9) HEADING1 (chr 9) HEADING2))

(princ (chr 9))  returns "\t"

ECCAD

0 Likes
Message 3 of 16

john.uhden
Mentor
Mentor

@scooberu ,

Haven't tried it, but how about?...

(command "_tabledit" "6.5,-2.1" "\t")

AND/OR

Try dropping the "(princ" and matching ")"

OR

Try selecting the next cell numerically.

John F. Uhden

0 Likes
Message 4 of 16

ec-cad
Collaborator
Collaborator
Accepted solution

Found this in this forum: It may be of use to make the Table, and store those values.

 

; Example of how to create an Autocad Table
; By Alan H 

(defun AHMaketable (/ colwidth numcolumns numrows objtable rowheight sp vgad vgao vgms)
(vl-load-com)
(setq sp (vlax-3d-point '(100 0 0))) ;PUTS AT 0,0,0
(Setq vgms (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) ;
(setq numrows 5)
(setq numcolumns 3)
(setq rowheight 2.5)
(setq colwidth 60)
(setq objtable (vla-addtable vgms sp numrows numcolumns rowheight colwidth))
(vla-settext objtable 0 0 "DRAWING REGISTER")
(vla-settext objtable 1 0 "DRAWING NUMBER") 
(vla-settext objtable 1 1 "DRAWING TITLE") 
(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")
(command "_zoom" "e")
(princ)
)
(AHMaketable)

 

Thank you Alan H.

 

0 Likes
Message 5 of 16

Sea-Haven
Mentor
Mentor

Once you have a table, as above in my Maketable, you can set the row number to say 2 then in a while you enter text values and keep going you can make the cells go down or across, you use insertrows to add a row 1st then the settext function with a row and column parameter.

 

The best way is to wrap it in a function like Tab7 meaning 7 columns required and go across in a row before adding a new row, a Enter would be equal to put nothing in next cell. The dwg will provide the table details like column widths and text sizes.

 

So provide some more information re table, a dwg would be best and do you want to go across or down ?

 

 

0 Likes
Message 6 of 16

scooberu
Enthusiast
Enthusiast

@john.uhden wrote:

@scooberu ,

Haven't tried it, but how about?...

(command "_tabledit" "6.5,-2.1" "\t")

AND/OR

Try dropping the "(princ" and matching ")"

OR

Try selecting the next cell numerically.


Thank you for the suggestions. I did try your first suggestion prior to the nested (princ). The Tabledit command did not recognize the "\t" as a tab. When text strings were used, it recognized the first string and nothing after it. However, it did accept a function (princ in this case) as a single argument, even if that argument had several components.

 

When you suggest selecting the next cell numberically, are you referring to coordinates (B1, B2, etc)? Is there a way to reference "next cell" without the number?

0 Likes
Message 7 of 16

scooberu
Enthusiast
Enthusiast

 

 

; Example of how to create an Autocad Table
; By Alan H 

(defun AHMaketable (/ colwidth numcolumns numrows objtable rowheight sp vgad vgao vgms)
(vl-load-com)
(setq sp (vlax-3d-point '(100 0 0))) ;PUTS AT 0,0,0
(Setq vgms (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) ;
(setq numrows 5)
(setq numcolumns 3)
(setq rowheight 2.5)
(setq colwidth 60)
(setq objtable (vla-addtable vgms sp numrows numcolumns rowheight colwidth))
(vla-settext objtable 0 0 "DRAWING REGISTER")
(vla-settext objtable 1 0 "DRAWING NUMBER") 
(vla-settext objtable 1 1 "DRAWING TITLE") 
(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")
(command "_zoom" "e")
(princ)
)
(AHMaketable)

 

 

 

Thank you Alan H.

 


This looks very promising. It appears that "vla-addtable" from line 12 is similar to (command _table), but line 12 also assigns said table a name "objtable". Then the command "vla-settext" calls said table by name and populates a cell? If this works, I believe it would get past my obstacle.

 

I believe Sea-Haven is suggesting I can populate each cell of a row and create a condition to repeat until I run out of data..? This would be considerably more robust than trying to pick the coordinates of each cell.

 

One part that may come back to bite me though: If I build a function to do this on each layout of a drawing, would each table have the same name, and ...  crash the function?  Or is that table name just a lisp variable reference to the autocad id of the table? 

0 Likes
Message 8 of 16

Sea-Haven
Mentor
Mentor

Every table is known as a  "ACAD_TABLE" but every table has a different ID, so if you want 1 in each layout no problems.

Numrows is the row number so increments by 1 each time ran the row height here is the data row height.

(vla-insertrows objtable  numrows  (vla-GetRowHeight objtable (1- numrows)) 1)

You can then populate that row using settext, do a say "continue yes no" so add more rows.

 

What is in your table ? It may be easier to say pick objects eg Block with attributes and populate the table. 

 

Post a sample dwg.

 

0 Likes
Message 9 of 16

scooberu
Enthusiast
Enthusiast

This piece of my process will build a sheet quantity table by selecting all instances of a block (on that sheet), reading attribute fields, sorting, then placing the data in a table. I will post some of my code or dwg or something when I get pieces to work. There are obviously other pieces to this, but I will not post my whole process in one place. 

 

I know AutoCAD has "automated" quantity takeoffs if you want to tiptoe through their process with many manual steps and get tables that were printed in 1988. But I don't like putting everything together with nails just because CAD handed me a hammer.

0 Likes
Message 10 of 16

Sea-Haven
Mentor
Mentor

Making table of Block attributes is off the shelf for many of us, sorted and counted, tested on 100's of blocks. So post a dwg. Need all blocks or some info.

 

0 Likes
Message 11 of 16

ec-cad
Collaborator
Collaborator

You probably have figured it out by now. But here's a function to add some rows to 

the end of the table, once it's built. Tested OK.

 

ECCAD

(defun add_rows ( S1 S2 S3 ); Pick table and Add a row of 3 strings
  (setq tb (vlax-ename->vla-object (car (entsel))))
  (setq rownum (vla-get-rows tb))
  (vla-InsertRows tb  (+ rownum 1)  (vla-GetRowHeight tb (- rownum 1)) 1); adds to bottom
  (setq rownum (vla-get-rows tb))
  (vla-settext tb (- rownum 1) 0 S1)
  (vla-settext tb (- rownum 1) 1 S2)
  (vla-settext tb (- rownum 1) 2 S3)
); defun
;; OR below function - not both..
(defun add_rows ( tblobject S1 S2 S3 ); Send in table object and Add a row of 3 strings
  (setq tb tblobject);  local var
  (setq rownum (vla-get-rows tb))
  (vla-InsertRows tb  (+ rownum 1)  (vla-GetRowHeight tb (- rownum 1)) 1); adds to bottom
  (setq rownum (vla-get-rows tb))
  (vla-settext tb (- rownum 1) 0 S1)
  (vla-settext tb (- rownum 1) 1 S2)
  (vla-settext tb (- rownum 1) 2 S3)
); defun

 

0 Likes
Message 12 of 16

scooberu
Enthusiast
Enthusiast

@Sea-Haven wrote:

Making table of Block attributes is off the shelf for many of us, sorted and counted, tested on 100's of blocks. So post a dwg. Need all blocks or some info.

 


I appreciate the offer, but at this point the 2 lines of code above are what I have. It appears the commands in the previous posts will help though. At this point I can say the code will do something like this:

 

1) Function to accept an n by m matrix (list of lists), count the rows & columns, make a new table, and populate the table with the values in the matrix. I will prolly make the table style a parameter also.

 

2) Function to grab several attributes & properties from all instances of one block on a layout, sort them & organize them into an nxm matrix.

 

3) Function that gets a little user input such as "do it on one sheet or all the sheets?", "include...xxx?", etc. then references the previous functions to do the work.

 

If these items are off the shelf and free to copy I am happy to. I do think this forum has given me a lot of tools to move forward with already. 

0 Likes
Message 13 of 16

john.uhden
Mentor
Mentor

@Sea-Haven wrote, "... to move forward with ..."

Umm, that should be "... with which to move forward..."

But you guys (@sea-haven & countrymen) are upside down, so I guess it's okay.  🤔

John F. Uhden

0 Likes
Message 14 of 16

Sea-Haven
Mentor
Mentor

I have gone more down the path of what a user table should look like and add that Table style. It makes the row height and text properties much easier. Could have some lisp that makes the table to set sizes, just load as required and pass variables.

 

(defun CreateTableStyle( / dicts dictobj key class custobj )
    
;; Get the Dictionaries collection and the TableStyle dictionary
(setq dicts (vla-get-Dictionaries (vla-get-ActiveDocument(vlax-get-acad-object))))
(setq dictObj (vla-Item dicts "acad_tablestyle"))

(setq txtht 300)

(setq yourtablename "No")
(vlax-for dname dictobj
(if (=  (vla-get-name dname) "yourtablename" ) ; does it exist
(setq yourtablename "found")
)
)

(if (= yourtablename "No")
(progn

;; Create a custom table style
(setq key "yourtablename" class "AcDbTableStyle")
(setq custObj (vla-AddObject dictObj key class))

;; Set the name and description for the style
(vla-put-Name custObj "yourtablename")
(vla-put-Description custObj "Yourtablename 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 horizontal margin for the table cells
(vla-put-HorzCellMargin custObj txtht )

;; Sets the vertical margin for the table cells
(vla-put-VertCellMargin custObj txtht )

;; Set the alignment for the Data, Header, and Title rows
(vla-SetAlignment custObj (+ acDataRow acHeaderRow acTitleRow) acMiddleCenter)

;; Set the text height for the Title, Header and Data rows
(vla-SetTextHeight custObj acDataRow txtht)
(vla-SetTextHeight custObj acHeaderRow (* txtht 1.2))
(vla-SetTextHeight custObj acTitleRow (* txtht 1.5))

(setq colObj (vlax-create-object (strcat "AutoCAD.AcCmColor." (substr (getvar "ACADVER") 1 2))))

    (vla-setRGB colObj 255 0 0)
    (vla-setcolor cuStobj acTitleRow colObj)

    (vla-setRGB colObj 255 0 255)
    (vla-setcolor cuStobj acHEADERRow colObj)


;; Set the text height and style for the Title row
(vla-SetTextStyle custObj (+ acDataRow acHeaderRow acTitleRow) "Arial")

; (vla-SetrowHeight custObj 0 20)

; (vla-put-regeneratetablesuppressed custobj :vlax-false)
)
)

(setvar 'ctablestyle "yourtablename")

  (princ)
) ; CreateTableStyle
0 Likes
Message 15 of 16

scooberu
Enthusiast
Enthusiast

@Sea-Haven wrote:

Making table of Block attributes is off the shelf for many of us, sorted and counted, tested on 100's of blocks. So post a dwg. Need all blocks or some info.

 


All right, I'll bite. I have been able to get the lisp commands to create my table, but I have not been able to get the property values out of the dynamic blocks.  The logical starting point is the line of code

  (vlax-invoke blk 'getdynamicblockproperties)

 from Lee Mac's function "Get Dynamic Block Property Values".  I have found that "vlax-invoke" has been replaced by "vlax-invoke-method", but I get "error: bad argument type: VLA-OBJECT (<Entity name...."

 

Please share the code you use to retrieve a custom properties and attributes from a dynamic block. 

 

Regarding posting a drawing: I am asking a general question, not a question specific to one drawing. The result may be used on 100s of drawings. If the answer is different for different drawings, that information would also be helpful.

0 Likes
Message 16 of 16

Sea-Haven
Mentor
Mentor

I use the great Dynamics block by Lee-Mac all the time just use 

 

;; Get Dynamic Block Property Value  -  Lee Mac
;; Returns the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)

(defun LM:getdynpropvalue ( blk prp )

(setq len (LM:getdynpropvalue blk "Distance1")) ; blk is a VL block picked.

 

A side note can get current visibilty state as well. 

0 Likes