Lisp needed for text extraction

Lisp needed for text extraction

JB-T
Enthusiast Enthusiast
2,876 Views
6 Replies
Message 1 of 7

Lisp needed for text extraction

JB-T
Enthusiast
Enthusiast

Hello all!

 

Complementary to the LISP file request thread that I created this week for the annotation of closed areas, I would like to have a second routine that would allow me to extract the annotations made with this first routine.

 

 

Standard display of the informations when I am ready to extract them from AutoCAD. There may be many more stations (XXX+YYY,ZZZ) on the right side of the image below :

 

acad.jpg

 

 

Desired results for the extraction of the above data to a Microsoft Excel file. Notice the extracted data (contents and layers) and their order (extracted from bottom to top, left to right). I tried to find a way to get a similar extraction order with AutoCAD’s Extract command, but it does not seem possible :

 

EXCEL.jpg

 

 

When the routine would be invoked, it would first ask to select the informations to be extracted. After selecting these informations, we would press Enter key and the routine would then ask to enter a name for the Excel file. The default saving directory from the Excel file could be modified within the Lisp script only.

 

 

The routine would ignore everything in the selection that is not text. It would extract all types of texts (mtext, dtext, etc.).

 

 

Do you think that this routine can be written?

 

 

I really hope someone will be able to help me, because this routine could help not only me but many of my colleagues.

 

 

Thanks a lot for looking at my request!

 

 

If you need more details, just ask me.

 

 

JBT

0 Likes
2,877 Views
6 Replies
Replies (6)
Message 2 of 7

CADaSchtroumpf
Advisor
Advisor

Hello,

 

Making it quickly, try this... it's a CSV file with comma delimiter, simple with excel!

 

(defun c:list_for_CSV ( / js file2open f_open n dxf_cod)
  (setq js (ssget '((0 . "*TEXT"))))
  (cond
    (js
      (setq file2open (strcat (getvar "DWGPREFIX") (getvar "DWGNAME") (rtos (getvar "cdate") 2 4) ".CSV"))
      (setq f_open (open file2open "w"))
      (repeat (setq n (sslength js))
        (setq dxf_cod (entget (ssname js (setq n (1- n)))))
        (princ (cdr (assoc 1 dxf_cod)) f_open)
        (princ ";" f_open)
        (princ (cdr (assoc 8 dxf_cod)) f_open)
        (princ ";" f_open)
        (princ "\n" f_open)
      )
      (close f_open)
    )
  )
  (prin1)
)
0 Likes
Message 3 of 7

JB-T
Enthusiast
Enthusiast

Hello,

 

Thank you for your answer!

 

I tried your routine and it extracted the texts and the layers correctly. There was only one problem : the extracting order.

 

Below I inserted a screenshot of the result : the extraction order seems to be set to "the oldest to the newest". I really need to have the same extraction order that you can see on the second image of my initial post, or another type of order where each station (XXX+YYY,ZZZ) is followed by its data(s) (e.g. 2,34)

 

Extract to CSV.jpg

 

Thanks alot for your time!

 

JB-T

0 Likes
Message 4 of 7

CADaSchtroumpf
Advisor
Advisor

Hello,

 

It not there no magical selection; Autocad cannot choose on your place in a definite order!
The only order which he knows is the order of creation of entities.

 

Therefore the only and only means which stays is selection one after another of texts in the order which you wish.
I hope for you that you do not have 100 objects, therefore clicks 100 to accomplish...

 

(defun c:list_for_CSV ( / js js_one file2open f_open n dxf_cod)
  (setq js (ssadd))
  (while (setq js_one (ssget "_+.:E:S" '((0 . "*TEXT"))))
    (setq js (ssadd (ssname js_one 0) js))
  )
  (cond
    (js
      (setq file2open (strcat (getvar "DWGPREFIX") (getvar "DWGNAME") (rtos (getvar "cdate") 2 4) ".CSV"))
      (setq f_open (open file2open "w") n -1)
      (repeat (sslength js)
        (setq dxf_cod (entget (ssname js (setq n (1+ n)))))
        (princ (cdr (assoc 1 dxf_cod)) f_open)
        (princ ";" f_open)
        (princ (cdr (assoc 8 dxf_cod)) f_open)
        (princ ";" f_open)
        (princ "\n" f_open)
      )
      (close f_open)
    )
  )
  (prin1)
)
0 Likes
Message 5 of 7

lando7189
Advocate
Advocate

To get the sort you want, you will need to get a selection set of all the text on the 'station text' layer sorted by x coordinate.  Then from each piece of text, get any other text where the x value of the center of the text lands between the 'x extents' of the text on the 'station text' layer, sorted by the y coordinate.

 

Correct?

0 Likes
Message 6 of 7

JB-T
Enthusiast
Enthusiast

Hi,

 

I found a quick method to extract my informations with your routine, which is faster then using the Extract command.

 

I first extract the stations to identify their drawing order, then I annotate the area for each station in the same order. When I extract the areas and the stations to CSV I get, in one column, the stations in order and the areas annotations in the same order, just below the stations. Finally, I just paste the annotations in the second column, next to the stations.

 

Is it possible to add to this routine a way to give a name to the extracted CSV file?

 

Thanks a alot for your time and have a great day!

 

JBT

0 Likes
Message 7 of 7

CADaSchtroumpf
Advisor
Advisor

A new version which tries to sort out data (by station).
The distance one asks for which for the selection is half a distance of the digonale of the boundingbox crossing.
In your example it portray will you work because data do not overlap from a station to the other one?
The name of the file is free.
I hope that it will be able to admit and that translation is clear because I play English not much, I could hardly make better...

 

(defun c:list_for_CSV ( / js_station file_name key f_open n dxf_cod lst_dxf for_nth d_search js_other)
  (setq js_station (ssget "_X" '((0 . "*TEXT") (8 . "Station text"))) d_search nil)
  (cond
    (js_station
      (setq file_name (getfiled "Name of file to create ?: " (strcat (substr (getvar "dwgname") 1 (- (strlen (getvar "dwgname")) 3)) "csv") "csv" 37))
      (if (null file_name) (exit))
      (if (findfile file_name)
        (progn
          (prompt "\nFile already exist!")
          (initget "Add Replace Undo")
          (setq key
            (getkword "\nData to file? [Add/Replace/Undo] <R>: ")
          )
          (cond
            ((eq key "Add")
              (setq key "a")
            )
            ((or (eq key "Replace") (not key ))
              (setq key "w")
            )
            (T (exit))
          )
          (setq f_open (open file_name key))
        )
        (setq f_open (open file_name "w"))
      )
      (repeat (setq n (sslength js_station))
        (setq
          dxf_cod (entget (ssname js_station (setq n (1- n))))
          lst_dxf (cons (list (assoc 10 dxf_cod) (assoc 1 dxf_cod) (assoc 8 dxf_cod)) lst_dxf)
        )
      )
      (setq 
        for_nth (vl-sort-i (mapcar 'car (mapcar 'cdr (mapcar 'car lst_dxf))) '<)
        lst_dxf (mapcar '(lambda (x) (nth x lst_dxf)) for_nth)
      )
      (foreach el lst_dxf
        (if (not d_search)
          (progn
            (initget 1)
            (setq d_search (getdist (cdar el) "\nDistance for search other text?: "))
          )
        )
        (setq js_other
          (ssget "_C"
            (mapcar '- (cdar el) (list d_search d_search 0.0))
            (mapcar '+ (cdar el) (list d_search d_search 0.0))
            '((0 . "*TEXT") (8 . "Red text,Green text,White text"))
          )
        )
        (princ (cdr (assoc 1 el)) f_open)
        (princ ";" f_open)
        (princ (cdr (assoc 8 el)) f_open)
        (princ ";" f_open)
        (princ "\n" f_open)
        (cond
          (js_other
            (repeat (setq n (sslength js_other))
              (setq dxf_cod (entget (ssname js_other (setq n (1- n)))))
              (princ (cdr (assoc 1 dxf_cod)) f_open)
              (princ ";" f_open)
              (princ (cdr (assoc 8 dxf_cod)) f_open)
              (princ ";" f_open)
              (princ "\n" f_open)
            )
          )
        )
      )
      (close f_open)
    )
  )
  (prin1)
)
0 Likes