Jump to content

Recommended Posts

Posted

Hello Everyone,

 

I have prepared a table from a list. After editing it by inserting additional information I want to return it to a list. How can I do it?.

 

Thanking in advance,

 

Aloy

  • Replies 25
  • Created
  • Last Reply

Top Posters In This Topic

  • aloy

    11

  • Lee Mac

    9

  • Grrr

    4

  • BIGAL

    2

Top Posters In This Topic

Posted

Just look at this example you can get columns and rows so just do a double repeat as you build the list.

 

; pick your table
(setq obj (vlax-ename->vla-object (car (entsel "\nPick object"))))
(setq col (vla-get-columns obj))
(setq row (vla-get-rows obj))
;(setq celltxt (vla-gettext obj row column))
(setq celltxt (vla-gettext obj 0 0))

Posted

This is what I have been looking for.

Thanks very much BIGAL.

 

Aloy

Posted (edited)

Full code tested on a Table of 24 rows and 18 columns is as follows:

;;By BIGAL & Aloy
(defun C:TableToList( / row cell rws clns lstx)
 (setq obj (vlax-ename->vla-object (car (entsel "\nPick object"))))  
 (setq lst nil lstx nil row 2 cell 0)
 (setq rws(vla-get-rows obj))
 (setq clns(vla-get-columns obj))  
      (while (and (<= row (- rws 1)) (< cell clns))	  
  (setq celltxt(vla-gettext obj row cell))	 
  (setq lstx(cons celltxt lstx))
 (setq cell(+ cell 1))
 (if (>= cell clns) (progn (setq lst (cons (reverse lstx) lst))
		           (setq row (+ row 1)
		                 cell 0
		                 lstx nil)
		    )
 )
      )
    (setq lst(reverse lst))
(princ)
)

 

Aloy

Edited by aloy
Posted

Here's another way to write it:

(defun c:tab2lst ( / sel )
   (if (setq sel (ssget "_+.:E:S" '((0 . "ACAD_TABLE"))))
       (tab2lst (vlax-ename->vla-object (ssname sel 0)))
   )
)
(defun tab2lst ( obj / col lst row tmp )
   (repeat (setq row (vla-get-rows obj))
       (repeat (setq row (1- row) col (vla-get-columns obj))
           (setq tmp (cons (vla-gettext obj row (setq col (1- col))) tmp))
       )
       (setq lst (cons tmp lst) tmp nil)
   )
   lst
)

Posted

This was version of mine:

; (GetTableContent (vlax-ename->vla-object (car (entsel "\nPick a table: "))))
(defun GetTableContent ( o / IntegerToLst Lst1 Lst2 )
 
 (defun IntegerToLst ( n / L ) ; returns zero-based lst ; (IntegerToLst 5) -> (0 1 2 3 4)
   (if (and (eq 'INT (type n)) (< 0 n) ) (repeat n (setq L (cons (setq n (1- n)) L)) ) )
 )
 
 (if (and (eq 'VLA-OBJECT (type o)) (eq "AcDbTable" (vla-get-ObjectName o)))
   (foreach r (IntegerToLst (vla-get-Rows o))
     (foreach c (IntegerToLst (vla-get-Columns o)) (setq Lst1 (cons (vla-GetText o r c) Lst1)) )
     (if Lst1 (setq Lst2 (cons (reverse Lst1) Lst2))) (setq Lst1 nil)
   )
 )
 (reverse Lst2)
); defun GetTableContent

 

But Lee's suggestion is most effective. (remember mapcartablecells? :D )

Posted

Yes, this works well giving me a list including the title and headings of the table. It took some time to get a clue of the method of selection of table object.

Thanks Lee.

Posted
Yes, this works well giving me a list including the title and headings of the table. It took some time to get a clue of the method of selection of table object.

Thanks Lee.

 

You're most welcome - you may find this reference helpful to understanding the selection mode string.

Posted

Grrr,

I cannot figure out what the parameter to be used for the function call.

The other thing is the outcome from all these method is lists of texts which we cannot use for any processing. Before these data were put into table they were integers, point coordinate values, strings and so on. But after extraction they are all text strings. Therefore I tend to believe that it is much better to export them to excel, then format besides putting in additional info and then import to a'cad with all data types intact.

What do you think the best way?.

Regards,

Aloy

Posted
Grrr,

I cannot figure out what the parameter to be used for the function call.

 

Like this (the example is commented above the function) :

Command: (GetTableContent (vlax-ename->vla-object (car (entsel "\nPick a table: "))))
Pick a table: (("A1" "" "") ("B1" "B2" "B3") ("C1" "C2" "C3") ("D1" "D2" "D3"))

 

 

The other thing is the outcome from all these method is lists of texts which we cannot use for any processing. Before these data were put into table they were integers, point coordinate values, strings and so on. But after extraction they are all text strings. Therefore I tend to believe that it is much better to export them to excel, then format besides putting in additional info and then import to a'cad with all data types intact.

What do you think the best way?.

 

To apply some value (other than block definition) into a cell it must be in string format, check vla-SetText method. - Atleast I think so.

Thats why when "reading" the table, outputs are lists that contain text strings.

I'd rely on string-checking functions to determine whats the string content, like:

; _$ (f "1. 2. 0.") -> 3DPOINT
; _$ (f "0. -3.") -> 2DPOINT
; _$ (f "ABC DEF GHI") -> LIST
; _$ (f "123") -> INT
; _$ (f "123.") -> REAL
; _$ (f "ABC") -> STR
(defun f ( x )
 (
   (lambda (x / tmp len)
     (cond 
       ( (and (setq tmp (read (strcat "(" x ")"))) (< 1 (setq len (length tmp))))
         (if (vl-every 'numberp tmp)
           (cond ( (= 2 len) '2dpoint ) ( (= 3 len) '3dpoint ))
           'list
         )
       )
       ( (numberp (read x)) (if (eq 'INT (type (read x))) 'int 'real) )
       (T 'str)
     )
   )
   x
 )
); defun       

Posted
The other thing is the outcome from all these method is lists of texts which we cannot use for any processing. Before these data were put into table they were integers, point coordinate values, strings and so on. But after extraction they are all text strings.

 

To apply some value (other than block definition) into a cell it must be in string format, check vla-SetText method. - Atleast I think so.

 

Not quite true - to retrieve the value of a table cell whilst honouring the cell data format, use the getcellvalue method, which will return a variant of type dependent on the cell data format.

Posted
Not quite true - to retrieve the value of a table cell whilst honouring the cell data format, use the getcellvalue method, which will return a variant of type dependent on the cell data format.

 

Ah I see, so my string-checking function could become variant checking, by using a little modification:

(setq L (tab2lst o)) ; where vla-getcellvalue is used instead of vla-gettext
(mapcar 'vlax-variant-type L)
(mapcar 'vlax-variant-value L)

 

Thanks again, Lee! :thumbsup:

Posted

You're welcome.

 

Since the returned variant can be of Safearray type (e.g. 8192+5=8197 for the 'Point' cell data format), you may want to use a function similar to the following:

(defun variant->value ( var )
   (cond
       (   (= 'variant (type var))
           (variant->value (vlax-variant-value var))
       )
       (   (= 'safearray (type var))
           (mapcar 'variant->value (vlax-safearray->list var))
       )
       (   var   )
   )
)

I believe this form of function was originally demonstrated by Vladimir Nesterovsky several years back - another version here.

Posted
"Originally posted by Aloy"

Before these data were put into table they were integers, point coordinate values, strings and so on.

I need to modify my above statement a bit as follows:

"Before these data were put into original table from a list they were integers, point coordinate values, strings and so on.

And that was prepared with following code:

 

(vla-settext myTable row cell (car lst1))

 

Is there a way to retain the data type in the original table ?.

Posted
that was prepared with following code:

 

(vla-settext myTable row cell (car lst1))

 

Is there a way to retain the data type in the original table ?.

 

Use vla-setcellvalue in place of vla-settext, and supply the data as a variant of the desired data type.

Posted (edited)

Many thanks Lee, it is so simple as I do not deal with Safearrays. I have made changes to my codes in creation of table and it comes right.

However, retrieval after editing appears to be still a problem. I tried the method 'GetcelValue' and I ended up with a list where each value is preceded with a '' statement. I am still trying to get it right.

Edited by aloy
Posted

You're welcome aloy.

 

I tried the method 'GetcelValue' and I ended up with a list where each value is preceded with a '' statement.

 

Refer to this post. ;)

Posted (edited)

Lee, here is how I tried. Still no luck as I get entire list as text. My original list that made the table and the list I got at the end are also given:

(defun C:TabToLst( / row cell rws clns lstx)
 (setq obj (vlax-ename->vla-object (car (entsel "\nPick object"))))  
 (setq lst nil lstx nil row 2 cell 0)
 (setq rws(vla-get-rows obj))
 (setq clns(vla-get-columns obj))  
      (while (and (<= row (- rws 1)) (< cell clns))	  
  (setq cellcont(vla-getcellvalue obj row cell))
  (setq cellcont(variant->value cellcont))
  (setq lstx(cons cellcont lstx))
 (setq cell(+ cell 1))
 (if (>= cell clns) (progn (setq lst (cons (reverse lstx) lst))
		           (setq row (+ row 1)
		                 cell 0
		                 lstx nil)
		    )
 )
      )
    (setq lst(reverse lst))
(princ)
)
(defun variant->value ( var )
 (cond
     ( (= 'variant (type var))
       (variant->value (vlax-variant-value var))
     )

     ( (= 'safearray (type var))
       (mapcar 'variant->value (vlax-safearray->list var))
     )
     ( var )
  )
)
Command: !l
((4 "MH- 4" 1097.01 88.8977 0.0 6.49583 29.8119 0.0 0.0 "p200" 0.0 0.0 "p250" 0.0 0.0 0.0 0.0 0.0) 
(3 "MH- 3" 1091.32 92.0437 0.0 13.693 23.316 0.0 0.0 "p200" 0.0 0.0 "p250" 0.0 0.0 0.0 0.0 0.0) 
(2 "MH- 2" 1079.4 98.7786 0.0 9.62301 9.62301 0.0 0.0 "p200" 0.0 0.0 "p250" 0.0 0.0 0.0 0.0 0.0) 
(1 "MH-1" 1083.56 107.455 0.0 0.0 0.0 0.0 0.0 "p200" 0.0 0.0 "p250" 0.0 0.0 0.0 0.0 0.0))
Command: !lst
(("1" "MH-1" "1083.56462823596" "107.455006691549" "0" "0" "0" "0" "0" "p200" "0" "0" "p250" "0" "0" "0" "0" "0") 
("2" "MH- 2" "1079.4026719087" "98.7785814962926" "0" "9.62300548887428" "9.62300548887428" "0" "0" "p200" "0" "0" "p250" "0" "0" "0" "0" "0") 
("3" "MH- 3" "1091.32495061517" "92.043721670568" "0" "13.6930298483224" "23.3160353371967" "0" "0" "p200" "0" "0" "p250" "0" "0" "0" "0" "0") 
("4" "MH- 4" "1097.00813495964" "88.8977432136699" "0" "6.49582671755135" "29.8118620547481" "0" "0" "p200" "0" "0" "p250" "0" "0" "0" "0" "0"))

                                    

Edited by aloy
Posted

I have used vla-setcellvalue in creating the table from the list given above. However, it appears the autocad doesn't understand the context and applied variant type 8 (ie. vlax-vbString) to all. Perhaps I need to force the data type at the time of creation of the table and I have to find a way.

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...