Another ; error: bad argument type: consp nil

Another ; error: bad argument type: consp nil

john.uhden
Mentor Mentor
1,591 Views
8 Replies
Message 1 of 9

Another ; error: bad argument type: consp nil

john.uhden
Mentor
Mentor

I'm suspecting that (vl-file-systime) is the culprit.

I built an ambitious FindFiles routine that looks through the entire CADD server for DWG files matching dialogue inputs for filtering (oldest year, town, dwg spec, client).  In testing, every now and then it would crash with this error. Part of my process is to display the matching files with dates in a list_box so that a sort button will redisplay the list.  To convert the systime date in the format (2020 03 22 ...) I am using the nth function to get the month and year and converting to a string "2020/3/22" which is easily sortable.  All the other code is very tight so I am wondering if vl-file-systime sometimes returns nil.  That would explain the error.

I might try catching the error in my own @Anonymous_date function to replace the error with a date like "????/??/??"

Any opinions?

BTW, it's not as slow as one might think.  It's a lot more useful than Explorer.  Plus I added an "Open" button.

John F. Uhden

0 Likes
1,592 Views
8 Replies
Replies (8)
Message 2 of 9

john.uhden
Mentor
Mentor

Alrighty then!

I added...

  (defun @Anonymous_date (file / date)
    (setq date (vl-catch-all-apply 'vl-file-systime (list file)))
    (if (or (not date)(vl-catch-all-error-p date))
      (setq date "????/??/??")
      (setq date (mapcar 'itoa date)
            date (strcat (car date) "/" (nth 1 date) "/" (nth 2 date))
      )
    )
    (cons file date)
  )

and it revealed about 20 files from the years 2007 to present that had no date, and it didn't crash.

But the date is displayed in Explorer.  So is there a better way to get a file date in AutoLisp?

John F. Uhden

0 Likes
Message 3 of 9

diagodose2009
Collaborator
Collaborator

My Fast Solution=You detoKenize your SourceLisp to version*.jc_aro10.lsp

After you get the error, then you type (princ setmypid) and you search C033namefunction inside Lisp-Asci.jcaro10.lsp

cl_aclayer_topograf_2021_pp_curbedenivel-vlax.gif

 

 

0 Likes
Message 4 of 9

dbroad
Mentor
Mentor

 

_$ (nth 1 nil)
LISP ERROR:  bad argument type: consp nil  

 

which would seem to indicate that if a file is found and their are problems with the date but a list is returned then something like this might help.

 

(defun _date (file / date)
    (setq date (vl-catch-all-apply 'vl-file-systime (list file)))
    (if (or (vl-catch-all-error-p date)(not date)(not(apply 'or date)))
      (setq date "????/??/??")
      (setq date (mapcar 'itoa date)
            date (strcat (car date) "/" (cadr date) "/" (caddr date))
      )
    )
    (cons file date)
  )

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 5 of 9

john.uhden
Mentor
Mentor
@diagodose2009
I don't need to "detokenize" anything, whatever that means.
I was just not aware that vl-file-systime can return nil. I now have it
covered in a way, but thank you kindly for your concern.
What I can do differently is when vl-file-systime returns nil is to get the
date of the .bak file. That's probably better than "????/??/??." And
that's probably what I will do on Monday. Have a Happy Easter, or whatever
you celebrate this time of year.

John F. Uhden

0 Likes
Message 6 of 9

Sea-Haven
Mentor
Mentor

Using a shell command can get all *.dwg from a drive into a text file including sub directories or just 1 directory.

This is old fashioned DOS

 

example

cd \alan\lisp

D:\Alan\LISP>dir *.dwg /s > dirlst.txt

 

Looking at the txt file
Volume in drive D is Data
Volume Serial Number is 389C-402D

Directory of D:\Alan\LISP

04/07/2020 12:11 PM 14,563 100x100.dwg
13/04/2013 09:53 AM 1,008,810 2012094-ccad.dwg
06/08/2019 12:00 PM 1,721,595 2012094-CSD.dwg
05/08/2019 06:39 PM 977,217 2012094.dwg

and so on including subdirectories being searched, can then do a make list etc form txt file and sort required item name, date size etc.

 

Note the use of the /B option as well as the /S which is search subdirectories.

 

 

Have you looked at a program like "Everything" its fantastic for find a file it indexes the drives so can just type a few characters and it will display a matching list dbl click open. project12*.dwg etc 

 

I have c: 😧 and F: which is 640mb external drive almost full instant to find file, used at work and we had like 1.5Gb in one drive and it would index it.

0 Likes
Message 7 of 9

Lee_Mac
Advisor
Advisor

@john.uhden wrote:

So is there a better way to get a file date in AutoLisp?

For those instances where vl-file-systime is returning nil, you could fall back on obtaining the datelastmodified property of the File object returned by the GetFile method of the File System Object (FSO).

 

For example, consider the following set of functions:

;; Date Last Modified  -  Lee Mac
;; Returns a list of (yyyy mo dd mm hh ss) representing the last modified date/time for the supplied file

(defun LM:datelastmodified ( fnm )
    (cond
        ((LM:vldatelastmodified fnm))
        ((LM:fsdatelastmodified fnm))
    )
)
(defun LM:vldatelastmodified ( fnm / lst )
    (if (setq lst (vl-file-systime fnm))
        (mapcar '(lambda ( n ) (nth n lst)) '(0 1 3 4 5 6))
    )
)
(defun LM:fsdatelastmodified ( fnm / obj rtn )
    (if (setq fnm (findfile fnm))
        (progn
            (setq rtn
                (vl-catch-all-apply
                   '(lambda ( )
                        (setq obj (vlax-invoke-method (LM:fso) 'getfile fnm))
                        (+ 2415019 (vlax-get-property obj 'datelastmodified))
                    )
                )
            )
            (if (= 'vla-object (type obj)) (vlax-release-object obj))
            (cond
                (   (vl-catch-all-error-p rtn)
                    (prompt (vl-catch-all-error-message rtn))
                )
                (   (numberp rtn)
                    (read (strcat "(" (menucmd (strcat "m=$(edtime," (LM:num->str rtn) ",yyyy mo dd hh mm ss)")) ")"))
                )
            )
        )
    )
)

;; File System Object  -  Lee Mac
;; Returns a cached reference to the FSO, caller's responsibility to release

(defun LM:fso ( )
    (eval (list 'defun 'LM:fso 'nil (vlax-create-object "scripting.filesystemobject")))
    (LM:fso)
)

;; Number to String  -  Lee Mac
;; Converts a supplied numerical argument to a string

(defun LM:num->str ( num / dim rtn )
    (if (equal num (atoi (rtos num 2 0)) 1e-8)
        (rtos num 2 0)
        (progn
            (setq dim (getvar 'dimzin))
            (setvar 'dimzin 8)
            (setq rtn (rtos num 2 16))
            (setvar 'dimzin dim)
            rtn
        )
    )
)

(vl-load-com) (princ)

Call the above using:

(LM:datelastmodified "C:\\YourFile.ext")

Here, the LM:vldatelastmodified function will first attempt to obtain the last modified date/time using the standard vl-file-systime function, resorting to the FSO only when this function returns nil.

 

The date/time will be returned as a list of the form:

(yyyy mo dd hh mm ss)

Which could be easily converted to your desired format using something like:

(substr
    (apply 'strcat
        (mapcar
           '(lambda ( a b ) (strcat a (if (< b 10) "0" "") (itoa b)))
           '("/""/""/")
            (LM:datelastmodified "C:\\YourFile.ext")
        )
    )
    2
)

 

Message 8 of 9

john.uhden
Mentor
Mentor
@Sea-Haven
Yes. I still remember a lot of my batch programming.
But I think I'm happier with what I have.
BTW, you forgot the /B option, but that eliminates the date.

John F. Uhden

0 Likes
Message 9 of 9

john.uhden
Mentor
Mentor

@dbroad 

Thanks as usual, Doug, but check my message #2.

At least you've made me feel better about my decision.

John F. Uhden

0 Likes