TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: jaydee on July 26, 2011, 06:29:16 AM

Title: Findfile questions
Post by: jaydee on July 26, 2011, 06:29:16 AM
Hi.

I just leant that Findfile doen't look into project directories (projectname and setup under project files search path)
and heres my option. I manage to extract a list of project paths in a list as below. Please note the list of directories varies from job to jobs. What i had in mind is to split each item in the list and put it into a (cond statement.

Please assist and show me how convert this list into searchable paths?

Code: [Select]

(
"N:\\JOBS\\123\\DWG"
"N:\\JOBS\\123\\PDF"
"N:\\JOBS\\123\\IN"
"N:\\JOBS\\123\\OUT"
)


(defun FindMyFile ()

(setq MyFile (strcase (getstring "\nEnter File Name and Extention")))

(if (setq MyFile (findfile MyFile))
 (Dothis)
 (progn
  (cond
   ((setq MyFile (findfile (stcat dir1 "\\" MyFile))))
   ((setq MyFile (findfile (stcat dir2 "\\" MyFile))))
   ((setq MyFile (findfile (stcat dir3 "\\" MyFile))))
   ((setq MyFile (findfile (stcat dir4 "\\" MyFile))))
  )
 )
)
(princ))


Title: Re: Findfile questions
Post by: irneb on July 26, 2011, 06:55:06 AM
You mean something like this?
Code: [Select]
(defun SplitString (str tok / lst n m)
  (setq n 0)
  (while (setq m (vl-string-search tok str n))
    (setq lst (cons (substr str (1+ n) (- m n)) lst)
          n (1+ m)
    )
  )
  (reverse (cons (substr str (1+ n)) lst))
)

(defun ForceDirDelim (path / )
  (if (wcmatch path "*\\,*/") path (strcat path "\\"))
)

(defun FindFile2 (fn paths / found)
  (if (= (type paths) 'STR) (setq paths (SplitString paths ";")))
  (while (and (not found) paths)
    (setq found (findfile (strcat (ForceDirDelim (car paths)) fn))
          paths (cdr paths)
    )
  )
  found
)
BTW, the project folders are saved in registry to a key like this:
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R18.1\ACAD-9001:409\Profiles\<<Profile Name>>\Project Settings\<<Project Name>>

The Red depends on your ACad version and the green on Vanilla/some other Vertical.

Then the path is contained in RefSearchPath (a semi-colon separated string).
Title: Re: Findfile questions
Post by: kdub_nz on July 26, 2011, 07:14:56 AM
You could play with something like this :
I've kept it fairly simple ...
Code: [Select]
(defun c:doit (/ folderlist filename result)
  (setq folderlist (list "K:\\JOBS\\123\\DWG"
                         "K:\\JOBS\\123\\PDF"
                         "K:\\JOBS\\123\\IN"
                         "K:\\JOBS\\123\\OUT"
                   )
  )
  (if (setq filename (strcase (getstring "\nEnter File Name and Extention :")))
    ;; (setq filename "test.dwg")
    (or (setq result (findfile filename))
        (setq result (findmyfile filename folderlist))
    )
  )
  (if result
    (alert result)
    (alert "Too bad, so sad")
  )
  (princ)
)
;;----------------------------------------------------------------------
(defun findmyfile (filename folderlist / foldercount index result)
  (setq foldercount (length folderlist)
        index       0
  )
  (while (and (< index foldercount) (not result))
    (setq result (findfile (strcat (nth index folderlist) "\\" filename))
          index  (1+ index)
    )
  )
  result
)
(princ)
Title: Re: Findfile questions
Post by: Lee Mac on July 26, 2011, 07:44:53 AM
Another variation:

Code: [Select]
(defun c:test ( / file filepath )
  (setq file (getstring t "\nEnter Filename & Extension: "))
  (if
    (setq filepath
      (cond
        ( (findfile file) )
        ( (vl-some '(lambda ( path ) (findfile (strcat path "\\" file)))
           '(
              "N:\\JOBS\\123\\DWG"
              "N:\\JOBS\\123\\PDF"
              "N:\\JOBS\\123\\IN"
              "N:\\JOBS\\123\\OUT"
            )
          )
        )
      )
    )
    filepath
  )
)
Title: Re: Findfile questions
Post by: jaydee on July 26, 2011, 07:46:02 AM
Thankyou irneb and kdub_bne

Both of your functions works very well

Lee Mac, once again you provide the shortest and the simplest codes.

Cheers
Title: Re: Findfile questions
Post by: irneb on July 26, 2011, 07:49:56 AM
Or another to make a one-size-fits-all:
Code: [Select]
(vl-load-com)

(defun SplitString (str tok / lst n m)
  (setq n 0)
  (while (setq m (vl-string-search tok str n))
    (setq lst (cons (substr str (1+ n) (- m n)) lst)
          n   (1+ m)
    )
  )
  (reverse (cons (substr str (1+ n)) lst))
)

(defun ForceDirDelim (path /)
  (if (wcmatch path "*\\,*/")
    path
    (strcat path "\\")
  )
)

(defun FindFileWC (fn paths / found relpath prj lst)
  (if (= (type paths) 'STR)
    (setq paths (SplitString paths ";"))
  )
  (if (not (eq (setq prj (getvar 'ProjectName)) ""))
    (progn
      (setq found (vl-remove-if
                    '(lambda (p)
                       (vl-position p paths)
                     )
                    (append paths
                            (SplitString
                              (vl-registry-read
                                (strcat "HKEY_CURRENT_USER\\"
                                        (vlax-product-key)
                                        "\\Profiles\\"
                                        (getvar 'CProfile)
                                        "\\Project Settings\\"
                                        prj
                                )
                                "RefSearchPath"
                              )
                              ";"
                            )
                    )
                  )
      )
      (if paths
        (setq paths (append paths found))
        (setq paths found)
      )
    )
  )
  (if paths
    (setq paths (append paths
                        (vl-remove-if
                          '(lambda (p)
                             (vl-position p paths)
                           )
                          (SplitString (getenv "ACAD") ";")
                        )
                )
    )
    (setq paths (SplitString (getenv "ACAD")))
  )
  (if (not (vl-position (getvar 'DwgPrefix) paths)) (setq paths (cons (getvar 'DwgPrefix) paths)))
  (if (vl-string-search "\\" fn)
    (setq relpath (vl-filename-directory fn)
          fn      (strcat (vl-filename-base fn) (vl-filename-extension fn))
    )
    (setq relpath "")
  )
  (while paths
    (if (setq found (vl-directory-files
                      (setq prj (strcat (ForceDirDelim (car paths))
                                        relpath
                                )
                      )
                      fn
                      1
                    )
        )
      (progn
        (setq prj (ForceDirDelim (vl-filename-directory (findfile (strcat prj (car found))))))
        (if lst
          (setq lst (append lst (mapcar '(lambda (f) (strcat prj f)) found)))
          (setq lst (mapcar '(lambda (f) (strcat prj f)) found))
        )
      )
    )
    (setq paths (cdr paths))
  )
  lst
)
Even works with wildcard matching of filenames. Only now it returns a list of full paths to each file found. Send nil as path parameter if you don't have any extra paths over and above the current drawing's folder, the project paths and the support paths.
Title: Re: Findfile questions
Post by: jaydee on July 26, 2011, 08:14:32 AM
Im using acet-file-dir to built up my list which list each path inside a quotation mark.

But if using the vl-registry-read method, the list return the paths seperated by ";" semi colon

( "N:\\JOBS\\123\\DWG;N:\\JOBS\\123\\PDF;N:\\JOBS\\123\\IN;N:\\JOBS\\123\\OUT")

So how do i utilised this list.

Thanks
 
Title: Re: Findfile questions
Post by: irneb on July 26, 2011, 08:38:57 AM
Im using acet-file-dir to built up my list which list each path inside a quotation mark.

But if using the vl-registry-read method, the list return the paths seperated by ";" semi colon

( "N:\\JOBS\\123\\DWG;N:\\JOBS\\123\\PDF;N:\\JOBS\\123\\IN;N:\\JOBS\\123\\OUT")

So how do i utilised this list.

Thanks
That's why I created that SplitString method. Pass it the string and the "token" on which it needs to split. E.g.
Code: [Select]
_$ (SplitString "N:\\JOBS\\123\\DWG;N:\\JOBS\\123\\PDF;N:\\JOBS\\123\\IN;N:\\JOBS\\123\\OUT" ";")
("N:\\JOBS\\123\\DWG" "N:\\JOBS\\123\\PDF" "N:\\JOBS\\123\\IN" "N:\\JOBS\\123\\OUT")
Title: Re: Findfile questions
Post by: alanjt on July 26, 2011, 09:08:41 AM
Another variation:

Slight mod...

Code: [Select]
(defun c:Test (/ file)
  (cond
    ((findfile (setq file (getstring t "\nEnter Filename & Extension: "))))
    ((vl-some '(lambda (path) (findfile (strcat path "\\" file)))
              '("N:\\JOBS\\123\\DWG" "N:\\JOBS\\123\\PDF" "N:\\JOBS\\123\\IN" "N:\\JOBS\\123\\OUT")
     )
    )
  )
)
Title: Re: Findfile questions
Post by: jaydee on July 26, 2011, 06:51:29 PM
Sorry about that irneb
I probably posted it before seeing your new post.
Thankyou verymuch, it works great.