Author Topic: How to run a lisp when close file ?  (Read 16904 times)

0 Members and 1 Guest are viewing this topic.

HasanCAD

  • Swamp Rat
  • Posts: 1422
How to run a lisp when close file ?
« on: May 30, 2012, 05:01:15 AM »
Hi all

I started this lisp but need some help

Usage of lisp:
To create the file history
Search for a text start with "Save Date *"
if yes find the last one and insert new text under the last one
if no alert the user to pick a point to insert new text

Questions:
Q1: How to run this lisp when close the file?
Q2: In if condition How to search for a text start with "Save Date *" and if there more than one select the last to insert the new text under it ?

The code
Code: [Select]
(defun c:FileHistory (/)
      ;Get time and date
      ;Afralisp
  (setq d (rtos (getvar "CDATE") 2 6)
yr (substr d 1 4) ;extract the year
        mo (substr d 5 2) ;extract the month
        dy (substr d 7 2) ;extract the day
hr (substr d 10 2);extract the hour
        m  (substr d 12 2);extract the minute
Sdate (strcat "Save Date: "(strcat dy "/" mo "/" yr))
Stime (strcat " Time: "(strcat hr ":" m ))
SUser (strcat " User: "(getvar "loginname"))
SStr (strcat Sdate Stime SUser)
)
 
  (if ()
    (progn
      (setq Tpt )
      (maketext SStr Tpt 4000)
      )
    (Progn
      (alert (strcat "Pick a point to Insert file history"))
      (setq Tpt (getpoint))
      (maketext SStr Tpt 4000)
   )))
(defun maketext (str pt ht )
  (entmakex (list (cons 0 "TEXT") ;***
  (cons 1 str) ;* (the string itself)
  (cons 6 "BYLAYER") ; Linetype name
  (cons 7 (getvar "TEXTSTYLE")) ;* Text style name, defaults to STANDARD, current
  (cons 8 (getvar "CLAYER")) ; layer
  (cons 10 pt) ;* First alignment point (in OCS)
  (cons 11 pt) ;* Second alignment point (in OCS)
  (cons 39 0.0) ; Thickness (optional; default = 0)
  (cons 40 ht) ;* Text height
  (cons 41 0.8) ; Relative X scale factor, Width Factor, defaults to 1.0
  (cons 51 0.0) ; Oblique angle
  (cons 62 256) ; color
  (cons 71 0) ; Text generation flags
  (cons 72 0) ; Horizontal text justification type
  (cons 73 1) ; Vertical text justification type
  (cons 210 (list 0.0 0.0 1.0))
    )  ))

HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #1 on: May 30, 2012, 08:04:00 AM »
This is a try
Code: [Select]
(defun c:FileHistory (/)

;Get time and date
;Afralisp
  (setq d (rtos (getvar "CDATE") 2 6))
  (setq yr (substr d 1 4)) ;extract the year
  (setq mo (substr d 5 2)) ;extract the month
  (setq dy (substr d 7 2)) ;extract the day
  (setq hr (substr d 10 2)) ;extract the hour
  (setq m (substr d 12 2)) ;extract the minute
  (setq Sdate (strcat "Save Date: " (strcat dy "/" mo "/" yr)))
  (setq Stime (strcat " Time: " (strcat hr ":" m)))
  (setq SUser (strcat " User: " (getvar "loginname")))

  (setq SStr (strcat Sdate Stime SUser))
  (setq sset (ssget "_X" '((0 . "Text") (1 . "Save Date:*"))))
  (setq ss (ssname sset 0))
  (setq dxfdata (entget ss))
  (setq old-dxf (assoc 10 dxfdata))
  (setq y1 (nth 2 old-dxf))

  (if (> (sslength sset) 0)
    (progn
      (repeat (setq inc (sslength sset))
(setq ss (ssname sset (setq inc (1- inc))))
(setq dxfdata (entget ss))
(setq old-dxf (assoc 10 dxfdata))
(setq x (nth 1 old-dxf))
(setq y (nth 2 old-dxf))
(if (> y1 y)
  (setq y2 y) ;T
  (setq y2 y1) ;not
)
      )
      (setq Tpt (list x y))
      (maketext SStr Tpt 4000)
    )
    (Progn
      (alert (strcat "Pick a point to Insert file history"))
      (setq Tpt (getpoint))
      (maketext SStr Tpt 4000)
    )
  )
)

Coder

  • Swamp Rat
  • Posts: 827
Re: How to run a lisp when close file ?
« Reply #2 on: May 30, 2012, 09:31:32 AM »

Code: [Select]
 
  (if (???????????)
    (progn
      (setq Tpt ??????? )
      (maketext SStr Tpt 4000)
      )
   

Some missing variables  :-D

pBe

  • Bull Frog
  • Posts: 402
Re: How to run a lisp when close file ?
« Reply #3 on: May 30, 2012, 09:32:38 AM »
Code - Auto/Visual Lisp: [Select]
  1. (defun C:Mark ( / Text Cstr low lowpt strs i e data pts inspt)
  2. (vl-load-com)      
  3. (defun Text (lay pt hgt sty str rot wd)
  4.   (entmakex (list (cons 0 "TEXT")
  5.                   (cons 1 str)
  6.                   (cons 8 lay)
  7.                   (cons 7 sty)
  8.                   (cons 10  pt)
  9.                   (cons 40 hgt)
  10.                   (cons 41 wd)
  11.                   (cons 1  str))))
  12. (setq Cstr (apply 'strcat
  13.        (mapcar  '(lambda (k)  (strcat (car k)
  14.        (menucmd (strcat "m=$(edtime,$(getvar,DATE),"
  15.                 (eval (cadr k)) ")"))))
  16.              '(("Save Date: " "")
  17.                ("" "MO/DD/YYYY ")
  18.                ("Time: " "HH:MMam/pm ")
  19.                ("User: " (getvar "loginname"))))))      
  20. (if (setq low nil pts nil
  21.           strs (ssget "_X" '((0 . "TEXT")(1 . "Save Date:*"))))
  22.     (progn
  23.     (repeat (setq i (sslength strs))
  24.           (setq e (entget (ssname strs (setq i (1- i)))))
  25.           (if (or (< (cadr (setq pt (cdr (assoc 10 e)))) low)
  26.                   (null low))
  27.                 (progn
  28.                       (setq data (append
  29.                                        (mapcar
  30.                                              'cdr
  31.                                              (vl-remove-if-not
  32.                                                    '(lambda (k)
  33.                                                           (vl-position
  34.                                                                 (car k)
  35.                                                                 '(8 40 50 41 7)))
  36.                                                    e))
  37.                                        (list pt))
  38.                             low  (cadr pt))))
  39.           (setq pts (cons pt pts))
  40.           )
  41.     (setq lowpt (last data))
  42.     (setq inspt
  43.                (list (car lowpt)
  44.                      (- low
  45.                         (if (cadr pts)
  46.                               (apply
  47.                                     'min
  48.                                     (mapcar '(lambda (k l)
  49.                                                    (distance
  50.                                                          k
  51.                                                          l))
  52.                                             pts
  53.                                             (cdr pts)))
  54.                               8000))
  55.                      (last lowpt)))
  56.     (Text (car data) inspt (cadr data)(nth 4 data) Cstr (caddr data) (nth 3 data))
  57.     )
  58.           (if (setq inspt
  59.                          (getpoint
  60.                                "\nPick point to insert file history"))
  61.                 (Text (getvar 'Clayer)
  62.                       inspt
  63.                       4000
  64.                       (getvar 'Textstyle)
  65.                       Cstr
  66.                       0.0
  67.                       1.0)
  68.                 )
  69.     )
  70.       )

Questions:
Q1: How to run this lisp when close the file?

I guess the best way to do that is via reactor


HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #4 on: May 30, 2012, 09:37:07 AM »
Thanks pBe
this is mine
Code: [Select]
(defun c:FileHistory (/      d     yr    mo   dy hr m
      sdate  stime  suser  sstr   sset ss dxfdata
      dxf    y1     old-dxf   dxfdata x
      y      y1     y2
     )
  (and
;Get time and date
;Afralisp
    (setq d (rtos (getvar "CDATE") 2 6))
    (setq yr (substr d 1 4)) ;extract the year
    (setq mo (substr d 5 2)) ;extract the month
    (setq dy (substr d 7 2)) ;extract the day
    (setq hr (substr d 10 2)) ;extract the hour
    (setq m (substr d 12 2)) ;extract the minute
    (setq Sdate (strcat "Save Date: " (strcat dy "/" mo "/" yr)))
    (setq Stime (strcat " Time: " (strcat hr ":" m)))
    (setq SUser (strcat " User: " (getvar "loginname")))
    (setq SStr (strcat Sdate Stime SUser))
    (setq ssetL (ssget "_X" '((0 . "Text") (1 . "Save Date:*"))))
    (setq sset (if ssetl
(sslength ssetL)
(setq sset 0)
       )
    )
  )

  (if (> sset 0)
    (progn
      (setq ss (ssname ssetL 0))
      (setq dxfdata (entget ss))
      (setq dxf (assoc 10 dxfdata))
      (setq y1 (nth 2 dxf))
    )
  )
;OK

  (if (> sset 0)
    (progn
      (repeat (setq inc sset)
(setq ss (ssname ssetL (setq inc (1- inc))))
(setq dxfdata1 (entget ss))
(setq old-dxf (assoc 10 dxfdata1))
(setq x (nth 1 old-dxf))
(setq y (nth 2 old-dxf))
(if (> y1 y)
  (setq y2 y) ;T
  (setq y2 y1) ;not
)
      )
      (setq Tpt (list x (- y 6000)))
      (maketext SStr Tpt 4000)
    )
    (Progn
      (alert (strcat "Pick a point to Insert file history"))
      (setq Tpt (getpoint))
      (maketext SStr Tpt 4000)
    )
  )
) ;defun

(defun maketext (str pt ht)
  (entmakex (list (cons 0 "TEXT") ;***
  (cons 1 str) ;* (the string itself)
  (cons 6 "BYLAYER") ; Linetype name
  (cons 7 (getvar "TEXTSTYLE"))
;* Text style name, defaults to STANDARD, current
  (cons 8 (getvar "CLAYER")) ; layer
  (cons 10 pt) ;* First alignment point (in OCS)
  (cons 11 pt) ;* Second alignment point (in OCS)
  (cons 39 0.0) ; Thickness (optional; default = 0)
  (cons 40 ht) ;* Text height
  (cons 41 0.8) ; Relative X scale factor, Width Factor, defaults to 1.0
  (cons 51 0.0) ; Oblique angle
  (cons 62 256) ; color
  (cons 71 0) ; Text generation flags
  (cons 72 0) ; Horizontal text justification type
  (cons 73 1) ; Vertical text justification type
  (cons 210 (list 0.0 0.0 1.0))
    )
  )
)
« Last Edit: May 30, 2012, 09:56:07 AM by HasanCAD »

HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #5 on: May 30, 2012, 09:48:06 AM »
Thanks pBe I'll study yours

I guess the best way to do that is via reactor
How is this?
I do not know whats reactor.
« Last Edit: May 30, 2012, 09:55:40 AM by HasanCAD »

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

pBe

  • Bull Frog
  • Posts: 402
Re: How to run a lisp when close file ?
« Reply #7 on: May 30, 2012, 11:44:08 AM »
Also from the same website you used for reference on you code:

http://www.afralisp.net/visual-lisp/tutorials/reactors-part-1.php



HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #8 on: May 30, 2012, 12:04:12 PM »
Thanks irneb
Thanks pBe I'll study your lisp and I am sure that its great lisp

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to run a lisp when close file ?
« Reply #9 on: May 30, 2012, 01:35:24 PM »
Glad to help, though I fear we've led you to the dark side. If you think you've made errors before, wait till you've made an error in reactors  :lmao: ... they're DANGEROUS beyond belief!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

kruuger

  • Swamp Rat
  • Posts: 637
Re: How to run a lisp when close file ?
« Reply #10 on: May 30, 2012, 05:38:16 PM »
Thanks pBe I'll study yours

I guess the best way to do that is via reactor
How is this?
I do not know whats reactor.
Code - Auto/Visual Lisp: [Select]
  1. (Defun AtSaveCommand (calling-reactor b)
  2.   (if
  3.     (or
  4.       (= (car b) "QSAVE")
  5.       (= (car b) "SAVEAS")
  6.       (= (car b) "SAVE")
  7.     )
  8.     (C:SLOWNIK)
  9.   )
  10. )
  11.  
  12. (Defun loadTheSaveReactor ()
  13.   (if *FileOnSave* (vlr-remove *FileOnSave*))
  14.   (setq *FileOnSave* (vlr-command-reactor nil '((:vlr-commandwillStart . AtSaveCommand))))
  15. )
  16.  
  17. (loadTheSaveReactor)
i'm using this when someone save the drawing. works very well.
easy to modify to CLOSE.
kruuger

pBe

  • Bull Frog
  • Posts: 402
Re: How to run a lisp when close file ?
« Reply #11 on: May 30, 2012, 11:44:01 PM »
Glad to help, though I fear we've led you to the dark side. If you think you've made errors before, wait till you've made an error in reactors  :lmao: ... they're DANGEROUS beyond belief!

So true.. Dangerous reactor is.

@hasanCAD/kruuger

Think about this. what are the conditions as when to trigger the lisp routine? Every time the user invoke a save* command? in the event the user saves the file and continues working on the file?
after a while the user click save again, then that will be two Filehistory lines. You may need to use a counter within the lisp code to determine that it ran at least once, then it should the repalce the string rather than writing a new line.

_close reator is indeed the way to go
« Last Edit: May 30, 2012, 11:47:49 PM by pBe »

HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #12 on: May 31, 2012, 03:04:30 AM »
Glad to help, though I fear we've led you to the dark side. If you think you've made errors before, wait till you've made an error in reactors  :lmao: ... they're DANGEROUS beyond belief!

Welcome mr. Angel 

HasanCAD

  • Swamp Rat
  • Posts: 1422
Re: How to run a lisp when close file ?
« Reply #13 on: May 31, 2012, 03:07:42 AM »
Glad to help, though I fear we've led you to the dark side. If you think you've made errors before, wait till you've made an error in reactors  :lmao: ... they're DANGEROUS beyond belief!

So true.. Dangerous reactor is.

@hasanCAD/kruuger

Think about this. what are the conditions as when to trigger the lisp routine? Every time the user invoke a save* command? in the event the user saves the file and continues working on the file?
after a while the user click save again, then that will be two Filehistory lines. You may need to use a counter within the lisp code to determine that it ran at least once, then it should the repalce the string rather than writing a new line.

_close reator is indeed the way to go

Yes That is correct.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to run a lisp when close file ?
« Reply #14 on: May 31, 2012, 03:22:09 AM »
Another thing to "worry" about, sometimes while the file is "closing" ... it might be impossible to modify anything inside the file. That's usually why the "command will start" reactor is usually better to use. If you use a :vlr-beginClose reactor, it might fail, especially if the user clicks Cancel when asked to save changes. Also you might need to undo the save on a :vlr-commandCanceled / :vlr-commandFailed reactor.

Reactors, dangerous they are ... you find all sorts of "disturbances in the force" which you never thought would happen.

I also think it might be a better idea to have the log saved as a text file in the same folder as the DWG with the same filename. That way it might alleviate any non-modifyable issues. Perhaps save it in CSV format, then you could link to it as if it's an Excel sheet and have a auto-updating table if you really want it displayed inside the DWG. Then you might even use the :vlr-databaseToBeDestroyed since you're not going to modify the DWG database at all.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.