Jump to content

Recommended Posts

Posted

I need you to explain a little more.

Did you use multiple Lisp commands or just load files?

Take a screenshot of the code you pasted into the "acad2021Doc.lsp" file.

Posted (edited)
13 minutes ago, GLAVCVS said:

I need you to explain a little more.

Did you use multiple Lisp commands or just load files?

Take a screenshot of the code you pasted into the "acad2021Doc.lsp" file.

I  load programs and use them.

 

cmdsCargados.png

Edited by Nikon
Posted
On 9/27/2025 at 12:33 PM, Nikon said:

LISPLogV1-0.lsp is a very convenient program. Thanks @Lee Mac.
Is it possible to get a list of lisp commands in the drawing? That is, when saving a drawing, a request appears: 
"Save a list of lisp commands?" and the text with the commands is inserted into the drawing?

 

Here's a quick & dirty version - it's not advisable to prompt the user for any input as part of a reactor callback.

(defun init ( )
    (foreach grp (vlr-reactors :vlr-command-reactor :vlr-lisp-reactor)
        (foreach rtr (cdr grp)
            (if (= "lisp-commands" (vlr-data rtr))
                (vlr-remove rtr)
            )
        )
    )
    (setq lisp-command-list nil)
    (vlr-command-reactor "lisp-commands" '((:vlr-commandwillstart . onsave)))
    (vlr-lisp-reactor    "lisp-commands" '((:vlr-lispwillstart    . onlisp)))
    (princ)
)
(defun onsave ( rtr arg / idx lyr sel str )
    (setq lyr "lisp-commands")
    (cond
        (   (not arg))
        (   (not (wcmatch (setq arg (strcase (car arg))) "SAVE,QSAVE,SAVEAS")))
        (   lisp-command-list
            (if (setq sel (ssget "_X" (list (cons 8 lyr))))
                (repeat (setq idx (sslength sel))
                    (entdel (ssname sel (setq idx (1- idx))))
                )
            )
            (setq str "")
            (foreach itm (vl-sort lisp-command-list '(lambda ( a b ) (> (cdr a) (cdr b))))
                (setq str (strcat str "\\P" (car itm) "\t\t" (itoa (cdr itm))))
            )
            (makelayer lyr)
            (entmakex
                (list
                   '(0 . "MTEXT")
                   '(100 . "AcDbEntity")
                   '(100 . "AcDbMText")
                   '(010 0.0 0.0)
                    (cons 1 (substr str 3))
                    (cons 8 lyr)
                )
            )
        )
    )
    (princ)
)
(defun onlisp ( rtr arg / fun itm )
    (cond
        (   (not arg))
        (   (wcmatch (setq arg (strcase (car arg))) "~(C:*)"))
        (   (setq fun (substr arg 4 (- (strlen arg) 4))
                  itm (assoc fun lisp-command-list)
            )
            (setq lisp-command-list (subst (cons (car itm) (1+ (cdr itm))) itm lisp-command-list))
        )
        (   (setq lisp-command-list (cons (cons fun 1) lisp-command-list)))
    )
    (princ)
)
(defun makelayer ( lay )
    (if (not (tblobjname "layer" lay))
        (entmake
            (list
               '(0 . "LAYER")
               '(100 . "AcDbSymbolTableRecord")
               '(100 . "AcDbLayerTableRecord")
               '(070 . 0)
                (cons 2 lay)
               '(062 . 8)
               '(290 . 0)
            )
        )
    )
) 
(vl-load-com)
(init)

 

  • Thanks 1
Posted (edited)

Great code, as always, Mr. Lee

 

As for mine, I think I forgot that some reactors are persistent.
So, Nikon, the problem is that you must have opened the same drawing several times in the same AutoCAD session, and several prompts have accumulated, repeating the request several times.
That problem shouldn't occur anymore with this new code.
Also, you'll be able to see the text inserted before confirming the closing of the drawing.

Simply replace the "fota" function
in your "acad2021Doc.lsp" with this new one.

 

(defun fota (/ arch cad cmd mens)
  (defun pregunta (a b / cad)
    (cond
      ((= (car b) "CLOSE")
       (if (and *lstCmds*
		(setq mens (cmdsCargados))
		(= (vlax-invoke-method (vlax-create-object "wscript.shell") 'popup "驴Dejar en el dibujo un MTEXT con todos los comandos utilizados?" 0 "Guardar comandos usados" 4) 6)
	   )
	 (progn
	   (vlr-remove-all)
	   (vla-AddMText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point (getpoint "\nInsertion point...")) 100 mens)
	   (vlax-invoke-method (vlax-get-acad-object) 'Update)
	 )
	 (vlr-remove-all)
       )
      )
      ((= (type a) 'VLR-Lisp-Reactor)
       (if (not (member (setq cad (substr (car b) 4 (- (strlen (car b)) 4))) *lstCmds*))
         (setq *lstCmds* (cons (substr (car b) 4 (- (strlen (car b)) 4)) *lstCmds*))
       )
      )
    )
  )
  (vlr-remove-all) 
  (foreach sim (atoms-family 0)
    (if (wcmatch (setq cmd (strcase (vl-princ-to-string sim) T)) "c:*")
      (setq *afI* (cons sim *afI*))
    )
  )
  (setq *r* (vlr-command-reactor nil '((:vlr-commandwillStart . pregunta))))
  (setq *r1* (vlr-lisp-reactor nil '((:vlr-lispwillstart . pregunta))))
)

 

Edited by GLAVCVS
  • Thanks 1
Posted

Thanks @GLAVCVS

 

I would advise against (vlr-remove-all), as this will remove all reactors defined within the session, not only those defined by your program.

Posted
1 hour ago, Lee Mac said:

Here's a quick & dirty version - it's not advisable to prompt the user for any input as part of a reactor callback.

Please explain how to use it correctly, which command to call?

Posted
1 hour ago, GLAVCVS said:

As for mine, I think I forgot that some reactors are persistent.
So, Nikon, the problem is that you must have opened the same drawing several times in the same AutoCAD session, and several prompts have accumulated, repeating the request several times.
That problem shouldn't occur anymore with this new code.
Also, you'll be able to see the text inserted before confirming the closing of the drawing.

Simply replace the "fota" function
in your "acad2021Doc.lsp" with this new one.

Yes, I may have opened the same drawing several times. I noticed that if I use 2 lisps, then close the file, but cancel closing it and continue working in this file with new codes, when I close it again, the suggestion to save the list of commands does not appear...

Posted
2 hours ago, Lee Mac said:

 

Here's a quick & dirty version - it's not advisable to prompt the user for any input as part of a reactor callback.

 

 

Lee it is a rare day when I find an improvement for you, and it might be today... might be...

 

In your onsave would it be preferable to take any strings that 'sel' finds in the ssget and append the new commands to them? Maybe put some sort of delimitator between old and new strings? 

Reason I ask, it is not unusual for me to complete a drawing over a few sessions - end of day into the next day being most common - which means the reactors will be reset... but the commands used will still need to be listed.

 

 

  • Like 1
Posted
2 hours ago, Steven P said:

Lee it is a rare day when I find an improvement for you, and it might be today... might be...

 

In your onsave would it be preferable to take any strings that 'sel' finds in the ssget and append the new commands to them? Maybe put some sort of delimitator between old and new strings? 

Reason I ask, it is not unusual for me to complete a drawing over a few sessions - end of day into the next day being most common - which means the reactors will be reset... but the commands used will still need to be listed.

 

Yes I suppose if the log is to be maintained continuously, existing content could be parsed and updated accordingly - if more than just the OP are using this code, I'll look to update it.

  • Like 1
Posted
3 hours ago, Nikon said:

Please explain how to use it correctly, which command to call?

 

There are no commands - just load it, use a few LISP commands, and then save your drawing.

  • Thanks 1
Posted (edited)
13 hours ago, Lee Mac said:

Thanks @GLAVCVS

 

I would advise against (vlr-remove-all), as this will remove all reactors defined within the session, not only those defined by your program.

 

Yes
I know.
'vlr-remove-all' is executed during loading so that any reactor created with the previous code is erased.
It was a quick solution.

Additionally, it runs when the drawing is exited or at startup before any other application loads, so it would only affect those reactors that should remain between drawings.
I assumed that Nikon does not use these reactors.
But it is probably a risky assumption.

So I guess I am "obliged" to fix it.

 

Below, a solution that keeps the reactors even if the drawing closure is canceled, that respects any reactor created by another application, and that regenerates them in each drawing.

 

(defun fota (/ arch cad cmd mens etq letq n er lx)
  (defun pregunta (a b / cad)
    (cond
      ((member (strcase (car b)) '("CLOSE" "_CLOSE" "QUIT" "_QUIT" "EXIT" "_EXIT"))
       (if (and *lstCmds*
		(setq mens (cmdsCargados))
		(= (vlax-invoke-method (vlax-create-object "wscript.shell") 'popup "Print commands on screen?" 0 "Save commands name" 4) 6)
	   )
	 (progn
	   (vla-AddMText (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point (getpoint "\nInsertion point...")) 100 mens)
	   (vlax-invoke-method (vlax-get-acad-object) 'Update)
	 )
       )
      )
      ((= (type a) 'VLR-Lisp-Reactor)
       (if (not (member (setq cad (substr (car b) 4 (- (strlen (car b)) 4))) *lstCmds*))
         (setq *lstCmds* (cons (substr (car b) 4 (- (strlen (car b)) 4)) *lstCmds*))
       )
      )
    )
  )
  (setq letq '("Nikon1" "Nikon2") *afI* nil)
  (foreach r (vlr-reactors)
    (foreach er (cdr r)
      (if (member (setq etq (vlr-data er)) letq)
        (if (wcmatch etq "Nikon1,Nikon2") (setq lx (cons er lx)) )
      )
    )
  )
  (if lx (foreach r lx (vlr-remove r)))
  (foreach sim (atoms-family 0) 
    (if (wcmatch (setq cmd (strcase (vl-princ-to-string sim) T)) "c:*")
      (setq *afI* (cons sim *afI*))
    )
  )
  (setq *r* (vlr-command-reactor "Nikon1" '((:vlr-commandwillStart . pregunta))))
  (setq *r1* (vlr-lisp-reactor "Nikon2" '((:vlr-lispwillstart . pregunta))))
)

(defun cmdsCargados (/ cad)
  (setq *cadCmds* nil)
  (foreach sim (atoms-family 0)
    (if	(not (member sim *afI*))
      (if (and (wcmatch (setq cad (strcase (vl-princ-to-string sim) T)) "c:*")
	       (member (strcase (substr cad 3)) *lstCmds*)
	  )
	(setq *cadCmds* (strcat (if *cadCmds* (strcat *cadCmds* "\n") "\\C1Comandos utilizados durante la sesi贸n:\\C256\n") (substr cad 3)))
      )
    )
  )
  *cadCmds*
)
(fota)

 

Edited by GLAVCVS
  • Like 1
Posted

@Nikon

PS:
I think it’s better if you copy the code into "acad2021.lsp" and not into "acad2021Doc.lsp" because the content of the latter is loaded afterwards.

  • Thanks 1
Posted
8 hours ago, Lee Mac said:

There are no commands - just load it, use a few LISP commands, and then save your drawing.

I saved the reactor with the name onlispsave.lsp, uploaded it to autocad and added it to the startup.
But when I close the drawing, there is no reaction to the output of the lisps used.
That's why I asked how to use this reactor properly.

I use reactors. MTEditReactorV1-1.lsp. And a reactor to create layers for DIM, PLINE, HATCH, LEADER...
But in the codes of these reactors there are such lines:
(defun c:mteditreactoron nil
(defun c:mteditreactoroff nil

LISPLogV1-0.lsp
(defun c:LispLogON nil
(defun c:LispLogOFF nil

These reactors are working well for me.

Posted
7 hours ago, GLAVCVS said:

Below, a solution that keeps the reactors even if the drawing closure is canceled, that respects any reactor created by another application, and that regenerates them in each drawing.

I quickly tested the code. And it works perfectly! Thank you very much!

Posted
32 minutes ago, Nikon said:

I saved the reactor with the name onlispsave.lsp, uploaded it to autocad and added it to the startup.
But when I close the drawing, there is no reaction to the output of the lisps used.
That's why I asked how to use this reactor properly.

 

As I noted in my earlier post:

9 hours ago, Lee Mac said:

There are no commands - just load it, use a few LISP commands, and then save your drawing.

 

There are no prompts, no commands - the text is output to the drawing when the drawing is saved.

Posted
7 hours ago, GLAVCVS said:

@Nikon

PS:
I think it’s better if you copy the code into "acad2021.lsp" and not into "acad2021Doc.lsp" because the content of the latter is loaded afterwards.

 

The acad20##.lsp and acad20##doc.lsp files should not be modified - these are reserved for the application. Instead, you should create your own acad.lsp and acaddoc.lsp files.

 

Note that, by default, acad.lsp will be loaded once per session, and acaddoc.lsp will be loaded per document (unless ACADLSPASDOC=1, in which case acad.lsp will also be loaded per document).

Posted
7 hours ago, GLAVCVS said:

'vlr-remove-all' is executed during loading so that any reactor created with the previous code is erased

 

Not just those reactors created "with the previous code", but any reactor defined by any program - this is risky.

 

7 hours ago, GLAVCVS said:

Additionally, it runs when the drawing is exited or at startup before any other application loads, so it would only affect those reactors that should remain between drawings.

 

You cannot guarantee that it runs before any other application is loaded.

Posted
28 minutes ago, Lee Mac said:

... and acaddoc.lsp will be loaded per document (unless ACADLSPASDOC=1, in which case acad.lsp will also be loaded per document).

 

In theory, it should be that way.
But in practice, it's not.
At least not for me.

 

Can anyone else on this forum say that the same thing is happening to them?

Posted
15 hours ago, Lee Mac said:

There are no commands - just load it, use a few LISP commands, and then save your drawing.

I can't understand why your code (defun init ( )... it doesn't work for me. 
Is there a problem with the localization of Autocad?
Do I need to change this line?:

 ( (not (wcmatch (setq arg (strcase (car arg))) "SAVE,QSAVE,SAVEAS")))

to

 ( (not (wcmatch (setq arg (strcase (car arg))) "SAVE,QSAVE,SAVEAS,_SAVE,_QSAVE,_SAVEAS")))

Or something else?
Can anyone check the code?

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