Select text and make list as per user provided numbers

Select text and make list as per user provided numbers

nilambaridal28
Contributor Contributor
1,093 Views
9 Replies
Message 1 of 10

Select text and make list as per user provided numbers

nilambaridal28
Contributor
Contributor

Iam looking for a code for my project. In my drawing, I have multiple box available. In each box multiple texts are available. I need to make a list of that texts to paste in excel.
In picture you can see 3 boxes with different texts(number of boxes varies with my projects). Name of the box is not available in drawing.

nilambaridal28_0-1716355596719.png

 

My program will ask user "Provide 1st Box Name" (e.g. if user is putting box name as CAM1 then in excel in first column I need text as ***CAM1***)(in excel box name is displaying with prefix and suffix as ***)
After putting box name, program will ask user "Select text of CAM1", then user will select 1st text and then again program will ask user “Enter number” for 1st text which is required for number of times that text is required in excel. Then select next text and enter number of times need that second text, and so on. Those texts needs in list to paste in excl.

E.g. User is providing box name as CAM1.

Then selecting text ABC and entering 2 number.

Then selecting text ESC and entering number 3.

Then selecting text 435 and entering number 1.

Then selecting text ESC and entering number 4.

Then as a result I need a list text as ABC, ABC, ESC, ESC, ESC, 435, ESC, ESC, ESC, ESC which is below the ***CAM1***.

All the text which are selected in drawing should change their layer to "TXT_MISC" to understand that those are covered.
When I hit spacebar then program should ask "Provide 2nd Box name".

Then if user is putting name as NAT1 then ***NAT1*** will come below the box1 list.

In same way, user will select text AS3 from 2nd box and will enter number as 4.

Then user will select 2nd text ER12 and will enter number 3.

Then box 2 text will come below in same sequence like AS3, AS3, AS3, AS3, ER12, ER12, ER12 below text ***NAT1***. And all selected text layer will change in drawing.
Same way it will ask for box 3, box 4 and so on.
In last, when all boxes will finish, user will hit button L then excel list will be ready to paste in already opened excel sheet. User will go in Excel sheet and paste their list. List will look like as per attached picture.

 

nilambaridal28_1-1716355596722.png

 

 

Currently I am using below program but that gives me each text twice. Now I need text number of times as per user input.

(vl-load-com)

(defun c:TextList ( / tx ss d a htmlfile o c b n)

    (defun *error* ( msg )

        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))

            (princ (strcat "\nError: " msg))

        )

                (setq d nil)

                (clip c)

    (princ)

    )

(setq lay "TXT_MISC")

(if (not (tblsearch "layer" lay))(command "_layer" "n" lay ""))

(setq n 1 c "")

(setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))

(while

                (setq ss (ssget '((0 . "*TEXT"))))

                    (if ss

                                                (repeat (setq i (sslength ss))

                                                                (setq o (vlax-ename->vla-object (ssname ss (setq i (1- i)))))

                                                                (setq a (vlax-get-property o 'TextString))

                                                                (setq d (cons a d))

                                                                (vla-put-layer o lay)

                                                )

                                )

                (setq b (strcat "***" tx "***\n" (substr (apply 'strcat (mapcar '(lambda (x) (strcat "\n" x "\n" x)) d)) 2) "\n"))

                (setq c (strcat c b))

               

                (setq n (1+ n) d nil)

                (setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))

)

(clip c)

(princ)

)

 

(defun clip (txt)

                (terpri)(princ txt)

                (vlax-invoke (vlax-get (vlax-get (setq htmlfile (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'SetData "Text"  txt)

                (vlax-release-object htmlfile)

                (princ)

)

(princ "\nType P2X")

(princ)

 

Please help. Thanks in advance!

0 Likes
Accepted solutions (1)
1,094 Views
9 Replies
Replies (9)
Message 2 of 10

komondormrex
Mentor
Mentor

the code below does not directly copy made mtext to a clipboard but rather interactively builds one in the autocad  window to trace its exact value.

 

(defun c:mtext_make (/ header repeat_ text_ename)
	(if (null header_saved) (setq header_saved "CAM1"))
	(if (null repeat_saved) (setq repeat_saved 1))
 	(while (null (vl-catch-all-error-p (setq header (vl-catch-all-apply 'getstring (list (strcat "\nEnter box name <" header_saved ">: "))))))
		(if (= "" header) 
			(setq header header_saved) 
			(setq header_saved (setq header (strcase header)))
		)
		(if (or (null mtext)
				(vlax-erased-p mtext)
			)
			(setq mtext (vla-addmtext (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
							        	 			 (vlax-3d-point (getpoint "\nPick point for target mtext: "))
							        	 			 0
						        					 ""
						)
			)
		)
		(vla-put-textstring mtext (strcat (if (/= "\\P" (substr (vla-get-textstring mtext) (1- (strlen (vla-get-textstring mtext))))) "\\P" "") (vla-get-textstring mtext) (strcat "***" header "***") "\\P"))
		(while (and (null (vl-catch-all-error-p (setq text_ename (vl-catch-all-apply 'entsel (list (strcat "\nPick text inside the \"" header "\" box: "))))))
					text_ename 
			   )
			(setq text_ename (car text_ename)) 
			(entmod (append (entget text_ename) (list (cons 8 "TEXT_MISC"))))
			(if (null (vl-catch-all-error-p (setq repeat_ (vl-catch-all-apply 'getint (list (strcat "\nEnter \"" (cdr (assoc 1 (entget text_ename))) "\" text repetition <" (itoa repeat_saved) ">: "))))))
				(repeat (if (null repeat_) 
							(setq repeat_ repeat_saved) 
							(setq repeat_saved repeat_)
						)
					(vla-put-textstring mtext (strcat (vla-get-textstring mtext) (cdr (assoc 1 (entget text_ename))) "\\P"))
				)
			)
		)
	)
)

 

0 Likes
Message 3 of 10

ec-cad
Collaborator
Collaborator

You could try this change to your original code.

 

ECCAD

(setq n 1 c "")

(setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))

(while

                (setq ss (ssget '((0 . "*TEXT"))))

                    (if ss

                                                (repeat (setq i (sslength ss))

                                                                (setq o (vlax-ename->vla-object (ssname ss (setq i (1- i)))))

                                                                (setq a (vlax-get-property o 'TextString))
;; *** Modified
                                                                (setq NN (getint (strcat "\nNumber of times to repeat " a " ?")))
                                                                (repeat NN
                                                                 (setq d (cons a d))
                                                                ); repeat
;; *** End of Modification
                                                                (vla-put-layer o lay)

                                                )

                      )

                (setq b (strcat "***" tx "***\n" (substr (apply 'strcat (mapcar '(lambda (x) (strcat "\n" x "\n" x)) d)) 2) "\n"))

                (setq c (strcat c b))

                (setq n (1+ n) d nil)

                (setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))

)
0 Likes
Message 4 of 10

Sea-Haven
Mentor
Mentor

Pick a box, get all text inside pop a dcl that asks for how many then send to Excel my take on the problem.

 

Using the Multi getvals you can build a list on the fly before calling it. Done this many times, each box will produce a dcl with correct number of texts.

SeaHaven_0-1716439435870.png

I don't want to waste my time if this is not the way you want to go. Can do Cam1 Cam2 Cam3 etc auto increase in dcl.

 

0 Likes
Message 5 of 10

nilambaridal28
Contributor
Contributor

Thanks a lot @ec-cad 

Its working. Below is the updated code as per your suggestion. But after providing box name, I could select only one text. After one text selection, it is asking for next box. Whereas I have multiple text in one box. After all text selection with alongwith their quantity, then only next Box will come. I have attached cad file more clarification.

(vl-load-com)
(defun c:TextList ( / tx ss d a htmlfile o c b n)
    (defun *error* ( msg )
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            (princ (strcat "\nError: " msg))
        )
(setq d nil)
(clip c)
    (princ)
    )
(setq lay "TXT_MISC")
(if (not (tblsearch "layer" lay))(command "_layer" "n" lay ""))
(setq n 1 c "")
(setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))
(while 
(setq ss (ssget '((0 . "*TEXT"))))
    (if ss
(repeat (setq i (sslength ss))
(setq o (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
(setq a (vlax-get-property o 'TextString))
(setq NN (getint (strcat "\nNumber of times to repeat " a " ?")))
                                (repeat NN
(setq d (cons a d))
);Repeat
(vla-put-layer o lay)
)
)
(setq b (strcat "***" tx "***\n" (substr (apply 'strcat (mapcar '(lambda (x) (strcat "\n" x "\n" x)) d)) 2) "\n"))
(setq c (strcat c b))
 
(setq n (1+ n) d nil)
(setq tx (getstring (strcat "\nProvide " (rtos n 2) " Box name :" )))
)
(clip c)
(princ)
)
 
(defun clip (txt)
(terpri)(princ txt)
(vlax-invoke (vlax-get (vlax-get (setq htmlfile (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'SetData "Text"  txt)
(vlax-release-object htmlfile)
(princ)
)
(princ "\nType P2X")
(princ)

Please support.

0 Likes
Message 6 of 10

ec-cad
Collaborator
Collaborator
Accepted solution

OK, I modified the Lisp in several ways. It should work as you wanted it to originally.

You can enter as many 'CAMx' as you want, and for each Text selected, enter a number of times

repeated in output. The output looks like this:

CHANGED TO ALLOW APPEND OF NEXT BOX: RESULT:
Enter More Boxes <Y N>:N
***CAM1***
ASC
453
453
GEF
GEF
GEF
CDE
CDE
CDE
CDE
***CAM2***
ASC
454
454
GEF
GEF
GEF
CDE
CDE
CDE
CDE
***CAM3***
ASC
455
455
GEF
GEF
GEF
CDE
CDE
CDE
CDE

 

I'll include the testing text, and the program.

 

ECCAD

 

0 Likes
Message 7 of 10

Sea-Haven
Mentor
Mentor

I know pushing my own wheelbarrow but did you read what I posted ? It is what you want and write direct to Excel. Do you want it or not ? It will only display in the DCL the text that is inside the box, 1-???

0 Likes
Message 8 of 10

nilambaridal28
Contributor
Contributor

@Sea-Haven - Thanks for your help! I didn't understand how to check the code. Could you please guide me.

0 Likes
Message 9 of 10

Sea-Haven
Mentor
Mentor

Ok will write full code as soon as I get a chance.

0 Likes
Message 10 of 10

Sea-Haven
Mentor
Mentor

Try this needs multi getvals above, save in a support path. Dont have excel open. 

 

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/select-text-and-make-list-as-per-user-provided-numbers/td-p/12789124
; write to excel text in rectang
; BY AlanH June 2024

(defun c:txtexcel ( / )

;;	Thanks to fixo			;;
;;   = Set Excel cell text =    ;;
;;				;;
(defun xlsetcelltext ( row column text)
(setq cells (vlax-get-property  (vlax-get-property myxl "ActiveSheet") "Cells"))
  (vl-catch-all-apply
    'vlax-put-property
    (list cells 'Item row column
	(vlax-make-variant (vl-princ-to-string text) vlax-vbstring)))
)

(if (not AH:getvalsm)(load "Multi Getvals.lsp"))

(or (setq myxl (vlax-get-object "Excel.Application"))
    (setq myxl (vlax-get-or-create-object "excel.Application"))
)
(vla-put-visible myXL :vlax-true)
(vlax-put-property myxl 'ScreenUpdating :vlax-true)
(vlax-put-property myXL 'DisplayAlerts :vlax-true)
(vlax-invoke-method (vlax-get-property myXL 'WorkBooks) 'Add)

(setq num 1)
(setq rows 1)

(while (setq plent (entsel "\nPick a rectang Enter to exit "))
(if plent (setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (car plent))))))
(progn
  (setq co-ord (cons (last co-ord) co-ord))
  (setq ss (ssget "wp" co-ord '((0 . "TEXT"))))
  (setq lst '() lst1 '())
  (repeat (setq x (sslength ss))
    (setq str (cdr (assoc 1 (entget (ssname ss (setq x (1- x)))))))
    (setq lst1 (cons str lst1))
    (setq lst (cons "1" lst))
    (setq lst (cons 20 lst))
    (setq lst (cons 19 lst))
    (setq lst (cons str lst))
  )
  (setq lst (cons "Enter values " lst))

  (setq ans (AH:getvalsm lst))

  (setq lst3 '())
  (setq k 0)

  (repeat (length ans)
    (setq lst3 (cons (list (nth k lst1) (nth k ans)) lst3))
    (setq k (1+ k))
  )

  (xlsetcelltext rows 1 (strcat "CAM" (rtos num 2 0)))
  (setq rows (1+ rows))
  (foreach val lst3
    (repeat (atoi (cadr val))
     (xlsetcelltext rows 1 (car val))
     (setq rows (1+ rows))
    )
  )

  (setq num (1+ num))
 )
)

(princ)
)
(c:txtexcel)

 

 

0 Likes