DVDM Posted April 3, 2009 Posted April 3, 2009 Hi all, I have recently discovered the joys acaddoc.lsp, but want to use it a bit smarter than what I’m doing now. I’ve made a routine that will reconcile several layers, and also removes an xref’d image that’s no longer available. Problem is, if these unreconciled layers and xref aren’t there, it will tell you on the command prompt, despite setting cmdecho to 0. While this doesn’t really interfere with anything, it doesn’t look very tidy (Especially the last one, which returns this when Company Logo is not there): No unreconciled layers selected. No unreconciled layers selected. No unreconciled layers selected. No unreconciled layers selected. Unknown command "Company Logo". Press F1 for help. ; error: extra right paren on input This is the code from acaddoc.lsp: (setvar "cmdecho" 0) (command "layer" "reconcile" "A4SHEET*" "") (command "layer" "reconcile" "A3SHEET*" "") (command "layer" "reconcile" "A2SHEET*" "") (command "layer" "reconcile" "A1SHEET*" "") (command "layer" "reconcile" "A0SHEET*" "") (command "layer" "reconcile" "B1SHEET*" "") (command "image" "detach" "Company Logo") (setvar "cmdecho" 1) What I would like to do, is make the routine a bit smarter, so that it only reconciles a layer when it actually needs reconciling, and detach the Company Logo image when the image is there. I have tried things like this, but without much luck: (progn (if tblsearch "layer" "A4SHEET|70") (command "layer" "reconcile" "A4SHEET*" "")) Does anyone know how to get this ‘if’ routine to work? Quote
Lee Mac Posted April 3, 2009 Posted April 3, 2009 This will sort your layer problem : (defun laychk (lay) (if (tblsearch "LAYER" lay) (command "layer" "_reconcile" lay ""))) (mapcar 'laychk '("A4SHEET" "A3SHEET" "A2SHEET" "A1SHEET" "A0SHEET" "B1SHEET")) Quote
Lee Mac Posted April 3, 2009 Posted April 3, 2009 This is all I could think of for the Image detach - Assumes that the file extension is 4 chrs long. i.e. .jpg or .bmp etc etc (defun c:test (/ ss iNme) (if (setq ss (ssget "X" '((0 . "IMAGE")))) (progn (foreach img (mapcar (function (lambda (x) (cdr (assoc 1 x)))) (mapcar (function (lambda (x) (entget (cdr (assoc 340 (entget x)))))) (mapcar 'cadr (ssnamex ss)))) (if (eq "COMPANY LOGO" (strcase (setq iNme (substr img (- (strlen img) 15) 12)))) (command "_-image" "_D" iNme))))) (princ) ) Quote
DVDM Posted April 6, 2009 Author Posted April 6, 2009 Thanks Lee Mac, I modified your layer routine to work for me. In my initial routine I had a wildcard, because it was always a set of layers that needed reconciling. The layers always belong to a drawing border that is xref’d into the drawing, so a list of unreconciled layers would sometimes come up looking like this: A1SHEET|25, A1SHEET|50, A1SHEET|70 etc etc, where 25, 50, 70 are layers in that xref’d drawing. That’s why I initially used A1SHEET* to reconcile this whole set. I tried using a wildcard in the routine you made, but couldn’t get it to work, so instead I just added all variations to the list, and it works great. Would it have been possible to use wildcards in this lisp routine? I was expecting the solution for the missing image reference to be as elegant as the routine you made for the layers, but I guess the problem here is that it’s not possible to do a tblsearch for image references? Your solution looks quite ingenious. I tested it, and it works perfect for drawings with a missing Company Logo.bmp reference. Unfortunately for me however, this is not the actual name of the missing reference. First I replaced ‘Company Logo’ with ‘Xxxxxxx Yyyyyyy Logo’, and adjusted the following string to the correct number of characters in the image name: (substr img (- (strlen img) 23) 20), but without success. Then I realized you assemble the image name by using the mapcar and cdr and cadr functions to build a list using the individual words in the image name? Since in actual fact the image name has 3 words instead of 2, I presume there will have to be a third mapcar ‘caddr function in there for this to work? I had a try, but I’m afraid it’s all a bit out of my league J On a side note: would this routine have been much easier had the image reference not contained any spaces, but underscores instead? Whether or not you can help me out a bit further, I appreciate the help you’ve given me. It's really just a small glitch I'm trying to overcome, but it's always good to learn a few new things along the way. Quote
CarlB Posted April 6, 2009 Posted April 6, 2009 Your modification of Lee's code should have worked even with more spaces in the name. Since the "strcase" function is used, you need to put the image name in all capital letters for it to work. Quote
DVDM Posted April 6, 2009 Author Posted April 6, 2009 I tried that, but nothing. I can't see where I'm going wrong though, because it doesn't return an error either. It just does nothing, with or without all caps. I tested with a Company Logo.bmp that I inserted, and then deleted the file, which works fine when I run the routine. The only difference I see is the status: Not Found vs Unreferenced for the file I'm actually trying to detach. Quote
Lee Mac Posted April 6, 2009 Posted April 6, 2009 Would it have been possible to use wildcards in this lisp routine? I shall try to incorporate a wildcard method for you First I replaced ‘Company Logo’ with ‘Xxxxxxx Yyyyyyy Logo’, and adjusted the following string to the correct number of characters in the image name: (substr img (- (strlen img) 23) 20), but without success. As Carl says, just adjusting the character count and make the (eq "XXX YYY) all caps should work - it is really no different from the original routine. I included the "strcase" as I didn't know whether it was "Company Logo", or "COMPANY LOGO" etc etc... but this would work throughout. The original array of mapcar's just retrieves the whole filename of the image, then the substr just strips out the name from the whole filename. Format the Substr as follows: (eq [color=Red][b]"COMPANY LOGO"[/b][/color] (strcase (setq iNme (substr img (- (strlen img) [b][color=Red]15[/color][/b]) [b][color=Red]12[/color][/b])))) Where, "COMPANY LOGO" is the exact name of the image to be found, all in capitals (spaces and all). 15 is the string length of the image name + 3 12 is the string length (counting spaces as well) Quote
Lee Mac Posted April 6, 2009 Posted April 6, 2009 Not sure if this would work for the reconciling with wildcard. - untested (defun c:laychk (/ wcrds layers reclay) (vl-load-com) (setq wcrds '("A4SHEET*" "A3SHEET*" "A2SHEET*" "A1SHEET*" "A0SHEET*" "B1SHEET*")) (vlax-for lay (vla-get-layers (vla-get-ActiveDocument (vlax-get-acad-object))) (setq layers (cons (vla-get-name lay) layers))) (foreach wc wcrds (setq reclay (vl-remove-if-not (function (lambda (x) (wcmatch x wc))) layers)) (mapcar (function (lambda (x) (command "layer" "_reconcile" x ""))) reclay)) (princ)) Quote
DVDM Posted April 7, 2009 Author Posted April 7, 2009 Reconciling with the wildcard works great! I still can not get the image detach routine to work though, but I have an idea where the problem is. If I detach via the command line manually, detaching works fine whether the status is Not Found or Unreferenced. For the lisp routine however, it does not work for Unreferenced images. I tested it in several ways, and when I have a Not Found reference the routine detaches it just fine, no matter what name and how many words, as you said. If I create an Unreferenced image though, it will not work. Now the question is, what is it about the lisp routine that makes the end result different to what I can do manually from the command line? I mean, really all the routine does is check if that exact image name is there before feeding it to the command line with the image detach command. I have attached a sample file with a Not Found reference Company Logo.bmp The routine works just fine on this. Now delete the reference you can see in modelspace, it becomes Unreferenced, and the routine no longer works. COMPANYLOGOTEST.dwg Quote
Lee Mac Posted April 7, 2009 Posted April 7, 2009 Many thank DVDM - I shall investigate... EDIT: I know why it works with the image in the drawing and not when its deleted - the code works in a way that creates a selection set of all the images in the drawing - hence, if the image isn't there, it won't find it - yet the image definition is still there. Quote
Lee Mac Posted April 7, 2009 Posted April 7, 2009 Here is a shorter code for the image detaching - but it still won't work when the image is deleted. (defun c:imgdel (/ imGLst) (vlax-for Obj (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) (if (eq "AcDbRasterImage" (vla-get-ObjectName Obj)) (setq imGLst (cons (vla-get-Name Obj) imGLst)))) (mapcar '(lambda (x) (command "_-image" "_D" x)) imGLst) (princ (strcat "\n" (itoa (length imGLst)) " Image(s) Detached.")) (princ)) Quote
Lee Mac Posted April 7, 2009 Posted April 7, 2009 You could try this from Wizman: ;|***********************---wiz24MAR09---************************** lisproutine for detaching not_found/unreferenced/orphaned/unloaded images,not yet tested on nested images|; (defun c:imgdet (/ imgpath_lst img_dep img_info img_info340 img_path img_set im_dict im_ent im_ent_1 im_lst im_lst_1 wiz_cnt ) (vl-load-com) ;;;------------------------------------------------------------ ;;List all images which are present in the drawing in var = im_lst_1 (setq img_set (ssget "_x" '((0 . "IMAGE")))) (setq i (sslength img_set)) (while (not (minusp (setq i (1- i)))) (setq im_ent_1 (ssname img_set i)) (setq img_info (entget im_ent_1)) (setq img_info340 (entget (cdr (assoc 340 img_info)))) (setq img_path (cdr (assoc 1 img_info340))) (if (not (member img_path im_lst_1)) (setq im_lst_1 (cons img_path im_lst_1)) ) ;_ {if ) ;_ {while ;;;------------------------------------------------------------ ;;List all images saved in the file_dependencies in var = imgpath_lst (setq imgpath_lst '()) (vlax-for i (setq img_dep (vla-get-FileDependencies (vla-get-ActiveDocument (vlax-get-Acad-Object) ) ;_ {vla-get-ActiveDocument ) ;_ {vla-get-FileDependencies ) ;_ {vla-get-FileDependencies (if (= (vla-get-Feature i) "Acad:Image") (setq imgpath_lst (cons (vl-catch-all-apply (function (lambda () (vla-get-FullFileName i) ) ;_ {lambda ) ;_ {function ) ;_ {VL-CATCH-ALL-APPLY imgpath_lst ) ;_ {cons ) ;_ {setq ) ;_ {if ) ;_ {vlax-for ;(vlax-release-object img_dep) ;;;------------------------------------------------------------ ;;List all images saved in the image_dictionary in var im_lst (setq im_dict (dictsearch (namedobjdict) "ACAD_IMAGE_DICT")) (setq wiz_cnt -1) (setq im_lst '()) (while (setq im_ent (nth (setq wiz_cnt (1+ wiz_cnt)) im_dict ) ;_ {nth ) ;_ {setq (if (eq (car im_ent) 3) (setq im_lst ;_Image list to process below (cons (cons (cdr im_ent) (cdr (nth (setq wiz_cnt (+ wiz_cnt 1)) im_dict ) ;_ {nth ) ;_ {cdr ) ;_ {cons im_lst ) ;_ {cons ) ;_ {setq ) ;_ {if ) ;_ end_while ;;;------------------------------------------------------------ ;;Begin Process ;;Check if im_lst is present in im_lst_1 and imgpath_lst ;; (mapcar (function (lambda (x) (if (or ;;If im_lst is not member of im_lst_1 ;;then it is orphaned/unreferenced (not (member (cdr (assoc 1 (entget (cdr x)))) im_lst_1)) ;;if im_list is not member of imgpath_lst ;;then it is not found (not (member (cdr (assoc 1 (entget (cdr x)))) imgpath_lst ) ;_ {member ) ;_ {not ;;if assoc 280 is 0 then it is unloaded (zerop (cdr (assoc 280 (entget (cdr x))))) ) ;_ {or (vl-catch-all-apply (function (lambda () (vla-delete (vlax-ename->vla-object (cdr x))) ) ;_ {lambda ) ;_ {function ) ;_ {vl-catch-all-apply ) ;_ {if ) ;_ {lamda ) ;_ {function im_lst ) ;_ {mapcar (princ) ) ;_ {defun Quote
DVDM Posted April 8, 2009 Author Posted April 8, 2009 Thanks Lee Mac, I had a quick try with that last routine, and it seems to work well. I haven't had a chance to test it in the acaddoc.lsp yet. Again thanks for all your help! Quote
Lee Mac Posted April 8, 2009 Posted April 8, 2009 Thanks Lee Mac, I had a quick try with that last routine, and it seems to work well. I haven't had a chance to test it in the acaddoc.lsp yet. Again thanks for all your help! No Problem - I had another look at it - but I think Wizmans code is much more than I could ever have thought of 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.