Jump to content

Leaderboard

  1. mhupp

    mhupp

    Trusted Member


    • Points

      24

    • Posts

      2,230


  2. SLW210

    SLW210

    Moderator


    • Points

      19

    • Posts

      11,614


  3. BIGAL

    BIGAL

    Trusted Member


    • Points

      16

    • Posts

      20,091


  4. rlx

    rlx

    Trusted Member


    • Points

      11

    • Posts

      2,267


Popular Content

Showing content with the highest reputation since 04/27/2026 in all areas

  1. ;;; QSS - Quick String Search Rlx 5/'26 ;;; Just a basic string search engine, primarily meant for text based files like lsp & txt files + dwg files (dbx) ;;; Some files are read as stream so maybe it also works for other file types ... bucketlist material. ;;; On my home computer text search in total commander stopt working so decided to do it myself. ;;; Also Total commander was removed from my work computer. I allready lispify some other ;;; Total Commander functions like copy, move & rename but those live in my batch program. ;;; Main use for me is sometimes I remember making a lisp but not remembering how I named it or where I saved it. ;;; At moment of writing this app is still in beta. (defun C:QSS ( / ;;; globals OldErr regkey regvar sysvar-names sysvar-old-values total-file-list hit-list qss-open-dwg-on-your-way-out fn ;;; object dbx / RegExp actApp actDoc actDocs actLay actDbx AllOpen RegExp ;;; Excel xlApp xlWorkbooks xlWorkbook xlSheets ;;; registry QSS-Search-Folder ;;; String - Folder where lisp files are placed QSS-Include-Subfolders ;;; Toggle - "0" scan only search folder, "1" also scan subfolders QSS-Filename-Extension-Filter ;;; String - delimited by , like "lsp,txt" QSS-Search-String-Filter ;;; String - delimited by | like "Rlx|Dragon" QSS-Case-Sensitive ;;; Toggle - "0" don't care, "1" case sensitive search QSS-Whole-Words-Only ;;; Toggle - "0" find every part, "1" only find whole words ;;; dialog QSS-Main-Dialog-fn QSS-Main-Dialog-fp QSS-Main-Dialog-id MainDialog-tl MainDialog-rd ) (QSS_init) (QSS_exit) (if (and qss-open-dwg-on-your-way-out (setq fn (findfile qss-open-dwg-on-your-way-out)))(_ShellOpen fn)) ) ;--- Init ------------------------------------------------- Begin Init Section --------------------------------------------------- Init --- (defun QSS_Init () ; initialize error handling (setq OldErr *error* *error* QSS_Err) ; backup & set system variables (not realy used here, just added for template purposes) (setq sysvar-names (list (cons 'cmdecho 0)) sysvar-old-values (mapcar '(lambda (x)(getvar (car x))) sysvar-names)) (mapcar '(lambda (x)(setvar (car x) (cdr x))) sysvar-names) ;;; init registry variables (InitDefaultRegistrySettings)(ReadSettingsFromRegistry) ;;; lets go girls (QSS_Main_Dialog_Start) ) (defun QSS_Err ($s) (princ $s)(QSS_Exit)(setq *error* OldErr)(princ)) (defun QSS_Exit () ; cleanup dialog(s) (I use list for future use in case of more dialogs) (mapcar '(lambda (x) (if (not (null x)) (unload_dialog x))) (list QSS-Main-Dialog-fn)) (mapcar '(lambda (x) (if (not (null x)) (close x))) (list QSS-Main-Dialog-fp)) (mapcar '(lambda (x) (if (and (not (null x)) (findfile x)) (vl-file-delete x))) (list QSS-Main-Dialog-fn)) ; reset system variables (not realy used here just for future / template purposes) (mapcar '(lambda (x y)(setvar (car x) y)) sysvar-names sysvar-old-values) (term_dialog) (gc) (princ "\nDone") (terpri) (princ) ; release actDbx & RegExp (foreach obj (list actDbx RegExp) (vl-catch-all-apply 'vlax-release-object (list obj))) ;;; release Excel (Exit_Excel) ) ;;; ------------------------------------------------------ End of Init Section ------------------------------------------------------------ ;;; --- Registry Settings ------------------------------- Begin Registry Settings ------------------------------- Registry Settings --- ;;; (defun InitDefaultRegistrySettings () (setq regkey "HKEY_CURRENT_USER\\SOFTWARE\\QSS\\") ;;; regkeys must be strings ("variable name" "default value") (setq regvar (list '("QSS-Search-Folder" "") ;;; String - Folder where lisp files are placed '("QSS-Include-Subfolders" "0") ;;; Toggle - "0" scan only search folder, "1" also scan subfolders '("QSS-Filename-Extension-Filter" "lsp,txt,dwg") ;;; String - delimited by , (comma) like "lsp,dwg" '("QSS-Search-String-Filter" "") ;;; String - delimited by | (Pipe) like "Rlx|Dragon" '("QSS-Case-Sensitive" "0") ;;; Toggle - "0" don't care, "1" case sensitive search '("QSS-Whole-Words-Only" "0") ;;; Toggle - "0" nope , "1" jip ) ) (mapcar '(lambda (x)(set (read (car x)) (cadr x))) regVar) ) (defun ReadSettingsFromRegistry () (mapcar '(lambda (x / n v) (if (setq v (vl-registry-read regkey (setq n (car x)))) (set (read n) v) (vl-registry-write regkey n (cadr x)))) regvar)) (defun WriteSettingsToRegistry () (mapcar '(lambda (x) (vl-registry-write regkey (car x) (eval (read (car x))))) regvar)) ;;; --- Registry Settings -------------------------------- End Registry Settings -------------------------------- Registry Settings --- ;;; ;;; --- dialog section ----------------------------------- begin dialog section ------------------------------------ dialog section --- ;;; ; SaveDialogData evaluates all vars from %tl and returns them as a list, reset does the opposite (defun Save_Dialog_Data (%tl) (mapcar '(lambda (x) (eval (car x))) %tl)) (defun Reset_Dialog_Data (%tl %rd) (mapcar '(lambda (x y) (set (car x) y)) %tl %rd)) (defun Set_Dialog_Tiles (%tl) (mapcar '(lambda (x / v) (if (eq 'str (type (setq v (eval (car x))))) (set_tile (cadr x) v))) %tl)) (defun Main_Dialog_Cancel () (Reset_Dialog_Data MainDialog-tl MainDialog-rd) (WriteSettingsToRegistry)) (defun QSS_Main_Dialog_Create () (if (and (setq main-dialog-fn (vl-filename-mktemp "Main.dcl")) (setq main-dialog-fp (open main-dialog-fn "w"))) (mapcar '(lambda (x)(write-line x main-dialog-fp)) (list "QSS : dialog {label=\"QSS - Quick String Search (RLX May 2026)\";" ":boxed_column {label=\"Search folder :\";" ":row {:edit_box {key=\"eb_search_folder\";}" ":button {fixed_width=true;width=12;key=\"bt_select_search_folder\";label=\"Select\";}}" ":toggle {label=\"Include subfolders\";key=\"tg_include_subfolders\";}}" ":boxed_row {label=\"Filename Extension Filter [ , ]\"; :edit_box {key=\"eb_filename_extension_filter\";}}" ":boxed_column {label=\"Search string filter [ | ]\";" ":edit_box {key=\"eb_search_string_filter\";}" ":row {:toggle {label=\"Case sensitive\";key=\"tg_case_sensitive\";}" " :toggle {label=\"Whole words only\";key=\"tg_whole_words_only\";}}}" "spacer;" ":concatenation {gap; :image {height=1.5;width=91;key=\"the_bar\";color=dialog_background;}gap;}" "spacer;ok_cancel;spacer;" "}" "gap:image {fixed_width=true;width=0.001;color=dialog_background;}" ) ) ) (if main-dialog-fp (close main-dialog-fp))(gc) ) (defun QSS_Main_Dialog_Start ( / drv ) (if (null main-dialog-fn)(QSS_Main_Dialog_Create)) (if (and (setq main-dialog-dcl (load_dialog main-dialog-fn)) (new_dialog "QSS" main-dialog-dcl)) (progn (QSS_Main_Dialog_Update) (QSS_Main_Dialog_Action) (setq drv (start_dialog)) (cond ((= drv 0)(Main_Dialog_Cancel)) ((= drv 1)(WriteSettingsToRegistry)(QSS_DoIt)) ((= drv 2)(WriteSettingsToRegistry)(Show_Hit_List)) ) ) ) (if main-dialog-fn (vl-file-delete main-dialog-fn)) (setq main-dialog-fn nil) ) (defun QSS_Main_Dialog_Update () (setq MainDialog-tl '((QSS-Search-Folder "eb_search_folder") (QSS-Include-Subfolders "tg_include_subfolders") (QSS-Filename-Extension-Filter "eb_filename_extension_filter") (QSS-Search-String-Filter "eb_search_string_filter") (QSS-Case-Sensitive "tg_case_sensitive") (QSS-Whole-Words-Only "tg_whole_words_only") ) ) ;;; rd = reset data (val1 val2 ...) , in case of a cancel store original values before start of dialog (if (null MainDialog-rd) (setq MainDialog-rd (Save_Dialog_Data MainDialog-tl))) ;;; set edit boxes and toggle values (Set_Dialog_Tiles MainDialog-tl) ) (defun QSS_Main_Dialog_Action () (mapcar '(lambda (x)(action_tile (car x) (cadr x))) '(("cancel" "(done_dialog 0)") ;("accept" "(done_dialog 1)") ("accept" "(QSS_Pre_Scan)") ("eb_search_folder" "(setq QSS-Search-Folder $value)") ("bt_select_search_folder" "(QSS_select_search_folder)") ("tg_include_subfolders" "(setq QSS-Include-Subfolders $value)") ("eb_filename_extension_filter" "(setq QSS-Filename-Extension-Filter $value)") ("eb_search_string_filter" "(setq QSS-Search-String-Filter $value)") ("tg_case_sensitive" "(setq QSS-Case-Sensitive $value)") ("tg_whole_words_only" "(setq QSS-Whole-Words-Only $value)") ) ) ) (defun QSS_select_search_folder ( / f) (if (setq f (GetShellFolder "Select search folder"))(set_tile "eb_search_folder" (setq QSS-Search-Folder f)))) ;;; first handle the file & folder stuf side of things (defun QSS_Pre_Scan ( / subfolder-flag case-flag filename-extension-filter-list search-string-filter-list folder-list tmp-l) ;;; make sure include subfolders and case-sensitive flags are either T or nil (if (not (eq QSS-Include-Subfolders "1")) (setq subfolder-flag nil) (setq subfolder-flag T)) (if (not (eq QSS-Case-Sensitive "1")) (setq case-flag nil) (setq case-flag T)) ;;; check all parameters (cond ;;; verify search folder ((not (folder-p QSS-Search-Folder)) (alert (strcat "Invalid search folder : " (vl-princ-to-string QSS-Search-Folder)))) ;;; verify filename filter (like "lsp,dwg") -> pimpext -> ("*.lsp" "*.dwg") ((or (void QSS-Filename-Extension-Filter) (not (vl-consp (setq tmp-l (SplitStr QSS-Filename-Extension-Filter ",")))) (not (vl-every '(lambda (s) (wcmatch s "*`.*")) (setq filename-extension-filter-list (pimpex tmp-l))))) (alert (strcat "Bad filename filter : " (vl-princ-to-string QSS-Filename-Extension-Filter)))) ;;; verify search string filter ((or (void QSS-Search-String-Filter) (not (vl-consp (setq search-string-filter-list (SplitStr QSS-Search-String-Filter "|"))))) (alert (strcat "Invalid search string : " (vl-princ-to-string QSS-Search-String-Filter)))) ;;; maybe do file list check here (t ;;; show something wonderfull is about to happen (clear_bar)(set_tile "the_bar" " working...") (if (eq QSS-Include-Subfolders "1") (setq folder-list (QSS_FindSubfolders QSS-Search-Folder)) (setq folder-list (list QSS-Search-Folder))) ;;; just a little delay to enjoy the view, exterminate when it gets anoying (wait 1.5) (setq total-file-list (QSS_FindFiles folder-list filename-extension-filter-list)) (wait 1.5) (if (not (vl-consp total-file-list)) (alert (strcat "no files found :\nFolder : " (vl-princ-to-string QSS-Search-Folder) "\nFilter : " (vl-princ-to-string filename-extension-filter-list))) (QSS_Process_Total_File_List) ) );;; end t );;; end cond );;; end defun ;;; clear previous status (defun clear_bar () (start_image "the_bar")(fill_image 0 0 (dimx_tile "the_bar") (dimy_tile "the_bar") 141)(end_image)) (defun Show_Hit_List () (if (vl-consp hit-list) (dplm+ hit-list (strcat "Number of files found : " (itoa (length hit-list)))) (alert "Sorry search returned no results"))) (defun QSS_Process_Total_File_List ( / stream pattern file-count n l hit) (set_tile "the_bar" (strcat "Number of files to search : " (setq n (itoa (length total-file-list))))) (setq file-count 0 pattern QSS-Search-String-Filter) (if (eq QSS-Case-Sensitive "1")(setq ignoreCase nil)(setq ignoreCase T)) (foreach fn total-file-list ;;; split here for different types of extensions ;;; lisp & text files can be read by stream , dwg by odbx ;;; (strcase (last (fnsplitl "c:\\temp\lisp\acad.dwg")) t) -> ".dwg" (setq ext (strcase (last (fnsplitl fn)) t)) ;;; for now only *.lsp, *.txt & *.dwg, ;;; bucketlist xls/xlsx & pdf but they may need different approach or 3rd party software, so low priority (cond ((wcmatch ext "*`.lsp,*`.txt") (if (and (setq stream (_ReadStream fn 0)) (setq rtn (= (vlax-invoke (InitRegExp pattern ignoreCase nil) 'Test stream) -1)) (not (member fn hit-list))) (setq hit-list (cons fn hit-list)))) ;;; regex_string_search last parameter is for return as list ;;; if T -> return all strings in doc as list, if nil -> return nil or filename if pattern is found ((wcmatch ext "*`.dwg") (if (and (setq dbx-doc (odbx_open fn)) (setq hit (regex_string_search dbx-doc pattern nil))) (setq hit-list (cons fn hit-list)))) ;;; excel : Scan_Excel returns T or nil if regex pattern is found ((wcmatch ext "*`.xls,*`.xlsx") (if (and (Scan_Excel fn) (not (member fn hit-list))) (setq hit-list (cons fn hit-list)))) ) ;;; length of hit-list (setq l (itoa (length hit-list))) ;;; clear previous status (clear_bar) ;;; update status message (set_tile "the_bar" (strcat " ( " (setq *spin* (Spinbar *spin*)) " ) Scanning files [" (itoa file-count) " of " n "] - found " l)) ;;; increase file counter (setq file-count (1+ file-count)) ) (done_dialog 2) ) ;;; --- dialog section ------------------------------------ end dialog section ------------------------------------- dialog section --- ;;; ;--- + + + --------------------------------------------- Begin of tiny lisp section --------------------------------------------- + + + --- (defun void (x) (or (not x) (= "" x) (and (eq 'STR (type x)) (not (vl-remove 32 (vl-string->list x)))))) (defun wait (sec / stop)(setq stop (+ (getvar "DATE") (/ sec 86400.0)))(while (> stop (getvar "DATE")))) (defun string-p (s) (if (= (type s) 'str) t nil)) (defun folder-p (f) (if (and (= (type f) 'str) (vl-file-directory-p f)) t nil)) ;;; (Dos_Path (strcat (getvar "dwgprefix") (getvar "dwgname"))) -> "C:\\USERS\\ROB\\DOCUMENTS\\ACAD\\QUICKSTRINGSEARCH.DWG\\" (defun Dos_Path ($p) (if (= (type $p) 'STR) (strcase (strcat (vl-string-right-trim "\\" (vl-string-translate "/" "\\" $p)) "\\")) "")) ;;; (vl_path (strcat (getvar "dwgprefix") (getvar "dwgname"))) -> "c:/users/rob/documents/acad/quickstringsearch.dwg/" (defun vl_path ($p)(if (= (type $p) 'str) (strcat (vl-string-right-trim "\\/" (strcase (vl-string-translate "\\" "/" $p) t)) "/") "")) ; generic getfolder routine with possibility to create a new subfolder (GetShellFolder "select path") (defun GetShellFolder ( m / f s) (if (and (setq s (vlax-create-object "Shell.Application")) (setq f (vlax-invoke s 'browseforfolder 0 m 0 "")))(setq f (vlax-get-property (vlax-get-property f 'self) 'path)) (setq f nil))(vl-catch-all-apply 'vlax-release-object (list s)) (if f (strcat (vl-string-right-trim "\\" (vl-string-translate "/" "\\" f)) "\\"))) ; returns T if no errors occurred during program execution (defun _ShellOpen ( $f / it sh ) (if (and (not (void $f)) (setq $f (findfile $f)) (setq sh (vla-getInterfaceObject (vlax-get-acad-object) "Shell.Application"))) (progn (setq it (vl-catch-all-apply 'vlax-invoke (list sh 'open $f)))(vlax-release-object sh)(not (vl-catch-all-error-p it))) (progn (prompt "\nShell application was unable to open file")(setq it nil)))) ;;; d = directory , e = extension like "*.dwg" , f = flag include subfolders (any value or nil) ;;; test : (length (alf "d:/temp/lisp" "*.dwg" t)) (length (alf "d:/temp/lisp" "*.dwg" nil)) ;;; (setq l (alf "c:/temp/lisp" "*.xlsx" t)) (setq l (alf "c:\\temp\\lisp\\" "*.txt" t)) (defun alf (d e f) (setq d (vl-string-right-trim "/" (vl-string-translate "\\" "/" d))) (if f (apply 'append (cons (if (vl-directory-files d e)(mapcar '(lambda (x) (strcat d "/" x)) (vl-directory-files d e))) (mapcar '(lambda (x) (alf (strcat d "/" x) e f))(vl-remove ".." (vl-remove "." (vl-directory-files d nil -1)))))) (mapcar '(lambda (x) (strcat d "/" x))(vl-directory-files d e 1)))) ;;; (SplitStr "a,b,c" ",") -> ("a" "b" "c") (defun SplitStr (s d / p) (if (setq p (vl-string-search d s))(cons (substr s 1 p)(SplitStr (substr s (+ p 1 (strlen d))) d))(list s))) ;;; (lst->csv '("a" "b" "c") "|") -> "a|b|c" (defun lst->csv (%l $s) (apply 'strcat (cdr (apply 'append (mapcar (function (lambda (x) (list $s x))) %l))))) ;;; (sandwich '("a" "b" "c") "*") -> '("*a*" "*b*" "*c*") ;;; for whole word search each string in regex string has to begin and end with \\b (defun sandwich (%l %c) (mapcar '(lambda (s)(strcat %c s %c)) %l)) ;;; make sure each extension begin with *. (pimpex (splitstr "lsp,dwg" ",")) -> ("*.lsp" "*.dwg") (defun pimpex (%l) (mapcar '(lambda (s)(strcat "*." (vl-string-trim "*." s))) %l)) ; choose from list (cfl '("1" "2" "3")) (defun cfl (l / f p d r) (and (setq p (open (setq f (vl-filename-mktemp ".dcl")) "w")) (princ "cfl:dialog{label=\"Choose\";:list_box{key=\"lb\";width=40;}ok_cancel;}" p) (not (setq p (close p)))(< 0 (setq d (load_dialog f)))(new_dialog "cfl" d) (progn (start_list "lb")(mapcar 'add_list l)(end_list)(action_tile "lb" "(setq r (nth (atoi $value) l))(done_dialog 1)") (action_tile "accept" "(setq r (get_tile \"lb\"))(done_dialog 1)")(action_tile "cancel" "(setq r nil)(done_dialog 0)") (start_dialog)(unload_dialog d)(vl-file-delete f))) (cond ((= r "") nil)(r r)(t nil))) ;;; display list (plus message) (defun dplm (l m / f p d w) (and (vl-consp l) (setq l (mapcar 'vl-princ-to-string l)) (setq w (+ 5 (apply 'max (mapcar 'strlen l)))) (setq p (open (setq f (vl-filename-mktemp ".dcl")) "w")) (princ (strcat "cfl:dialog{label=\"" m "\";:list_box {key=\"lb\";" "width="(itoa w)";}ok_only;}") p)(not (setq p (close p)))(< 0 (setq d (load_dialog f)))(new_dialog "cfl" d)(progn (start_list "lb") (mapcar 'add_list l)(end_list)(action_tile "accept" "(done_dialog)")(start_dialog)(unload_dialog d)(vl-file-delete f)))) ;;; possibility to load / save the list and ShellOpen selection (defun dplm+ (l m / load_list save_list open_item f p d w pick) (defun load_list ()(alert "Under construction : Load List")) (defun save_list ()(alert "Under construction : Save List")) (defun open_item ( / i f)(if (and (vl-consp l)(not (null pick))(setq i (atoi pick))(setq f (nth i l))(setq f (findfile f))) (cond ((wcmatch (strcase (last (fnsplitl f)) t) "*.dwg")(setq qss-open-dwg-on-your-way-out f)(done_dialog))(t (_ShellOpen f))))) (if (not (vl-consp l)) (setq l (list "No results")) (setq l (mapcar 'vl-princ-to-string l))) ;;; make width dialog based on longest string in list (setq w (+ 5 (apply 'max (mapcar 'strlen l)))) (setq p (open (setq f (vl-filename-mktemp ".dcl")) "w")) (write-line (strcat "cfl:dialog{label=\"" m "\";") p) (write-line (strcat ":list_box {key=\"lb\";width=" (itoa w) ";height=25;}") p) (write-line (strcat ":column {:row {fixed_width=true;alignment=centered; :button {key=\"bt_load\";label=\"Load\";}" ":button {key=\"bt_save\";label=\"Save\";} :button {key=\"bt_open\";label=\"Open\";}}}") p) (write-line "ok_only;}" p) (if p (close p)) (if (and (< 0 (setq d (load_dialog f))) (new_dialog "cfl" d)) (progn (start_list "lb")(mapcar 'add_list l)(end_list) (action_tile "accept" "(done_dialog)") (action_tile "lb" "(setq pick $value)") (action_tile "bt_load" "(load_list)") (action_tile "bt_save" "(save_list)") (action_tile "bt_open" "(open_item)") (start_dialog) (unload_dialog d) (vl-file-delete f) ) ) ) ;--- + + + ---------------------------------------------- End of tiny lisp section ---------------------------------------------- + + + --- ;;; --- Odbx ---------------------------------------------- Begin Odbx Section ----------------------------------------------- Odbx --- ;;; (defun GetAllOpenDocs () (or actApp (setq actApp (vlax-get-acad-object))) (or actDoc (setq actDoc (vla-get-ActiveDocument actApp))) (or actDocs (setq actDocs (vla-get-documents actApp))) (vlax-for doc actDocs (if (= 1 (vlax-variant-value (vla-getvariable doc "DWGTITLED"))); no nameless drawings (setq AllOpen (cons (cons (strcase (vla-get-fullname doc)) doc) AllOpen)))) ) (defun _ReleaseAll () (mapcar '(lambda(x) (if (and (= 'vla-object (type x)) (not (vlax-object-released-p x))) (vlax-release-object x))(set (quote x) nil)) (list actLay actDoc actDocs actApp actDbx))(gc)) (defun _ReleaseAll () (mapcar '(lambda(x) (if (and (= 'vla-object (type x)) (not (vlax-object-released-p x))) (vlax-release-object x))(set x nil)) (list 'doc 'actLay 'actDoc 'actDocs 'actApp 'actDbx))(gc)) (defun _InitObjectDBX ()(or actApp (setq actApp (vlax-get-acad-object))) (or actDoc (setq actDoc (vla-get-ActiveDocument actApp)))(or AllOpen (setq AllOpen (GetAllOpenDocs))) (setq actDbx (vl-catch-all-apply 'vla-getinterfaceobject (list actApp (dbx_ver)))) (if (or (null actDbx)(vl-catch-all-error-p actDbx))(progn (princ "\nObjectDbx not available")(setq actDbx nil))) actDbx ) (defun odbx_open ( $dwg / _pimp doc) (or AllOpen (GetAllOpenDocs)) (defun _pimp (s) (strcase (vl-string-trim " ;\\" (vl-string-translate "/" "\\" s)))) (cond ((or (void $dwg) (not (findfile $dwg)))(princ "\nInvalid drawing")(setq doc nil)) ((not (or actDbx (_InitObjectDBX)))(princ "\nObjectDbx not available")(setq doc nil)) ((setq doc (cdr (assoc (_pimp $dwg) AllOpen)))) ((vl-catch-all-error-p (vl-catch-all-apply 'vla-Open (list actDbx (findfile $dwg)))) (princ "\nUnable to open drawing.")(setq doc nil)) (t (setq doc actDbx))) doc ) (defun odbx_close ( %doc ) (if (and (= 'vla-object (type %doc)) (not (vlax-object-released-p %doc)))(progn (vlax-release-object %doc))(setq %doc nil))) (defun dbx_ver ( / v) (strcat "objectdbx.axdbdocument" (if (< (setq v (atoi (getvar 'acadver))) 16) "" (strcat "." (itoa v))))) ;;; little test function to find all strings (txt/att etc) in all drawings in a folder (defun c:test1 ( / actDoc actDocs actApp actDbx RegExp dbx-doc write_result show_result search-folder dwg-list rtn result-list search-pattern result-list-fn) ;;; init vl functions, odbx & regexp (vl-load-com) (_InitObjectDBX) (or RegExp (setq RegExp (vlax-create-object "VBScript.RegExp"))) (defun write_result (lst fn / fp) (cond ((not (vl-consp lst)) (alert "Computer says no : empty result list, nothing to write")) ((or (not (= (type fn) 'STR)) (not (setq fp (open fn "w")))) (alert (strcat "unable to write to : " (vl-princ-to-string fn)))) ;;; format lst : ( ("dwgname1" . ("str1" "str2" ...)) ...) (t (write-line (strcat "Scanned " (itoa (length lst)) " drawings\n") fp) (foreach item lst (write-line (car item) fp) (foreach str (cdr item) (write-line (vl-princ-to-string str) fp)) (write-line "\n--\n" fp) ) ) ) (if fp (progn (close fp)(gc)(gc))) (princ) ) (defun show_result (fn) (if (and fn (setq fn (findfile fn))) (startapp "notepad" fn) (alert (strcat "Computer says no : unable to read from : " (vl-princ-to-string fn))) ) (princ) ) (setq search-pattern "*" result-list-fn "C:\\Temp\\QuickStringSearchResult.txt") (cond ;;; hard coded for test, could be replaced with something like : ;;; ((not (or (vl-file-directory-p (setq search-folder "C:\\Temp\\Lisp\\")) ;;; (setq search-folder (getfolder "Folder for string search"))))" ;;; (alert (strcat "computer says no : invalid folder : " search-folder))) ((not (vl-file-directory-p (setq search-folder "C:\\Temp\\Lisp\\"))) (alert (strcat "Folder " search-folder " does not exist - change folder"))) ((not (vl-consp (setq dwg-list (vl-directory-files search-folder "*.dwg")))) (alert (strcat "No dwg files in " search-folder))) (t ;;; if return-as-list is T regex_string_search returns all strings else T or nil if pattern is found (setq return-as-list T) (foreach dwg dwg-list (if (setq dbx-doc (odbx_open dwg)) (if (vl-consp (setq rtn (regex_string_search dbx-doc search-pattern return-as-list))) (setq result-list (cons (cons dwg rtn) result-list))) (princ (strcat "\nUnable to open " dwg)) ) ) (_ReleaseAll) ) ) ;;; release RegExp (if (= 'vla-object (type RegExp))(vlax-release-object RegExp)) (if (vl-consp result-list) (progn (write_result result-list result-list-fn) (show_result result-list-fn)) (princ (strcat "\nNo text was found in dwg files in " (vl-princ-to-string search-folder))) ) (princ) ) ;;; doc = duh , pat = duh , ral = return as list , if T return all strings , if nil test for pattern and return nil or T (defun regex_string_search (doc pat ral / pat-p pattern ingnoreCase global blocks objName textStr atts result s tableRow tableCol) ;;; not realy needed because als called in test function (or RegExp (setq RegExp (vlax-create-object "VBScript.RegExp"))) ;;; *** still to do create regex version, not sure pat-p is working as intended ;;; test if pattern is found in list of strings (RegExp needs to be initialized) (defun pat-p (p l) (vl-some (function (lambda (s)(= (vlax-invoke-method RegExp 'Test s) :vlax-true))) l)) ;;; *** still to do : apply ignore case / whole words only to pattern ;;; alternative : (lwcmatch "M-16427" '("As built K-16886.pdf" "As built M-16427.pdf" "As built N-16260.pdf")) (defun lwcmatch ( p l / r ) (foreach x l (if (vl-string-search p x)(setq r (cons x r)))) r) ;;; (re)init regex pattern (QSS-Search-String-Filter) is something like "Fikkie|Rlx" (setq pattern QSS-Search-String-Filter global T) (if (eq QSS-Case-Sensitive "1")(setq ignoreCase nil)(setq ignoreCase T)) (InitRegExp pattern ignoreCase global) ;;; go through all document objects and retrieve textstring, return as list or test with regex (pat-p) (setq blocks (vla-get-blocks doc)) (if (/= pat "") (progn (vlax-for block blocks (vlax-for obj block (setq objName (vlax-get-property obj 'ObjectName)) (setq textStr nil) ;;; Filter objects & get textString (cond ;; Text en MText ((vl-position objName '("AcDbText" "AcDbMText")) (setq textStr (vlax-get-property obj 'TextString))) ;; Old Leaders & Dimensions ((vl-position objName '("AcDbLeader" "AcDbDimension" "AcDbRotatedDimension" "AcDbAlignedDimension")) (if (vlax-property-available-p obj 'TextOverride) (setq textStr (vlax-get-property obj 'TextOverride)))) ;; Modern MultiLeaders (MLeader) ((= objName "AcDbMLeader") (if (= (vlax-get-property obj 'ContentType) 2) ; 2 = acMTextContent (setq textStr (vlax-get-property obj 'TextString)))) ;; Block Reference with Attributes ((= objName "AcDbBlockReference") (if (= (vlax-get-property obj 'HasAttributes) :vlax-true) (progn (setq atts (vlax-invoke obj 'GetAttributes)) (foreach attObj atts (setq s (vlax-get-property attObj 'TextString)) (if (and s (/= s "")) ;(= (vlax-invoke-method RegExp 'Test pat) :vlax-true)) (progn (setq textStr (cons (strcat "Block " (vlax-get-property obj 'Name) ", Tag : " (vlax-get-property attObj 'TagString) ", Text : " s) textStr)))) ) ) ) ) ;; Tabellen (Scant elke cel afzonderlijk) ((= objName "AcDbTable") (setq tableRow 0) (while (< tableRow (vlax-get-property obj 'Rows)) (setq tableCol 0) (while (< tableCol (vlax-get-property obj 'Columns)) (setq s (vlax-invoke obj 'GetText tableRow tableCol)) (if (and s (/= s "")); (= (vlax-invoke-method regex 'Test textStr) :vlax-true)) (setq textStr (cons (strcat "Table [Row " (itoa tableRow) ", Col " (itoa tableCol) "]: " s) textStr))) (setq tableCol (1+ tableCol)) ) (setq tableRow (1+ tableRow)) ) ) ) ;;; end cond ;;; put result in list (cond ((null textStr)) ((vl-consp textStr) (foreach x textStr (setq result (cons x result)))) (t (setq result (cons textStr result))) ) ) ;;; vlax-for block ) ;;; vlax-for blocks ) ;;; end progn ) ;;; end if (/= pat "") ;;; if ral = T return all strings as list else only return T if pattern is found in result list ;;; *** still to do replace lwcmatch with regex version (pat-p) ;(if ral result (lwcmatch pat result)) (if ral result (pat-p pattern result)) ) ;;; --- Odbx ---------------------------------------------- End Odbx Section ------------------------------------------------- Odbx --- ;;; ;;; --- RegExp -------------------------------------------------- RegExp --------------------------------------------------- RegExp --- ;;; ;;; Separate multiple patterns by pipe-operator | ;;; (vlax-put-property regexp "Pattern" "Rlx|CadTutor|Visual Lisp") ;;; Whole words only (not "Rlxie" when searching for "Rlx"): ;;; (vlax-put-property regexp "Pattern" "\\bRlx\\b|\\bCadTutor\\b|\\bVisual Lisp\\b") ;;; pattern : Pattern to search. ;;; ignoreCase : If non nil, the search is done ignoring the case. ;;; global : If non nil, search all occurences of the pattern, if nil, only searches the first occurence. (defun InitRegExp (pattern ignoreCase global) (or RegExp (setq RegExp (vlax-create-object "VBScript.RegExp"))) (vlax-put RegExp 'Pattern pattern) (if ignoreCase (vlax-put RegExp 'IgnoreCase acTrue)(vlax-put RegExp 'IgnoreCase acFalse)) (if global (vlax-put RegExp 'Global acTrue)(vlax-put RegExp 'Global acFalse)) RegExp ) ;;; len : Number of bytes to read. If non numeric, < 1 or greater than the number of bytes in file everything is returned. ;;; iomode : 1 = read, 2 = write, 8 = append , format : 0 = ascii, -1 = unicode, -2 = system default (defun _ReadStream ( path len / fso file stream result ) (vl-catch-all-apply '(lambda ( / iomode format size ) (setq iomode 1 format 0 fso (vlax-create-object "Scripting.FileSystemObject") file (vlax-invoke fso 'GetFile path) stream (vlax-invoke fso 'OpenTextFile path iomode format) size (vlax-get file 'Size) len (if (and (numberp len) (< 0 len size)) (fix len) size) result (vlax-invoke stream 'read len)) (vlax-invoke stream 'Close) ) ) (if stream (vlax-release-object stream))(if file (vlax-release-object file))(if fso (vlax-release-object fso)) result ) ;;; T if pattern is found else nil (defun c:test2 ( / fn pattern stream ignoreCase rtn) (setq fn "C:\\Temp\\Lisp\\RlxBatch.lsp") (setq ignoreCase T) (setq pattern "-publish") ;(setq pattern "dragon") (and (= (type fn) 'STR) (setq fn (findfile fn)) (setq stream (_ReadStream fn 0)) (setq rtn (= (vlax-invoke (InitRegExp pattern ignoreCase nil) 'Test stream) -1)) ) rtn ) ;;; --- RegExp -------------------------------------------------- RegExp --------------------------------------------------- RegExp --- ;;; ;;; --- Excel ---------------------------------------------------- Excel ---------------------------------------------------- Excel --- ;;; (defun Init_Excel () (or xlApp (setq xlApp (vlax-get-or-create-object "Excel.Application"))) (vla-put-visible xlApp :vlax-false) ) (defun Exit_Excel () (if xlApp (progn (vl-catch-all-apply 'vlax-invoke-method (list xlWorkbook 'Close :vlax-false)) ;(vlax-invoke-method xlWorkbook 'Close :vlax-false) ;;; close workbook without saving ;(vlax-invoke-method xlApp 'Quit) ;;; may want to skip this because it closes all workbooks (vlax-release-object xlSheets) ;;; ok to release (vlax-release-object xlWorkbook) ;;; ok to release (vlax-release-object xlApp) ;;; ok to release ) ) ) ;;; create range letters "A1:" + Letter & number like "A1:Z10" (defun _cl (i / n) (if (< i 27)(chr (+ 64 i))(if (= 0 (setq n (rem i 26))) (strcat (_cl (1- (/ i 26))) "Z")(strcat (_cl (/ i 26))(chr (+ 64 n)))))) ;;; retrieve all values from Excel workbook (defun Scan_Excel (fn / f xlUsedRange rows xlValue _safearray tmp-lst result excel-range excel-used-range excel-max-row excel-max-column excel-max-range excel-variant excel-value excel-to-list l2 l3 pattern ignoreCase global) ;;; just to make sure regex is up and running (or RegExp (setq RegExp (vlax-create-object "VBScript.RegExp"))) ;;; test if pattern is found in list of strings (RegExp needs to be initialized) (defun pat-p (p l) (vl-some (function (lambda (s)(= (vlax-invoke-method RegExp 'Test s) :vlax-true))) l)) ;;; (re)init regex pattern (QSS-Search-String-Filter) is something like "Fikkie|Rlx" (setq pattern QSS-Search-String-Filter global T) (if (eq QSS-Case-Sensitive "1")(setq ignoreCase nil)(setq ignoreCase T)) (InitRegExp pattern ignoreCase global) (if (and fn (string-p fn) (setq f (findfile fn))) (progn (Init_Excel) (setq xlWorkbooks (vlax-get-property xlApp 'Workbooks)) (setq xlWorkbook (vlax-invoke-method xlWorkbooks 'Open f)) (setq xlSheets (vlax-get-property xlWorkbook 'Sheets)) (vlax-for xlSheet xlSheets (setq xlUsedRange (vlax-get-property xlSheet 'UsedRange)) ;;; Set limits on number of rows, not sure what size would be to much for AutoCad to handle (setq rows (vlax-get-property (vlax-get-property xlUsedRange 'Rows) 'Count)) (if (< rows 500000) (progn ;(setq xlValue (vlax-get-property xlUsedRange 'Value)) ;(setq _safearray nil tmp-lst nil) ;(if (= (type xlValue) 'variant) (setq _safearray (vlax-variant-value xlValue))) ;(if (= (type _safearray) 'safearray) (setq tmp-lst (vlax-safearray->list _safearray))) (and (setq excel-variant (vlax-get-property xlUsedRange 'Value)) (setq excel-value (vlax-variant-value excel-variant)) (setq excel-to-list (vlax-safearray->list excel-value)) (setq tmp-lst (vl-remove nil (mapcar '(lambda (x) (vl-remove nil (mapcar '(lambda (y / val) (setq val (vl-catch-all-apply 'vlax-variant-value (list y))) (if (vl-catch-all-error-p val) nil val) ) x) ) ) excel-to-list ) ) ) (setq result (append result tmp-lst)) ) ) (princ (strcat "\nSkipped " (vl-filename-base fn) " Tab '" (vlax-get-property xlSheet 'Name) "' : to many rows (" (itoa rows) ").")) ) (vlax-release-object xlUsedRange) (vlax-release-object xlSheet) ) (vlax-invoke-method xlWorkbook 'Close :vlax-false) ) ) ;;; merge list of lists ( (...) (...) ...) -> (... ... ...) -> (setq l2 (apply 'append result)) ;;; make sure all elements are string -> (setq l3 (mapcar 'vl-princ-to-string l2)) ;;; test if pattern is found in result list , returns T or nil (if (vl-consp result) (pat-p pattern (mapcar 'vl-princ-to-string (apply 'append result)))) ) ;(setq l2 (apply 'append (mapcar '(lambda (x)(mapcar '(lambda (y)(append x y)) a)) b))) (defun c:test3 () (if (Scan_Excel "c:/temp/test.xlsx") (alert "Pattern found in c:/temp/test.xlsx") (alert "Pattern found in c:/temp/test.xlsx"))) ;;; --- Excel ---------------------------------------------------- Excel ---------------------------------------------------- Excel --- ;;; ;;; -------------------------------------------------- Begin of Progress Bar Section ------------------------------------------------------ ; (setq lst (acad_strlsort (QSS_FindSubfolders "c:/temp/lisp"))) (defun QSS_FindSubfolders ( d / l r s msg ) (setq l (list d)) (while l (setq s nil)(foreach d l (setq s (append s (mapcar (function (lambda ( x ) (strcat d "/" x))) (vl-remove-if (function (lambda (x)(member x '("." ".."))))(vl-directory-files d nil -1))))))(setq r (append s r) l s) (start_image "the_bar")(fill_image 0 0 (dimx_tile "the_bar") (dimy_tile "the_bar") 131)(end_image) (setq msg (strcat " ( " (setq *spin* (Spinbar *spin*))" ) Scanning for subfolders : " (itoa (length r)))) (set_tile "the_bar" msg) ) ;;; make sure sourcefolder is part of result (cons d r) ) ;;; (setq rtn (QSS_FindFiles '("c:/temp/lisp") '("*.lsp" "*.txt"))) (defun QSS_FindFiles (folder-list extension-list / folder result result-list status) ;;; folder-list is list of all (sub)folders to scan , make sure all folders end with "/" (setq folder-list (acad_strlsort (mapcar 'vl_path folder-list))) (foreach folder folder-list (foreach ext extension-list (if (vl-consp (setq result (mapcar '(lambda (x) (strcat folder x))(vl-directory-files folder ext 1)))) (setq result-list (append result-list result)) ) ) ;;; clear previous status (start_image "the_bar")(fill_image 0 0 (dimx_tile "the_bar") (dimy_tile "the_bar") 141)(end_image) ;;; update status message (setq status (strcat " ( " (setq *spin* (Spinbar *spin*)) " ) Scanning for files : " (itoa (length result-list)))) (set_tile "the_bar" status) ) result-list ) ; funny little indicator found in StripMtext.lsp ;(princ (strcat "\r (" (setq s (Spinbar s)) ") Files : " (itoa (setq i (1+ i))) "\t\t")) (defun SpinBar (spin) (cond ((= spin "\\") "|") ((= spin "|") "/") ((= spin "/") "-") (t "\\"))) ;;; ---------------------------------------------------- End of Progress Bar Section -------------------------------------------------- ;;; (princ "\nRlx May'26 - Type QSS for main function or test1 for test function (all text from all dwgs in c:/temp/lisp/") Most info included in lisp file. Just a quick string search for lsp, txt & dwg files. App is still in beta and hasn’t been field tested yet. Still working on the ignore case & whole word options. IT killed my Total Commander so had to write my own search engine Start with QSS , select folder , extension like lsp,dwg and search string like Rlx Type in extensions like lsp,txt (with comma) and for text use pipe symbol like Rlx|Dragon for now only lsp,txt and dwg are supported , haven't been able to make it work on pdf Result is shown in list box. You can select item and open. If item is lsp or txt , notepad will start. If item is dwg , app stops and opens dwg (load and save buttons not working yet, not sure I need them.
    6 points
  2. @PaulyPHI Give this a try.SetPlineZ_Updated.lsp
    4 points
  3. Indeed, if the block has attributes, (entmod) becomes more complicated: it requires going through transformation matrices and applying them to the attributes. The move command would be simpler... Here is the mhupp code adapted for proper operation: Merits to Mhupp for his code ;;----------------------------------------------------------------------------;; ;; Modify Text or Blocks to align Horozontal or Vertical ;; https://www.cadtutor.net/forum/topic/99091-i-need-a-lisp-to-align-blocks-and-texts-vertically/ (defun C:ATB () (C:AlignTextBlock)) (defun C:AlignTextBlock (/ vars vals pt1 pt2 vector mode ent ed pt newpt) (vl-load-com) (setq vars '(OSMODE ORTHOMODE) vals (mapcar 'getvar vars) ) (mapcar 'setvar vars '(0 1)) (setq pt1 (getpoint "\nAlignment Point: ")) (setq pt2 (getpoint pt1 "\nSelect Horozontal or Vertical:")) (setq vector (mapcar '- pt2 pt1)) (if (eq (car Vector) 0.0) (setq mode 'V) (setq mode 'H)) (while (setq ss (ssget '((0 . "TEXT,INSERT")))) (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) (setq ed (entget ent) pt (cdr (assoc 10 ed)) newpt (if (eq mode 'V) (list (car pt1) (cadr pt) (caddr pt)) (list (car pt) (cadr pt1) (caddr pt))) ) (vla-Move (vlax-ename->vla-object ent) (vlax-3d-point pt) (vlax-3d-point newpt)) ; (if (or (not (assoc 11 ed)) (eq (cdr (assoc 11 ed)) '(0.0 0.0 0.0))) ;test if 11 doesnt exist or is 0,0,0 ; (setq ed (subst (cons 10 newpt) (assoc 10 ed) ed)) ; (setq ed (subst (cons 11 newpt) (assoc 11 ed) ed)) ; ) ; (entmod ed) ) ) (mapcar 'setvar vars vals) (princ) ) (princ "\nAlignTextBlock Lisp Loaded") (princ "\nType ATB or AlignTextBlock to run command")
    4 points
  4. Very quickly try these changes: (setq alpty (cadr alpt)) ---> (setq alptx (car alpt)) (setq newpt (list inptx alpty)) --> (setq newpt (list alptx inpty))
    3 points
  5. Welcome. To make a cleaner look I would make a master Chart (or multiple BH SW MW or by area with a box around them) with all the relative call outs. this would allow a larger view of the area. eliminate the use/need of leaders that aren't really doing anything but cluttering the drawing. -edit Then updating would be adding borehole location and adding to the chart.
    2 points
  6. Don't know what is going on about Textexp but here is a favour for you. I just made A-Z 0-9 exploded. Convert to correct plines then can extrude into a solid say 1 unit high, will need to check the 36 shapes. The sample dwg really needs more thought say text size =1 and height equal say 0.1. It took about 10 minutes to make these. With a bit of practice much faster and use other fonts. You can use presspull to change height. BUT SET TEXT HEIGHT CORRECT BEFORE EXTRUDE. Oh yeah why do you have units set to Architectural when your talking mm ? new block.dwg
    2 points
  7. Ok I used Txtexp on "MACEY", then went to a 3d view so could see what was going on VPOINT -1,-1,-1. You have to check that all the objects that appear are plines I had to join the little "A" triangle. Ok extruded the base 1.5 Extruded the circles 2.5, then unionid both, to base, subtracted the inner circle from the new solid. Extruded the ""M" 4.5 then did a union again. Extruded the two parts of the "A" unioned together with base then subtracted the inner triangle, You can see the progress. What you want is not a single step but rather multiple steps, lastly can export the STL file. Once you get the hang of extruding, subtrcat and union you can do multiple objects at one time. This is a bit rough as a solid and can be done better, by moving the text to a Z matching base height before you start.
    2 points
  8. The equal linetype as supplied is just a dashed linetype that has a length of one unit and a gap of one unit. By setting its LTSCALE to the length of a pipe you can get an idea of the number of pipes involved. I have somewhere also convert an existing line to two lines as per right hand image, The GIS used to dump out a single line on a size layer so we wanted 2 dashed lines to imply existing drainage. Will try to find I think that is what you want.
    2 points
  9. This code is so helpful to convert texts or mtexts to mleader. In the attachments the lisp file and cad file that has the problem I tied to solve. The cad file contains a huge amounts of elevations as texts and leaders that are exploded for landscape work , therefore this lisp can help with case like this Regards TBC- JOIN TEXT AND POLYLINES AND CONVERT THEM TO MLEADER OR MAKE IT MANUALLY.lsp BR FIN LVLS-1.dwg
    2 points
  10. Before I used this : (defun GetFolder ( m / f s) (if (and (setq s (vlax-create-object "Shell.Application")) (setq f (vlax-invoke s 'browseforfolder 0 m 65536 "")))(setq f (vlax-get-property (vlax-get-property f 'self) 'path)) (setq f nil))(vl-catch-all-apply 'vlax-release-object (list s)) f) (defun wait (sec / stop)(setq stop (+ (getvar "DATE") (/ sec 86400.0)))(while (> stop (getvar "DATE")))) (defun findstring ( / a b c d e) (setq a (GetFolder "Select folder for string search")) (setq b (getstring "\nEnter string to search for : " T)) (setq c (getstring "\nFile extension (lsp) : ")) (if (eq c "") (setq c "lsp")) (setq d (strcat a "\\result.txt")) (setq e (strcat "findstr /i /s \"" b "\" " a "\\*." c " > " d)) (command "shell" e) (gc)(gc) ;;; natural delay for system to clear cache and write file to disk (alert "search completed") (startapp "notepad" d) (princ) ) (defun c:dfs ()(findstring)) (defun c:t1 ()(findstring)(princ)) This code only works for text based files. Have updated code in my first post with Excel support. Valid extensions are now lsp , txt , dwg , xls and xlsx I have a license for able2extract on my home computer and also written something that uses pdfattach and import for readable pdf's. Though I can take that route, it's not like shoot & forget , often more than one step is needed. But it is what it is... most pdf's I get are pretty poor quality , some by accident and some not because a 3rd party wants you as a returning client if you know what I mean.
    2 points
  11. I meant to mention adding the (\U+200A). IIRC it's called a nonbreaking space. "Hairspace" sounds better IMO. I didn't try this, but one article mentioned to "Save As" or "Export to" PDF to kill the hyperlinks. My AutoCAD 2026 has the option to check Include Hyperlinks under PDF Options on the plot manager.
    2 points
  12. ah yes. https://www.cadtutor.net/forum/topic/98598-just-a-funny-basic-toolbar/
    2 points
  13. Try this also. Seemed to work and makes a vector list code of objects. VECTORIZE.lsp
    2 points
  14. That would be The Dragon, RLX maybe? He had a menu but not sure if that is the one you're thinking off? (I was impressed but been too busy this year to get into using it)
    2 points
  15. Didn't someone have a lisp that created a menu system in model space ? on the right side of the current view.
    2 points
  16. Still starting from the mhupp code, I think this corresponds to your request: align all the blocks to the position of a block. Same for text or mtext. (defun C:ABC ( / vars vals ss ssref pt_ref pt2 vector mode ent ed pt newpt) (vl-load-com) (setq vars '(OSMODE ORTHOMODE) vals (mapcar 'getvar vars) ) (mapcar 'setvar vars '(0 1)) (princ "\nSelect Block or Texte.") (while (null (setq ss (ssget '((0 . "*TEXT,INSERT")))))) (princ "\nSelect ONE texte or block to align selection") (while (null (setq ssref (ssget "_+.:E:S" '((0 . "*TEXT,INSERT")))))) (setq pt_ref (cdr (assoc 10 (entget (ssname ssref 0))))) (setq pt2 (getpoint pt_ref "\nSelect Horozontal or Vertical:")) (setq vector (mapcar '- pt2 pt_ref)) (if (eq (car Vector) 0.0) (setq mode 'V) (setq mode 'H)) (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) (setq ed (entget ent) pt (cdr (assoc 10 ed)) newpt (if (eq mode 'V) (list (car pt_ref) (cadr pt) (caddr pt)) (list (car pt) (cadr pt_ref) (caddr pt))) ) (vla-Move (vlax-ename->vla-object ent) (vlax-3d-point pt) (vlax-3d-point newpt)) ) (mapcar 'setvar vars vals) (princ) )
    2 points
  17. I Just try to avoid using command. apparently their is a bug in autocad 2026 and newer that balloons lisp to 276 seconds when it only took .24 second in older versions. just figured everything contained in the block id would move when updating. cant test right but does adding the 66 . 0 exclude single text outside of blocks? vla-move works for me keep it simple.
    2 points
  18. @mhupp If you want to keep (entmod) in your code and make it efficient, you can refine your filter (ssget) to exclude blocks with attributes. (setq ss (ssget '((0 . "TEXT,INSERT") (66 . 0))))
    2 points
  19. notice your lisp name is MoveLayerAllLayouts that mean other tabs other than model? ssget "_X" wont pick up things on other tabs if they are on that layer. So if your moving everything might assume your deleting the old layer. if that's the case just rename it. no need to mess with ssget and will pick up everything. (vl-cmdf "_.-Rename" "LA" old new)
    2 points
  20. Using @BIGAL suggestion for ssget to only pick up text and blocks set in a while loop so you can align multiple things to the same axis. also added a visual to choose between horizontal or vertical alignment. AlignT&B.lsp
    2 points
  21. After quickly looking into this... Unchecking the box is equal to no limit. Had a little time at work so... quickly tested. ;;; Uncheck the Max leader points in the Multileader Style dialog box. (or set a value). | ;;; | ;;; https://www.cadtutor.net/forum/topic/99083-looking-for-lisp-to-uncheck-max-leader-points-for-all-mleader-styles/#findComment-678964 | ;;; | ;;; By SLW210 (a.k.a. Steve Wilson) | ;;; | ;;;*************************************************************************************************************************************| ;;;*************************************************************************************************************************************| (defun c:UnchkMLdrPnts (/ acApp doc dict obj) (vl-load-com) (setq acApp (vlax-get-acad-object)) (setq doc (vla-get-ActiveDocument acApp)) (setq dict (vla-Item (vla-get-Dictionaries doc) "ACAD_MLEADERSTYLE")) (vlax-for obj dict (if (vlax-property-available-p obj 'MaxLeaderSegmentsPoints) (vla-put-MaxLeaderSegmentsPoints obj 0) ;; 0 = unlimited ) ) (princ "\nMax leader points box is unchecked.") (princ) )
    2 points
  22. @darshjalal Nice work! Your added Automatic mode, and the code to strip numbers out of the text is over and above!
    1 point
  23. @PaulyPHI Here is a quick walk-though: This uses Visual LISP to pull the text string from the selected object and convert it to a real number. See the added comments below. (if (and ;; Logical AND = All conditions must be met. ;; 1) an object must be selected. (setq es (entsel "\nSelect Text Object: ")) ;; 2) The selected object must have a text string property, i.e. TEXT, MTEXT, ATTRIBUTE, MLEADER, etc. (vlax-property-available-p (vlax-ename->vla-object (car es)) 'TextString) ;; 3) Retrieve the textsting value if the above conditions are met. (setq newZ (vla-get-textstring (vlax-ename->vla-object (car es)))) ;; 4) The textstring value must evaluate to greater than 0 when converted to a real number. This only works if the text is numerical. (> (setq newZ (atof newZ)) 0.0) ) ;; if all conditions are met, then continue to the (progn) block that performs the changes.
    1 point
  24. Like I stated, I still like leaning on AutoCAD for making things for the 3D printer, but also learning Blender and playing with TinkerCAD, etc. The main goal is getting nice 3D Prints, I can tell you from experience, the stuff you get from online, supposedly ready to print, sometimes needs a little tweaking or outright re-modeled. I also have been learning to work in the 3D printer software, in my case, Bambu Studio, it's a lot easier cleaning up, scaling, adding text, etc. right before slicing. Like anyone that uses tools to do a job, learning what tools to use, how to use them, when to use what, etc. is usually the best way to go forward, it's a learning process. By all means start with AutoCAD and improve, we are here to help. Do you know how to export to STL and import that into your slicer?
    1 point
  25. I messed around a little with tinker cad but figured since I already had some knowledge of AutoCAD that it would probably be more useful to stick with AutoCAD. as I mentioned above, I just started learning AutoCAD in November of last year through Penn Foster (don't hold that against me. I'm basically teaching myself at this point with the help of you fellas).
    1 point
  26. Well, I just started learning AutoCAD in November of last year through Penn Foster (don't hold that against me. I'm basically teaching myself at this point with the help of you fellas). I didn't realize you could set the text height BEFORE you press pull. I just started the press/pull then typed the number I want. As far as architectural, I'll be honest, that's all we used when I was in college so that's all I really know
    1 point
  27. Did you try doing these in TinkerCAD? Not sure why your have issues with exploding the text in AutoCAD, I'll look when I get back to work tomorrow. Even as you describe it "When I tried txtexp it shot the text way off to the left and made it huge", you just have to move it and scale it. What you really want to do is learn to do this with the 3D Printer tools. https://www.youtube.com/watch?v=9McpK4nNf2k
    1 point
  28. Thank you very much sir, works perfect. I have compared the modified text file to the original and my brain just melted.... i can see some text that makes sense but the rest is just gobldee goop to me.... I'm just not programmed to understand it... Thank you once again.
    1 point
  29. Sorry it took so long to get back. I never got notifications that there were any replies. OK, so maybe I'm missing something here and ChatGPT and Gemini are of zero help so far. I have this drawing. I'm trying to make a 3d printed ATV number plate. Extrude absolutely won't work for me, not sure why. I was able to use the "presspull" command to punch out the holes (which I don't believe is the correct way) and I can raise the plate up the 3mm I want and the support around the holes the additional 1mm I want but it absolutely won't do anything with the text. I tried MTEXT and single line text. Neither works My printer is a FlashForge AD5X Mark Macey Rear Plate.dwg
    1 point
  30. PETA-INSERT ELEVATIONS FROM TEXTS INSIDE THE CLOSED OR OPEN POLYINE.LSP Try this one too
    1 point
  31. What 3D printer do you have? I just recalled, there used to be an APP at the Autodesk APP store, but no longer there, works on older AutoCAD, but it is also posted here at CADTutor and the Swamp. I use Bambu Labs and it comes with Bambu Studio which has a 3D Text that is very easy, I can do a custom name plate with text directly on the machine.
    1 point
  32. Taking your example video this is convert a p/line to a drainage pipe written for civil road works, with most common AUS sizes. Needs linetype Equal the length of dashed is set to 2.4 which is a length of a concrete pipe. Handy for civil works. It is not dynamic. *EQUAL,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ A,1.0,-1.0 Pipe offsets.lsp If you post here a VLR function can test. Fillet offset circle.lsp Have a look at "Fillet offset circle" uses reactors.
    1 point
  33. If the text is Searchable in the PDF. Windows Explorer will work. if the PDF is just an image then it wont work and have to use Adobe's OCR to convert them to be searchable. -Edit Tho not 100% some stuff come in weird like fractions or text between white space and pictures.
    1 point
  34. Yeah , well , I'm afraid to tempt 'the Gods' how much worse it can get haha. Big reorganization on its way and we hope things can only get better , but that's maybe tempting fate In the mean while got it working (I think) for excel workbooks too , but gonna have to post that later when I get home tonight. Clippy (the AI) told me without external programs like Adobe or pdf2text , its very unlikely I'm gonna be able to directly retrieve strings from a pdf. Since I cant install any software other than provided by the company that's not gonna happen. Only way would be pdfimport and pdfshx but that would defeat the purpose of this appie.
    1 point
  35. Nice work IT! They got you to spend hours trying to circumvent the limitations they forced upon their employees just to make it workable.
    1 point
  36. I have moved your post to a new thread ARES Commander LISP not Working in the AutoLISP, Visual LISP & DCL Forum. Please use Code Tags for posted code in the future. (<> in the editor toolbar) Where did you get the LISP and what does it do? Do other LISPs run in your Ares Commander? What does not work? Do you have the Visual Studio Code and the Graebert LISP Extension for troubleshooting the LISP?
    1 point
  37. I also used to use theDOS thing , but its not nearly as sexy : (sorry , <> has been disabled by my work , file upload as well and if I try to use a bat file admin locks me down) Will post tonight
    1 point
  38. "Why Use TXTEXP? 3D Extrusion: Converts text into line/polyline paths that you can use the EXTRUDE command on." So to use extrude you must have closed shapes it can take a few minutes to properly close the exploded text. When using extrude you should set a height that you want.
    1 point
  39. The work flow makes the copying of the texts to attribute block so quick> Regards CONVERT TEXTS TO ATTRIBUTE WORK FLOW-COMP.mp4 GTTB-BATCH-COPY ANY NUMBER OF TEXTS TO ATTRIB BLOCKS.LSP rec2txt-placing a specific object (like a .lsp H B2 FINISHS - ATT-2.dwg
    1 point
  40. Need a link https://autolispprograms.wordpress.com/water-supply-2/
    1 point
  41. See if this program by @Tharwat is suitable for you...
    1 point
  42. I can't get your examples to show as hyperlinks in Acrobat Pro or opening with MS Edge at work. If I create a hyperlink in AutoCAD, it shows as hyperlink in Adobe Pro and MS Edge, so not being blocked by Adobe Pro or AutoCAD. See if these show as hyperlinks on your reader. PDF_Hyperlink 3.pdf PDF_Hyperlink 2.pdf PDF_Hyperlink.pdf
    1 point
  43. I'll try that shortly and see if that works. PDF options didn't do much - mostly I think it is a PDF viewer thing (got into a whole word of space names yesterday, EM-space, EN-space, half EM, quarter EM... and so on depends on the website, never knew there were so many 'spaces')
    1 point
  44. Incredible: it seems that (GC) works! I think I last used this command on a 486! Thank you very much!
    1 point
  45. Thanks SLW210 for looking for me, a font of all knowledge
    1 point
  46. The project specifications are limiting us to Arial font, and a set format for the text strings. It isn't a CAD issue but a PDF reader issue - and we cannot control what others use to look at files. So not a lot we can actually do with the plotting to make it behave as it should unfortunately. So many texts that start with the format qwe.rty.uio..... are seen as hyperlinks in the PDF. Our work around - for anyone following this - is to use 'hairspace' after the '.' (\U+200A) which you can see is there if you know it is there else so far works.
    1 point
  47. A few comments. You have not put your name and date to code, say add at that start. You can write direct to Excel rather than opening a csv. Can help with that. You can replace the Initget with the attached. Multi radio buttons.lsp Other methods available also. Same with the "point markers" Multi toggles.lsp Also for input values strings or numbers Multi GETVALS.lsp if (not AH:Butts)(load "Multi radio buttons.lsp")) ; loads the program if not loaded already (if (= but nil)(setq but 1)) ; this is needed to set default button (setq lst (list "Please choose" "1-Pts" "2-Pl" "3-3DPl" "4-Cir" "5-Arc" "6-Blk" "7-Ln" "8-Spl" "9-FL" "10-All")) (setq ans (ah:butts but "V" lst)) All 3 options can be made into a single DCL.
    1 point
  48. Haven't been on AutoCAD for a while. maybe try GC command to free up memory might help. use mem at the start when its nice and fast and when it is starting to slow down. https://help.autodesk.com/view/ACDLT/2026/ENU/?caas=caas/documentation/ACD/2014/ENU/files/GUID-F4AEB953-2117-4BF2-8056-EA1384AC3FFF-htm.html
    1 point
  49. I used SSX to select all objects on the layer "SURVEY NO BOUNDARY". As long as "Optimize segments within polylines" is checked Overkill will fix the existing polylines. As Eldon said "If you run Overkill first, then Extrim will work. But it will only trim the lines crossing the rectangle." It's a routine for trimming not erasing. I use EraseOutsideBoundary to both trim & erase outside: ;| Function to trim objects inside selected boundaries (allows for multiple boundaries) Boundaries can be "Circle, Ellipse, LWPolyline and Polyline" Entities Written By: Peter Jamtgaard Copyright 2015 All Rights Reserved ^C^C^P(or C:BoundaryTrim (load "BoundaryTrim.lsp"));BoundaryTrim EraseOutsideBoundary added by Tom Beauford ^C^C^P(or C:EraseOutsideBoundary (load "BoundaryTrim.lsp"));EraseOutsideBoundary ==============================================================================|; ;(defun C:BT ()(c:BoundaryTrim)) (defun C:BoundaryTrim (/ acDoc intCount ssBoundaries) (if (setq ssBoundaries (ssget (list (cons 0 "Circle,Ellipse,LWPolyline,Polyline")))) (progn (vla-startundomark (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))) (repeat (setq intCount (sslength ssBoundaries)) (setq intCount (1- intCount)) (BoundaryTrim (ssname ssBoundaries intCount)) (BoundaryWindowErase (ssname ssBoundaries intCount)); <-Erase objects inside boundary optional ) ) ) (if acDoc (vla-endundomark acDoc)) ) ; Command line function to select objects that are windowed by a selected circle. (defun C:BoundarySelect (/ lstPoints objBoundary ssBoundary) (if (and (setq ssBoundary (ssget ":E:S" (list (cons 0 "Circle,Ellipse,LWPolyline,Polyline")))) (setq objBoundary (vlax-ename->vla-object (ssname ssBoundary 0))) (setq lstPoints (SegmentPoints objBoundary 360)) ) (and (setq ssSelections (ssget "_WP" lstPoints)) ) ) ) ; Function to trim linework inside a boundary entity (defun BoundaryTrim (entBoundary1 / lstPoints entBoundary1 entBoundary2 lstCenter lstPoints1 lstPoints2 objBoundary1 objBoundary2 ssBoundary *Error*) (defun *Error* () (setvar "cmdecho" intCMDEcho) ) (setq intCMDEcho (getvar "cmdecho")) (setvar "cmdecho" 0) (if (and (setq objBoundary1 (vlax-ename->vla-object entBoundary1)) (setq lstPoints1 (SegmentPoints objBoundary1 360)) (setq lstCenter (mapcar '(lambda (X)(/ (apply '+ X) (length lstPoints1)))(transposematrix lstPoints1))) (vl-cmdf "offset" (/ (distance (car lstPoints1) lstCenter) 36.0) entBoundary1 lstCenter "") (setq entBoundary2 (entlast)) (setq objBoundary2 (vlax-ename->vla-object entBoundary2)) (setq lstPoints2 (SegmentPoints objBoundary2 360)) ) (progn (vl-cmdf "trim" entBoundary1 "" "f") (foreach lstPoint lstPoints2 (vl-cmdf lstPoint)) (vl-cmdf "" "") (entdel entBoundary2) (vl-cmdf "redraw") (setvar "cmdecho" intCMDEcho) ) ) ) ; Function to trim linework outside a boundary entity (defun TrimOutsideBoundary (entBoundary1 / lstPoints entBoundary1 entBoundary2 lstCenter maxpt lstPoints1 lstPoints2 objBoundary1 objBoundary2 ssBoundary *Error*) (defun *Error* () (setvar "cmdecho" intCMDEcho) ) (setq intCMDEcho (getvar "cmdecho")) (setvar "cmdecho" 0) (if (and (setq objBoundary1 (vlax-ename->vla-object entBoundary1)) (setq lstPoints1 (SegmentPoints objBoundary1 360)) (setq lstCenter (mapcar '(lambda (X)(/ (apply '+ X) (length lstPoints1)))(transposematrix lstPoints1))) (setq maxpt (list (1+ (car (getvar 'extmax)))(1+ (cadr (getvar 'extmax)))(1+ (caddr (getvar 'extmax))))) (vl-cmdf "offset" (/ (distance (car lstPoints1) lstCenter) 200.0) entBoundary1 maxpt "") (setq entBoundary2 (entlast)) (setq objBoundary2 (vlax-ename->vla-object entBoundary2)) (setq lstPoints2 (SegmentPoints objBoundary2 360)) ) (progn (vl-cmdf "trim" entBoundary1 "" "f") (foreach lstPoint lstPoints2 (vl-cmdf lstPoint)) (vl-cmdf "" "") (entdel entBoundary2) (vl-cmdf "redraw") (setvar "cmdecho" intCMDEcho) ) ) ) ; Function to erase linework inside a boundary entity (defun BoundaryWindowErase (entBoundary / lstPoints objBoundary ssSelections) (if (and (setq objBoundary (vlax-ename->vla-object entBoundary)) (setq lstPoints (SegmentPoints objBoundary 360)) (setq ssSelections (ssget "_WP" lstPoints)) ) (and (setq ssSelections (ssget "_WP" lstPoints)) (vl-cmdf "erase" ssSelections "") ) ) ) ; Function to determine the points along a curve dividing it intSegments number of times (defun SegmentPoints (objCurve intSegments / sngSegment intCount lstPoint lstPoints sngLength sngSegment) (if (and (setq sngLength (vlax-curve-getdistatparam objCurve (vlax-curve-getendparam objCurve))) (setq sngSegment (/ sngLength intSegments)) (setq intCount 0) ) (progn (repeat (1+ intSegments) (setq lstPoint (vlax-curve-getpointatdist objCurve (* intCount sngSegment))) (setq lstPoints (cons lstPoint lstPoints)) (setq intCount (1+ intCount)) ) lstPoints ) ) ) ; Function to Transpose a matrix (defun TransposeMatrix (lstMatrix) (if (car lstMatrix) (cons (mapcar 'car lstMatrix) (TransposeMatrix (mapcar 'cdr lstMatrix)) ) ) ) ; Function to erase linework outside a boundary entity (defun C:EraseOutsideBoundary ( / ss1 n ssBoundary objBoundary lstPoints ssSelections entSelection) (vla-startundomark (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))) (setq ss1 (ssget "_X" '((67 . 0))) n -1) (if (and (setq ssBoundary (ssget ":E:S" (list (cons 0 "Circle,Ellipse,LWPolyline,Polyline")))) (setq entBoundary (ssname ssBoundary 0)) (ssdel entBoundary ss1) (TrimOutsideBoundary entBoundary) (setq objBoundary (vlax-ename->vla-object entBoundary)) (setq lstPoints (SegmentPoints objBoundary 360)) ) (and (setq ssSelections (ssget "_CP" lstPoints)) (repeat (sslength ssSelections) (setq entSelection (ssname ssSelections (setq n (1+ n)))) (if(ssmemb entSelection ssSelections)(ssdel entSelection ss1)) ) (command "erase" ss1 "") ) ) (if acDoc (vla-endundomark acDoc)) )
    1 point
×
×
  • Create New...