PDA

View Full Version : DWG tracking LISP


fletch97
2005-06-08, 12:02 AM
Hey All -

Does anyone have any info regarding a lisp routine and/or a program that will help to track changes to each drawing by entering the user info into a log/txt file? It would be nice if the lisp/program would create a log for each drawing, log the user name, date, time and prompt the user to enter a brief description of the changes they made before allowing them to close the drawing. Is that possible or am I asking for to much?

Any info or suggestions would be greatly appreciated!

Thank you,
Steve

fletch97
2005-06-08, 04:36 PM
Ok....so I've discovered several commands that will help me to achieve this goal but I am getting hung up on the area of creating a log.

Commands:

Date
loginname
dwgprefix
dwgname
write-line
shell

Note sure if I need to use the dos prompt or not?

So I figured out how to gather the info I want and how to send it to a file (write-line) but not sure how to create a log file based on the dwg path and name? This file is where I would want to send my logs.......any suggestions?

Thanks,
Steve

LanceMcHatton
2005-06-08, 04:54 PM
Hey All -

Does anyone have any info regarding a lisp routine and/or a program that will help to track changes to each drawing by entering the user info into a log/txt file? It would be nice if the lisp/program would create a log for each drawing, log the user name, date, time and prompt the user to enter a brief description of the changes they made before allowing them to close the drawing. Is that possible or am I asking for to much?
If you're using 2002, there's an express tool called "dwglog". Add "dwglog.lsp" and "dwglog.arx" to your Startup Suite from the Express folder. It won't let you enter a description like you mentioned but it'll include this info in a *.DWH file:

Opened by LMcHatton on LMCHATTON at 10:49:07 on 12/1/2004
Closed by LMcHatton on LMCHATTON at 10:52:50 on 12/1/2004

kennet.sjoberg
2005-06-08, 04:55 PM
want to send my logs.......any suggestions?
You already have the answer : dwgprefix

: ) Happy Computing !

kennet

tflaherty
2005-06-08, 05:08 PM
I'm looking for something just like this too. If you come up with anything please let know. My boss is driving me nuts about this (and the other employees), so we can get rid of our time clock.

[ Moderator Action = ON ] Email address removed due to privacy issues.

You may wish to review "Forum Security (http://forums.augi.com/faq.php?faq=vb_augi#faq_vb_augi_security)" which can be found in the "AUGI Forum Guidelines (http://forums.augi.com/faq.php?faq=vb_augi)". [ Moderator Action = OFF ]

fletch97
2005-06-08, 05:14 PM
Well see below for what I currently have but here is a list of my current problems -

Not sure how to convert the date from that long winded number?
Still don't know how to force the creation of a txt or log file?
During this test, it would only write once....if I iniated this again it would just overwrite the existing info rather than creating a new line to log all activity?


(defun c:track ()
(setq DT (getvar "date"))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "l:\\logs\\test.txt" "w"))
(write-line DT TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(close TX)
(princ)
)

fletch97
2005-06-08, 05:16 PM
Oh.....I am not really worried about allowing the user to add in a description, I can add that in later once I get this all working properly.

Thanks!

Opie
2005-06-08, 05:24 PM
(defun c:track ()
(setq DT (getvar "date"))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq logfile "l:\\logs\\test.txt") ;<- set logfile name to variable
(if (findfile logfile) ;<- check to see if logfile exists
(setq TX (open "l:\\logs\\test.txt" "a")) ;<- if exists, append to log file
(setq TX (open "l:\\logs\\test.txt" "w")) ;<- if does not exist, create file
)
(write-line DT TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(close TX)
(princ)
)
This allows you to create or append to the log file.

fletch97
2005-06-08, 06:38 PM
Well this seems to work pretty well so far. It would be nice if I could place a space in the log file to seperate the log entry's? I'd also like to have the log file be created using the dwg path and name? (I'll start working on that next but any help would be appreciated!)


(defun c:track ()
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "l:\\logs\\test.txt" "a"))
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(close TX)
(princ)
)

LanceMcHatton
2005-06-08, 06:42 PM
I'd also like to have the log file be created using the dwg path and name?
Look at the variables DWGNAME and DWGPREFIX

Opie
2005-06-08, 06:52 PM
Fletch,

Excuse my previous post with the if statement. My mind didn't come with me today to work.

It would be nice if I could place a space in the log file to seperate the log entry's?

What is your preferred output per entry?
Do you need one line per entry or several lins per entry?
for a single line entry you could concatenate the Date, LN, DP, DN using
(write-line (strcat Date "; " LN "; " DP DN) TX)

I'd also like to have the log file be created using the dwg path and name?
You can also concatenate the drawing name and prefix to create your log file name.

(open (strcat dp (vl-string-trim ".dwg" DN) ".log")) "a")

HTH

fletch97
2005-06-08, 07:12 PM
Thanks for you help Richard!!

I am having a syntext error with this line though.....any ideas?

(setq TX (open (strcat DP (vl-string-trim ".dwg" DN) ".log")) "a")



Here's the entire lisp so far....

(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open (strcat DP (vl-string-trim ".dwg" DN) ".log")) "a")
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)

Opie
2005-06-08, 07:15 PM
what version of autocad are you using?

fletch97
2005-06-08, 07:25 PM
AutoCAD 2006

Opie
2005-06-08, 07:29 PM
Thanks for you help Richard!!

I am having a syntext error with this line though.....any ideas?

(setq TX (open (strcat DP (vl-string-trim ".dwg" DN) ".log")) "a")

I put the "a" in the wrong place
(setq TX (open (strcat DP (vl-string-trim ".dwg" DN) ".log") "a"))

fletch97
2005-06-08, 07:43 PM
Dam.....I see exactly what you mean, nice catch!

Well everything seems to be working now but I have concerns with the ability of users to motify this log file. Is there a way to lock it down through lisp? I was thinking about placing all the logs into one folder on my CAD manager drive letter, which is locked down with permission groups, but I would need the log file to be created in there with a name that references the dwg path and dwg name? Unless you have any other suggestions? Just basically looking to not allow the user to manually change or delete this log file.

Thanks,
Steve

Opie
2005-06-08, 07:53 PM
Things that come to mind.

Are you wanting to create a log file for each drawing that is created? The number of files could get out of hand.

If you place it on a drive that is locked down to the users, will your program still work? Network permissions.

jwanstaett
2005-06-08, 08:06 PM
I use a VBA program to log all drawing close. It save the data in a access database file
it use the userr5 system Variable to save the TdinDwg system Variable so the time in the drawing is saved
this zip file has the database fie in it save it and change jwacmdopen to it location
the code go in thisdrawing of a VBA project that is always loaded
system Variable users5 is save as remarks in the database
and DwgSave is check in the database of the drawing was save be for closing


Private Sub AcadDocument_BeginClose()
Dim jwaLogin As String
jwaLogin = ThisDrawing.GetVariable("loginname")
Dim jwaCMDOpen As String
jwaCMDOpen = "e:Databasefilesworklog.mdb" 'change to Loaction of database
Dim jwaTdinDwg As Double
jwaTdinDwg = ThisDrawing.GetVariable("tdindwg")
Dim jwaUser5 As Double
jwaUser5 = ThisDrawing.GetVariable("userr5")
Dim jwaHours As Double
jwaHours = (jwaTdinDwg - jwaUser5) * 24'use userr5 to save time
Dim jwaSave As Boolean
Dim jwaRs As DAO.Recordset
Dim jwaDB As DAO.Database
Dim jwaWs As DAO.Workspace

jwaSave = ThisDrawing.Application.ActiveDocument.Saved
'If jwaLogin = "Cad04" Then
'MsgBox "Closeing Document"
'End If
On Error GoTo jwaError
If Left(ThisDrawing.GetVariable("DWGNAME"), 7) <> "Drawing" Then
Set jwaWs = DAO.DBEngine.Workspaces(0)
Set jwaDB = jwaWs.OpenDatabase(jwaCMDOpen)
Set jwaRS1 = jwaDB.OpenRecordset("Worklog")
With jwaRS1
.AddNew
!Drawing = ThisDrawing.GetVariable("dwgname")
!TdinDwg = jwaTdinDwg
!hours = jwaHours
!TdUsrTimer = ThisDrawing.GetVariable("TDUSRTIMER")
!DwgSaved = jwaSave
!User = jwaLogin
!remarks = ThisDrawing.GetVariable("users5")
.Update
.Bookmark = .LastModified
End With
End If
if jwaSave Then
ThisDrawing.SetVariable "userr5", jwaTdinDwg
End If
Exit Sub
jwaError:
MsgBox "Log Error " & Err.Description
End Sub

fletch97
2005-06-08, 08:26 PM
Richard -

Yea I was sort of thinking that there should be a log file for each drawing. Even know there may be a lot of log files, at least the log files themself, woulnd't be as large. I am mean if I just had a log file created for each user, the log files would be larger and it would be harder to find out who the last one was that modified a particular drawing.

Good question about the network log location.....not sure if the permissions would restrict them from writing to that location. I will check on that but if I were to do that, how should I structure this line.....

(setq TX (open (strcat DP (vl-string-trim ".dwg" DN) ".log") "a"))

It would need to create the log file into the L:\logs folder with a file name that reflected the dwg path and dwg name.

Opie
2005-06-08, 08:42 PM
Are you thinking of placing one log file per dwg?
The one to one log file may have a problem with duplicate file names.

One log file for all dwgs?
Would reduce the chance of duplicate file names.
Only one location to look for drawing information lookup.

fletch97
2005-06-08, 08:54 PM
I was thinking 1 file per drawing see below.....

If the drawing path is - \\99126\dwgs\sheets\

and the drawing name is - A-1.dwg

Than I would like to see the lisp create a file called "99126 dwgs sheets A-1.log" in the L:\Logs folder.

Does that sound like a good idea? If so, is it possible?

fletch97
2005-06-08, 08:56 PM
I would imagine that you need to chop up the dwg path and reassembly it when opening the file but that's just a guess. And if it's right guess, than how?

imblueflies
2005-06-08, 09:19 PM
I love this lisp routine. I always have trouble remembering the billion things I do each day and this is a way to keep track of it. This lisp is great, when I open up a drawing to work on it, I just type in TRACK and enter a description of what I'm doing and then when I need to enter my time into payroll I can just browse through the log file and see what I've done.

This brings me to a question; is there any way to add the date to the log file name? That way I would have a new log file for each day. For example the file name for today would be "track-060805.txt".

Any help would be appreciated!

Thanks,

Mike

Opie
2005-06-08, 09:35 PM
I was thinking 1 file per drawing see below.....

If the drawing path is - \\99126\dwgs\sheets\

and the drawing name is - A-1.dwg

Than I would like to see the lisp create a file called "99126 dwgs sheets A-1.log" in the L:\Logs folder.

Does that sound like a good idea? If so, is it possible?

Place the code in red between the corresponding lines
(setq DN (getvar "dwgname"))

(if (vl-string-search ":" dp)
(setq dp (substr dp (+ 2 (vl-string-search ":" dp))))
)
(while (vl-string-search "\\" dp)
(setq dp (vl-string-subst " " "\\" dp))
)
(setq LogFileDirectory "L:\\Logs\\")

(setq TX (open (strcat LogFileDirectory DP (vl-string-trim ".dwg" DN) ".log")) "a")

fletch97
2005-06-08, 10:02 PM
Richard......thanks so much for your help. I got the finished product I was looking for! Couldn't have done it without your help!

Now I plan on customizing everyone's Autocad's close command so that it access's the track lisp routine each time they try to close. We'll see how it goes!

NOTE: I had to play around with the permissions on my 'L' drive, logs folder. Please feel free to e-mail me for details but I was able to allow them to create the log, read the log, but they can't modify it, delete it or create any folders. sfletcher@tuckersadler.com


Here it is for everyone to use if they'd like.........


(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM)
LN (getvar "loginname")
DP (getvar "dwgprefix")
DP2 (getvar "dwgprefix")
DN (getvar "dwgname"))
(if (vl-string-search ":" DP)
(setq DP (substr DP (+ 2 (vl-string-search ":" DP))))
)
(while (vl-string-search "\\" DP)
(setq DP (vl-string-subst " " "\\" DP))
)
(setq LogFileDirectory "L:\\Logs\\")
(setq TX (open (strcat LogFileDirectory DP (vl-string-trim ".dwg" DN) ".log") "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP2 TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)

fletch97
2005-06-08, 10:04 PM
Now Mike -

Glad to hear you liked the lisp! This thread has been a collection of changes and adjustments to tweak it to my goals, so which one do you have? I can help you modify to include the date in the log name.

Thanks,
Steve

bbapties
2005-06-08, 10:08 PM
...I was able to allow them to create the log, read the log, but they can't modify it, delete it or create any folders....
If they cant modify it....how will the log file be modified when tracking the same drawing more than once....isnt it set up to add to the log if edited again....??

imblueflies
2005-06-08, 10:14 PM
LOL, it was fun to see this lisp evolve into what it is now. I preferred to have the log file remain in one place (not in the drawing directory) and the file name to be uniform (not based on drawing name) so here's what my file looks like right now:

(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "c:\\logs\\track.txt" "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)

So the file remains on my local drive and the lisp just keeps updating the txt file. What I would love to have it do is add the information into a text file (as it does now) but the text file name would be based on the current date. For example:

Today, I go about my work, enter in some entries using the TRACK command.....at the end of the day I should have a txt file in my log directory called "Track-060805.txt". Tomorrow, at the end of the day I should see a log file called "Track-060905.txt" and so on. That way I will be keeping track of my daily duties and all I have to do is type in TRACK in every drawing I work on. When payroll day comes around I can enter my time in based on my descriptions and each txt file would be one day's worth of work.

Does that make sense? Thank you so much for helping me out. I look forward to your response.

Mike

fletch97
2005-06-08, 10:14 PM
Just personally had that problem.....good catch. So I had to open the access for them to modify it. So now it works but how can I go about keeping the logs intact without anyone messing around with them?

I'll have to think about this one!

fletch97
2005-06-08, 10:17 PM
Oh......I can change the folder and files to be hidden and the lisp still works!!!


Mike -

I understand, I'll work on it now.

Steve

Opie
2005-06-08, 10:25 PM
Richard......thanks so much for your help. I got the finished product I was looking for! Couldn't have done it without your help!
Steve,

I'm glad I could help. 8)

kennet.sjoberg
2005-06-09, 12:15 AM
...Does anyone have any...
This may be an other way to do it, the reactor way :) it is made for the questions in the thread start.
(vl-load-com)
(defun Function_When_Saving_A_Drawing (ObjArg ListArg / LogFile File#1 Info )
(alert "Describe your changes at the Command line !" )
(setq LogFile (strcat (vl-string-right-trim ".dwg" (strcat (getvar "DWGPREFIX" ) (getvar "DWGNAME" ))) ".log" ) )
(setq File#1 (open LogFile "a" ) )
(princ (strcat (substr (rtos (getvar "CDATE")) 1 4 ) "-" (substr (rtos (getvar "CDATE")) 5 2 ) "-" (substr (rtos (getvar "CDATE")) 7 2 )) File#1 )
(princ (strcat " " (substr (rtos (getvar "CDATE")) 10 2 ) ":" (substr (rtos (getvar "CDATE")) 12 2 ) " " ) File#1 )
(princ (getenv "USERNAME" ) File#1 )
(princ " ; " File#1 )
(if (= (setq Info (getstring T "Describe your changes : " )) "" ) (princ "No info given" File#1 ) (princ Info File#1 ) )
(princ "\n" File#1 )
(close File#1 )
(princ)
)
(vlr-dwg-reactor nil '((:vlr-savecomplete . Function_When_Saving_A_Drawing )) )
: ) Happy Computing !

kennet

eleonard
2006-05-11, 08:23 PM
This may be an other way to do it, the reactor way :) it is made for the questions in the thread start.
(vl-load-com)
(defun Function_When_Saving_A_Drawing (ObjArg ListArg / LogFile File#1 Info )
(alert "Describe your changes at the Command line !" )
(setq LogFile (strcat (vl-string-right-trim ".dwg" (strcat (getvar "DWGPREFIX" ) (getvar "DWGNAME" ))) ".log" ) )
(setq File#1 (open LogFile "a" ) )
(princ (strcat (substr (rtos (getvar "CDATE")) 1 4 ) "-" (substr (rtos (getvar "CDATE")) 5 2 ) "-" (substr (rtos (getvar "CDATE")) 7 2 )) File#1 )
(princ (strcat " " (substr (rtos (getvar "CDATE")) 10 2 ) ":" (substr (rtos (getvar "CDATE")) 12 2 ) " " ) File#1 )
(princ (getenv "USERNAME" ) File#1 )
(princ " ; " File#1 )
(if (= (setq Info (getstring T "Describe your changes : " )) "" ) (princ "No info given" File#1 ) (princ Info File#1 ) )
(princ "n" File#1 )
(close File#1 )
(princ)
)
(vlr-dwg-reactor nil '((:vlr-savecomplete . Function_When_Saving_A_Drawing )) )
: ) Happy Computing !

kennet


I really like this but is there a way to have a log saved with out having the alert and entering in information. I am trying to log which users get into drawings. We have a lot of blaming the drafters on things that have happened when it was really a designer who isn't supposed to be in final product drawings messing things up.
I don't want people to know that I am logging who saves drawings.
I hope that makes sense.

Emily

kennet.sjoberg
2006-05-12, 07:32 AM
Hi Emily !

One ";" do suppress the command line

(vl-load-com)
(defun Function_When_Saving_A_Drawing (ObjArg ListArg / LogFile File#1 Info )
;; (alert "Describe your changes at the Command line !" )
(setq LogFile (strcat (vl-string-right-trim ".dwg" (strcat (getvar "DWGPREFIX" ) (getvar "DWGNAME" ))) ".log" ) )
(setq File#1 (open LogFile "a" ) )
(princ (strcat (substr (rtos (getvar "CDATE")) 1 4 ) "-" (substr (rtos (getvar "CDATE")) 5 2 ) "-" (substr (rtos (getvar "CDATE")) 7 2 )) File#1 )
(princ (strcat " " (substr (rtos (getvar "CDATE")) 10 2 ) ":" (substr (rtos (getvar "CDATE")) 12 2 ) " " ) File#1 )
(princ (getenv "USERNAME" ) File#1 )
(princ " ; " File#1 )
;; (if (= (setq Info (getstring T "Describe your changes : " )) "" ) (princ "No info given" File#1 ) (princ Info File#1 ) )
(princ "\n" File#1 )
(close File#1 )
(princ)
)
(vlr-dwg-reactor nil '((:vlr-savecomplete . Function_When_Saving_A_Drawing )) )

: ) Happy Computing !

kennet

mfowler
2006-07-06, 07:01 PM
LOL, it was fun to see this lisp evolve into what it is now. I preferred to have the log file remain in one place (not in the drawing directory) and the file name to be uniform (not based on drawing name) so here's what my file looks like right now:

(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "c:\\logs\\track.txt" "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)

So the file remains on my local drive and the lisp just keeps updating the txt file. What I would love to have it do is add the information into a text file (as it does now) but the text file name would be based on the current date. For example:

Today, I go about my work, enter in some entries using the TRACK command.....at the end of the day I should have a txt file in my log directory called "Track-060805.txt". Tomorrow, at the end of the day I should see a log file called "Track-060905.txt" and so on. That way I will be keeping track of my daily duties and all I have to do is type in TRACK in every drawing I work on. When payroll day comes around I can enter my time in based on my descriptions and each txt file would be one day's worth of work.

Does that make sense? Thank you so much for helping me out. I look forward to your response.

Mike
This is an awesome routine and I plan to begin using it. Two things I'd like to figure out how to do however...

1. Currently, when the log file is appended, the last line added is at the bottom of the log. Is there a way to append to the top of the log instead, so that scrolling is minimized after it begins to build up?

2. I'd really like to attach this to the _close command so it becomes mandatory before a user can exit the file. Using the function on the save command doesn't work that well because we tend to hit the save button several times before actually closing the file.

Thanks for the effort so far!

mfowler
2006-07-06, 09:23 PM
I've almost figured out a way to solve my own question #1. I'm sure this isn't the most efficient way, but I'm no programmer. Basically what I did was undefine the close command in my acad.lsp file, and then change the (defun c:track () line to (defun c:close (). Finally, at the end of track.lsp, after the (close TX) line I added lines to redefine and initiate the correct close command.

This works, but when it then prompts the user to save or discard changes, it does so at the command prompt instead of the alert box. I'd like to use the alert box, but I can't figure out how to get that part to work.

My new track.lsp code:

(defun c:close ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "z:\\standards\\cad manager\\logs\\track.txt" "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(command "redefine" "close")
(command ".close" )
(princ)
)

Opie
2006-07-06, 09:32 PM
I've almost figured out a way to solve my own question #1. I'm sure this isn't the most efficient way, but I'm no programmer. Basically what I did was undefine the close command in my acad.lsp file, and then change the (defun c:track () line to (defun c:close (). Finally, at the end of track.lsp, after the (close TX) line I added lines to redefine and initiate the correct close command.

This works, but when it then prompts the user to save or discard changes, it does so at the command prompt instead of the alert box. I'd like to use the alert box, but I can't figure out how to get that part to work.

My new track.lsp code:

Instead of redefining your close command, you could have a reactor execute your routine.
(vlr-dwg-reactor nil '((:vlr-beginClose . Function_When_Saving_A_Drawing)) )
The function in red would be changed to the appropriate routine name.

mfowler
2006-07-06, 09:43 PM
Instead of redefining your close command, you could have a reactor execute your routine. Thanks for the assist, but that doesn't seem to work. When I close, I get the alert prompt to save or discard, but it closes the drawing before allowing the description to be entered. Thus no entry is made into the log file.

Edit: I can actually see the track.lsp command being started, but it doesn't pause for the description before closing the drawing.


(vl-load-com)
(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "z:\\standards\\cad manager\\logs\\track.txt" "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)
(vlr-dwg-reactor nil '((:vlr-beginClose . track)) )

Opie
2006-07-06, 09:51 PM
Thanks for the assist, but that doesn't seem to work. When I close, I get the alert prompt to save or discard, but it closes the drawing before allowing the description to be entered. Thus no entry is made into the log file.

Edit: I can actually see the track.lsp command being started, but it doesn't pause for the description before closing the drawing.


(vl-load-com)
(defun c:track ()
(setq DES (getstring T"\n Enter Brief Description of Work Performed: "))
(setq
V1 (menucmd "M=$(edtime, $(getvar,date),DDDD)")
TM (menucmd "M=$(edtime, $(getvar,date),hh:mm:ss)")
MO (menucmd "M=$(edtime, $(getvar,date),MOnth)")
DAY (menucmd "M=$(edtime, $(getvar,date),DD)")
YR (menucmd "M=$(edtime, $(getvar,date),yyyy)")
DATE (strcat V1 ", " MO " " DAY ", " YR " " TM))
(setq LN (getvar "loginname"))
(setq DP (getvar "dwgprefix"))
(setq DN (getvar "dwgname"))
(setq TX (open "z:\\standards\\cad manager\\logs\\track.txt" "a"))
(write-line "" TX)
(write-line "-----------------------------------" TX)
(write-line "" TX)
(write-line Date TX)
(write-line LN TX)
(write-line DP TX)
(write-line DN TX)
(write-line "" TX)
(write-line "Description:" TX)
(write-line DES TX)
(close TX)
(princ)
)
(vlr-dwg-reactor nil '((:vlr-beginClose . track)) )

I gotcha. But I don't know how to remedy it.

kennet.sjoberg
2006-07-07, 12:19 PM
. . .I can actually see the track.lsp command being started, but it doesn't pause for the description before closing the drawing.
Try function, not "command function" remove "c:" (defun track ()

: ) Happy Computing !

kennet

kennet.sjoberg
2006-07-07, 02:39 PM
Try function, not "command function" remove "c:" (defun track ()
No that is not enough, you have to read the manual to ;) and take care of arguments.

; Construct the reactor, look in the help file please
(vlr-dwg-reactor data callbacks )
( event-name . callback_function ) ; the callback_function takes two arguments
(vlr-dwg-reactor nil :vlr-saveComplete . track00 )
(vlr-dwg-reactor nil '(( :vlr-saveComplete . track00 )) ) ; <- Ok here it is now

; Construct the callback_function
(defun track00 ( ObjArg ListArg / LocalVar1 LocalVar2 AndSoOnVar )
(princ "\n************************************\n" )
(princ "\n" )(princ ObjArg )(princ "\n" )
(alert "Now is ObjArg shown" )
(alert "Now comes the ListArg" )
(princ "\n************************************" )
(foreach in ListArg (princ "\n" )(princ in ) )
(princ "\n************************************\n" )
(alert "Hey time to write your info now and here !" )
(princ)
)


: ) Happy Computing !

kennet

mfowler
2006-07-07, 03:48 PM
Try function, not "command function" remove "c:" (defun track ()that doesn't work either. I can see what I think is "invalid argument... function cancelled" or something like that. It scrolls by too fast to read as the drawing closes. Maybe I should just stick to the command line save option.

kennet.sjoberg
2006-07-07, 04:28 PM
that doesn't work either. I can see what I think is "invalid argument... function cancelled". . .
The answer is here : LINK (http://forums.augi.com/showthread.php?t=20667#post516378) please test it.

: ) Happy Computing !

kennet

rcroke
2006-07-11, 02:51 PM
Wow I have been looking for something like this.
But with a twist.
I need it to track editing time. Can that be added?
I'm not a programmer

rcroke
2006-07-11, 03:45 PM
I use a VBA program to log all drawing close. It save the data in a access database file
it use the userr5 system Variable to save the TdinDwg system Variable so the time in the drawing is saved
this zip file has the database fie in it save it and change jwacmdopen to it location
the code go in thisdrawing of a VBA project that is always loaded
system Variable users5 is save as remarks in the database
and DwgSave is check in the database of the drawing was save be for closing


Private Sub AcadDocument_BeginClose()
Dim jwaLogin As String
jwaLogin = ThisDrawing.GetVariable("loginname")
Dim jwaCMDOpen As String
jwaCMDOpen = "e:Databasefilesworklog.mdb" 'change to Loaction of database
Dim jwaTdinDwg As Double
jwaTdinDwg = ThisDrawing.GetVariable("tdindwg")
Dim jwaUser5 As Double
jwaUser5 = ThisDrawing.GetVariable("userr5")
Dim jwaHours As Double
jwaHours = (jwaTdinDwg - jwaUser5) * 24'use userr5 to save time
Dim jwaSave As Boolean
Dim jwaRs As DAO.Recordset
Dim jwaDB As DAO.Database
Dim jwaWs As DAO.Workspace

jwaSave = ThisDrawing.Application.ActiveDocument.Saved
'If jwaLogin = "Cad04" Then
'MsgBox "Closeing Document"
'End If
On Error GoTo jwaError
If Left(ThisDrawing.GetVariable("DWGNAME"), 7) <> "Drawing" Then
Set jwaWs = DAO.DBEngine.Workspaces(0)
Set jwaDB = jwaWs.OpenDatabase(jwaCMDOpen)
Set jwaRS1 = jwaDB.OpenRecordset("Worklog")
With jwaRS1
.AddNew
!Drawing = ThisDrawing.GetVariable("dwgname")
!TdinDwg = jwaTdinDwg
!hours = jwaHours
!TdUsrTimer = ThisDrawing.GetVariable("TDUSRTIMER")
!DwgSaved = jwaSave
!User = jwaLogin
!remarks = ThisDrawing.GetVariable("users5")
.Update
.Bookmark = .LastModified
End With
End If
if jwaSave Then
ThisDrawing.SetVariable "userr5", jwaTdinDwg
End If
Exit Sub
jwaError:
MsgBox "Log Error " & Err.Description
End Sub


huh? How can I make this work?

jwanstaett
2006-07-12, 03:22 PM
Did you down load the zip file with the database, save the database and set jwaCMDOpen to the location of the database. you will need to references Microsoft DA0 Object Library for the code to work. Did you put the code in ThisDrawing of a loaded project. The best place is in Acad.dvd and on the AutoCAD sports path this way it will always load.

Note AutoCAD check the sports path for Acad.dvd and load it. If there more then one AutoCAD only load the first one it find.


huh? How can I make this work?

kgrant.115222
2007-11-21, 09:36 PM
i keep getting an error,

Command:
TRACK Wednesday, November 21, 2007 14:35:43
kgrant
C:\Documents and Settings\kgrant\My Documents\
Drawing2.dwg
; error: bad argument type: streamp nil



Dont know what i am doing wrong here. Anyone

rstrandmark
2007-11-22, 12:03 AM
Cool thread. Even though this is LISP thread I thought I might share my experiences with VBA in creating a time tracker.

I created VB(A) routines for AutoCAD, Word, Excel, Outlook, Access, and photoshop scripts that report back to a MS Access database. I haven't worked much in revit but I will tackle that when I work with it more.

At the end of the week I just create a report (from a premade template) that shows exactly what I did within the given time frame. It has graphs, pie charts, and totals showing time spent on different projects within the given time frame. The program figures out the project number from where the files reside on the network. For emails for example, I always put our project number first thing in the subject line so it gets parsed correctly, and the database stores the body of the text in a text field. It do all the calculations, sorting, graphing, etc within the MS Access client, and all the VBA or scripting routines do is report the data to the database. I've been using it for over 1 year now flawlessly, the database file has over 70,000 records and is only 20MB.

Here is the AutoCAD part of the VBA code:


'~~~~This Drawing module~~~~
Private Sub AcadDocument_Activate()
Call makeRecord("Activated")
End Sub
Private Sub AcadDocument_BeginClose()
Call makeRecord("Close")
End Sub
Private Sub AcadDocument_BeginDocClose(Cancel As Boolean)
Call makeRecord("DocClose")
End Sub
Private Sub AcadDocument_Deactivate()
Call makeRecord("Deactivated")
End Sub
Private Sub AcadDocument_EndPlot(ByVal DrawingName As String)
Call makeRecord("Plot")
End Sub
Private Sub AcadDocument_EndSave(ByVal FileName As String)
Call makeRecord("Save")
End Sub
Private Sub AcadDocument_LayoutSwitched(ByVal LayoutName As String)
Call makeRecord("Changed Layout to " & LayoutName)
End Sub

'~~~~module code~~~~
'requires DAO reference
Private Const LocOfDB As String = "\My Documents\Time Tracker\TimeTracking.mdb"

Public Sub makeRecord(evType As String)
On Error Resume Next
Dim uName As String, dbPath As String
Dim dbThisDB As DAO.Database
Dim rcdCID As DAO.Recordset
uName = Environ("USERNAME")
dbPath = Environ("USERPROFILE") + LocOfDB
Set dbThisDB = OpenDatabase(dbPath)
Set rcdCID = dbThisDB.OpenRecordset("tblAcadLog")
rcdCID.AddNew
rcdCID![DateOfEntry] = Now()
rcdCID![TypeOfApp] = "AutoCAD"
rcdCID![EventType] = evType
rcdCID![FileName] = Application.ActiveDocument.Name
rcdCID![FileDirectory] = Application.ActiveDocument.Path
rcdCID![ProjectNumber] = findPN(Application.ActiveDocument.Path)
rcdCID![UserName] = uName
'rcdCID![FileLastSave] = Application.ActiveDocument.GetVariable("TDUPDATE")
rcdCID![FileLastSave] = Format(Application.ActiveDocument.GetVariable("TDUPDATE"), Date) & " " & _
Format(Application.ActiveDocument.GetVariable("TDUPDATE"), "hh:mm:ss AMPM")
rcdCID![FileElapsedTime] = Application.ActiveDocument.GetVariable("TDINDWG")
rcdCID![SessionElapsedTime] = Application.ActiveDocument.GetVariable("TDUSRTIMER")
rcdCID.Update
rcdCID.Close
Set rcdCID = Nothing
Set dbThisDB = Nothing
End Sub

Function findPN(inputStr)
If InStr(1, inputStr, "Projects\") > 0 Then
fixstr = Replace(Trim(Mid(inputStr, InStr(1, inputStr, "rojects\") + 13)), " ", " ")
fixstr = Trim(Left(fixstr, InStr(1, fixstr, "\")))
If InStr(1, fixstr, " ") > 0 Then
fixstr = Trim(Left(fixstr, InStr(1, fixstr, " ")))
End If
findPN = Trim(Replace(fixstr, "\", ""))
Else
findPN = "Unknown"
End If
End Function

cadtag
2007-11-26, 10:47 PM
Just a suggestion, but you might want to add a column for the handle of the last entity created in the drawing.

(CDR(ASSOC 5(ENTGET(ENTLAST)))) will return the handle of the last entity created in the drawing as a string, which can be added to the information you write out to your logfile. since handles are sequential and never reused, they can act as a pointer to help track down problems with a drawing and map them back to the user who was working in the drwing when the problem was created.

Not foolproof, but can be very helpful...If the problem objects have a handle between Joe's save, and Marvin's save, then it's a good bet that Marvin did it. (whatever _it_ is)

bbapties
2007-11-27, 08:53 PM
I am very interested in this thread...I am too looking for the same type of routine.

I see alot of stuff that is close... but not exactly what im looking for. Can someone point me to the correct thread to satisfy what im looking for?

Creation of one log file on a certain network directory
prompts at closing for "reason of save" if closing a drawing that has been saved in one way or the other (and loop prompt untill user actually types something)...so that if someone opens the drawing and closes without saving it does not log.

log the following..
user, file name with directory, open time, close time, "reason for save"

I would be a hero to the "big cheese"
:mrgreen:
Please help me get my end of the year raise...;)

Thanks!!

kgrant.115222
2007-11-27, 11:44 PM
it seems as if it doesnt want me to save the file to the server on the network, but i can to the local drive.

kgrant.115222
2007-12-05, 08:26 PM
Anyone?

Still no luck yet, although i havent played with it in a couple of days now.