rcb007 Posted December 1, 2022 Posted December 1, 2022 I am trying to find a way where I can search for a keyword and it would open a dialog which would only show those files. User could then select the file in the dialog to load it. I stumbled upon a routine, I am trying to adjust to do that scenario. (Maybe this is not the right way to do it, but it does come close to what I am trying to do.) Currently, when the routine is executed, it asks for a keyword "testing". It then opens the Select File dialog, but does not show just the keyword files. It shows everything in the base AutoCAD Folder. (defun c:SearchforDLL (/ EndList SearchStr DirPath) ;;https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/searching-a-directory-tree/td-p/1875317 (setq SearchStr (getstring T"\n Enter string to search for: ")) (setq DirPath (getfiled "" "" "" 4)) (AddFileToList (vl-filename-directory DirPath) SearchStr) (and (defun AddFileToList (Path Str) (foreach file (vl-directory-files Path "*" 1) (if (wcmatch (strcase file) (strcase (strcat "*" Str "*"))) (setq EndList (cons (strcat Path "C:\\" file) EndList)) ) ) (foreach folder (vl-directory-files Path "*" -1) (if (not (or (= folder ".") (= folder ".."))) (AddFileToList (strcat Path "C:\\" folder) Str) ) ) ) ) EndList ) (princ) Thank you for the help. Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 Some questions: 1) What type of files are you searching for? 2) Do you want to search only a single folder, or all subfolders? 3) What will the default path be? I.e. start in the current drawing folder, or a specific folder? 4) You said you want to "load" them. Does that mean open a drawing, load a DLL file, or what? Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 DLLs and Lisps are the type of files to search. Ideally it would be one folder, maybe subfolders in the future. The default path would be C:\AutoCAD\Tools\ As for loading, I just mean where it loads it into the current drawing. I hope that helps more. Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 (edited) @rcb007 Give this a try - I threw it together using some great functions from Lee Mac's Library. After you load it, Type FSEARCH to start the command. Note - minimally tested and no error handling. EDIT: Note - this starts a "Browse for Folder" dialog starting in the search path you noted. you can change the path or just select "OK" to search in the default path. If you don't want the dialog at all, just comment out the line "(setq spth (LM:browseforfolder "Select Search Folder" spth 0))". EDIT2: I've updated the code to be a more generalized version that you can easily change the file type pattern. Note how many extension types can be loaded as a LISP file. I am also using some more advanced techniques to filter the file list. Someone else here may be able to do this more efficiently, but I enjoyed playing around with it. EDIT3: I forgot to add "(vl-load-com)" since I was using Visual LISP; now added to the code. EDIT4: Removed case sensitivity by forcing everything to uppercase. EDIT5: Masked the non-case sensitive search and show the original files in the results list. ;; Browse for Folder - Lee Mac ;; Displays a dialog prompting the user to select a folder. ;; msg - [str] message to display at top of dialog ;; dir - [str] [optional] root directory (or nil) ;; bit - [int] bit-coded flag specifying dialog display settings ;; Returns: [str] Selected folder filepath, else nil. (defun LM:browseforfolder ( msg dir bit / err fld pth shl slf ) (setq err (vl-catch-all-apply (function (lambda ( / app hwd ) (if (setq app (vlax-get-acad-object) shl (vla-getinterfaceobject app "shell.application") hwd (vl-catch-all-apply 'vla-get-hwnd (list app)) fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir) ) (setq slf (vlax-get-property fld 'self) pth (vlax-get-property slf 'path) pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth)) ) ) ) ) ) ) (if slf (vlax-release-object slf)) (if fld (vlax-release-object fld)) (if shl (vlax-release-object shl)) (if (vl-catch-all-error-p err) (prompt (vl-catch-all-error-message err)) pth ) ) ;; List Box - Lee Mac ;; Displays a DCL list box allowing the user to make a selection from the supplied data. ;; msg - [str] Dialog label ;; lst - [lst] List of strings to display ;; bit - [int] 1=allow multiple; 2=return indexes ;; Returns: [lst] List of selected items/indexes, else nil (defun LM:listbox ( msg lst bit / dch des tmp rtn ) (cond ( (not (and (setq tmp (vl-filename-mktemp nil nil ".dcl")) (setq des (open tmp "w")) (write-line (strcat "listbox:dialog{label=\"" msg "\";spacer;:list_box{key=\"list\";multiple_select=" (if (= 1 (logand 1 bit)) "true" "false") ";width=50;height=15;}spacer;ok_cancel;}" ) des ) (not (close des)) (< 0 (setq dch (load_dialog tmp))) (new_dialog "listbox" dch) ) ) (prompt "\nError Loading List Box Dialog.") ) ( t (start_list "list") (foreach itm lst (add_list itm)) (end_list) (setq rtn (set_tile "list" "0")) (action_tile "list" "(setq rtn $value)") (setq rtn (if (= 1 (start_dialog)) (if (= 2 (logand 2 bit)) (read (strcat "(" rtn ")")) (mapcar '(lambda ( x ) (nth x lst)) (read (strcat "(" rtn ")"))) ) ) ) ) ) (if (< 0 dch) (unload_dialog dch) ) (if (and tmp (setq tmp (findfile tmp))) (vl-file-delete tmp) ) rtn ) (defun c:FSearch (/ flst kstr loadlst pat spth sstr) (vl-load-com) (setq spth "C:\\AutoCAD\\Tools" pat (list "LSP" "MNL" "FAS" "VLX" "DLL") ) (if (and (setq kstr (getstring "\nEnter a Keyword to Search for <ENTER for *>: ")) (setq kstr (if (= kstr "") "*" (strcase kstr))) (setq spth (LM:browseforfolder "Select Search Folder" spth 0)) (setq flst (vl-sort (vl-directory-files spth "*" 1) '<)) ) (if (and flst (setq sstr (vl-string-right-trim "," (apply 'strcat (mapcar '(lambda (x) (strcat "*" kstr "*." x ",")) pat)))) (setq flst (vl-remove-if '(lambda (y) (= y nil)) (mapcar '(lambda (x)(if (wcmatch (strcase x) sstr) x)) flst))) (setq Loadlst (LM:listbox "Select Files to Load" flst 1)) ) (foreach f loadlst (cond ((wcmatch (strcase (vl-filename-extension f)) "`.LSP,`.MNL,`.FAS,`.VLX") (load (strcat spth "\\" f) (strcat "\n\"" f "\" Failed to Load.")) ) ((= f ".DLL") (command "._netload" (strcat spth "\\" f)) ) ) ) (princ (strcat "\nNo files found for the specific types with the Keyword \"" kstr "\".")) ) ) (princ) ) Edited December 1, 2022 by pkenewell Added clarification, Update Code 1 Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 Thank you much. This is what I was looking at. One question with the search. When I use the (*) wildcard, it shows all file names in the folder. Is there a setting I can take off the case sensitivity? I noticed I had to type the word in exactly as the file name. (i.e. dview, would not show, but DView would because that is how it is in the file name). Again, thank you! Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 @rcb007 No problem. Updated code in original post. I used the (strcase) function to force everything to be returned in uppercase. Give it a try. Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 lol. Thanks alot. Besides the Files are all Caps in the dialog box. lol, The search works just like it should! Thank you again. Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 (edited) @rcb007 LOL you are right. I have corrected this with another update to the original post; to mask the "non-case sensitive" search into the background and just show the original files in the results. Try the update and let me know. Edited December 1, 2022 by pkenewell 1 Quote
BIGAL Posted December 1, 2022 Posted December 1, 2022 (edited) Why would you not use a search method like this. Old fashioned menu, just use notepad to make. Edited December 1, 2022 by BIGAL Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 Just tried it out, but saw something I do not have. (setq spth (vl-filename-directory (findfile "pjk-utils.lsp")) and then an error on stringp C:FSEARCH Command: fsearch ; error: bad argument type: stringp nil Command: Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 BigAl, there are ALOT of files. I thought a keyword approach was easier than creating a pull down menu where the user still needs to look for what they want. 1 Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 3 minutes ago, rcb007 said: Just tried it out, but saw something I do not have. (setq spth (vl-filename-directory (findfile "pjk-utils.lsp")) and then an error on stringp C:FSEARCH Command: fsearch ; error: bad argument type: stringp nil Command: OOPS! I had my own path in it for testing and forgot to remove it when I reposted. Original post corrected. Try it again. Quote
BIGAL Posted December 1, 2022 Posted December 1, 2022 (edited) A keyword has at least a 1st Character A-Z so that is 26 menu's of around 20+ lisps. Or group the lisps via subject like the plot has 5 lisps. You can have more than one pop menu dedicated to your lisps. I worked with multiple staff and they would not know the key word to look for, past maybe a couple of characters. At least with a menu you can quickly search another menu group. Its like digital help if you don't know the correct word to look for you get no help. That image has around 200 lisps plus about 400 block inserts. Edited December 1, 2022 by BIGAL 1 Quote
rcb007 Posted December 1, 2022 Author Posted December 1, 2022 Got it! You rock! Thank you again. 1 Quote
pkenewell Posted December 1, 2022 Posted December 1, 2022 8 minutes ago, BIGAL said: A keyword has at least a 1st Character A-Z so that is 26 menu's of around 20+ lisps. Or group the lisps via subject like the plot has 5 lisps. I worked with multiple staff and they would not know the key word to look for, past maybe a couple of characters. At least with a menu you can quickly search another menu group. Its like digital help if you don't know the correct word to look for you get no help. @BIGAL Your idea has merit as well, even though personally I would go for a whole update to the CUI with ribbon, toolbar, etc. However - I found this could be useful for loading, for example, my extended Lisp library of example code, in which I have 935 files currently. I can search for stuff that is useful for learning and testing, but don't need it loaded for everyday use. That would be ALOT of menu items to put in notepad for an mnu file. (Although - personally when I am testing, I just open the explorer window and drag-n-drop the files into my AutoCAD window easy enough LOL.) Quote
BIGAL Posted December 2, 2022 Posted December 2, 2022 When coding I use drag and drop a lot or just copy and paste. My Notepad++ had the Active X plugin which allows you to run the code in N++ by just typing a command "N++" in CAD, well worth looking into. Unfortunately mine has stopped working after doing a software upgrade. A menu of select a block via slides I made by getting all block names and write out the mnu code. Then paste into the actual mnu. Did like 5 types with around 20 slides per type. Yes Toolbars can be made easy only hiccup is a ICON is needed. The ribbon is a difficult beast as you have to use the CUI to make, you can actually look inside and see how they are made but they are a XML group of files, it is on my to do list one day making from say a csv text file. Copy a CUIX then rename to .ZIP then have a look. 1 Quote
Recommended Posts
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.