Ryan W Posted August 24, 2023 Posted August 24, 2023 I have been using the CountAttributeValues.lsp and CountDynamicBlocks.lsp from Lee Mac and have tried to make some modifications to these without much success. What I'd like is to get a table from the CountDynamicBlocks.lsp that looks like this (formating is optional for left/right justification): And in the CountAttributeValues.lsp add a count if the item with the name so the table looks like this (formating is optional for left/right justification): I know for the first one, it's how the dotted pair list was made, and I've been unsuccessful in building the lisp to make it usable with his table function added. For the second, there's another layer of logic to get the block name parameter, then build the list with that and the dotted pair values. Any help or point me in the right direction would be greatly appreciated Quote
BIGAL Posted August 25, 2023 Posted August 25, 2023 Ok been answered so many times. Of recent and I need to finish it is what you want. Its done already but adding now the visibility. Its a case of making a list of the blocks getting name or effectivename, get visibility then sorting and counting. To do the answer correctly need a dwg showing the table and blocks, as the way to go is to make a custom table style that matches your dwg. Much easier do it one go rather than repeated changes. Need Visibility name. 1 Quote
Ryan W Posted August 28, 2023 Author Posted August 28, 2023 Thanks. I'm 90% of the way there (I've got it making a table), I just need to reverse the sub list: (("Block" ("vis5" 1) ("vis4" 1) ("vis3" 3) ("vis2" 1) ("vis1" 1))) I need to have it be: (("Block" ("vis1" 1) ("vis2" 1) ("vis3" 3) ("vis4" 1) ("vis5" 1))) So I need to reverse the order and I'm not having luck yet. I'm sure it's stupid easy (I believe I have to reconstruct the list via append, or reverse the list for sub elements). I haven't managed to get it yet, so if I'm missing the glaring obvious, I'd apprecaite the hand up. Thanks, Ryan Quote
BIGAL Posted August 28, 2023 Posted August 28, 2023 You can use (block1 "vis1")((block1 "vis1").......... so a big list then work on that list and it becomes a new list (Block1 "vis1" 3)(Block1 "vis2" 2) etc I use code by Gile to do it, will look for it. Again post a sample dwg. ; By Gile (defun my-count (a L) (cond ((null L) 0) ((equal a (car L)) (+ 1 (my-count a (cdr L)))) (t (my-count a (cdr L)))) ) ; By Gile (defun remove_doubles (lst) (if lst (cons (car lst) (remove_doubles (vl-remove (car lst) lst))) ) ) use something like (setq lst (cons (list bname vis) lst)) The result is lst3 (setq lst (vl-sort lst '(lambda (a b) (cond ((< (car a) (car b))) ((= (car a) (car b)) (< (cadr a) (cadr b))) ) ) ) ) (setq lst3 '()) (setq lst2 (remove_doubles lst)) (foreach val lst2 (setq cnt (my-count val lst)) (setq lst3 (cons (list (nth 0 val)(nth 1 val) cnt) lst3)) ) (setq lst3 (reverse lst3)) Quote
Ryan W Posted August 30, 2023 Author Posted August 30, 2023 Thanks, I'm very close, I have adapted his routine and it creates a table, however it's not including blocks without a visibility state. I'm essentially taking the selected data, creating a new list from the data extracted, and that leaves out the non-visibility states when making the new list. The new list is then passed to a table function and that's all working, except the non-visibility states blocks. I've attached the code and a sample drawing CountDynamicBlocks - Copy (2).lsp Sample DWG.dwg Quote
BIGAL Posted August 31, 2023 Posted August 31, 2023 I did not look at code to hard but if no visibility then still make the list the same as the visibility one use "" as the variable for the visibility name ((Bname1 "" 2)(bname2 "Vis1" 3).....), when making the table if value is "" skip settext. Quote
Ryan W Posted September 5, 2023 Author Posted September 5, 2023 in the code, I'm taking the list that's made with the look through (the variable is lst): (("Block" ("vis1" 1) ("vis2" 1) ("vis3" 3) ("vis4" 1) ("vis5" 1))) and generating a new list (variable tbllst) - to build the table: (foreach blk (setq lst (vl-sort lst '(lambda (a b) (< (car a) (car b))))) (cond ((listp (cadr blk)) (setq tbllst (append tbllst (list (cons (car blk) (itoa (apply '+ (mapcar 'cadr (cdr blk)))) ) ) ) ) (foreach vis (reverse (cdr blk)) (setq tbllst (append tbllst (list (cons (car vis) (itoa (cadr vis)))))) ) ) ) ) Going about it this way, it builds the list for the table in the correct order, but it there is no visibility state (variable VIS), then it skips it So when there is no visibility state, the item just has the block name and a count ("blockname" 3), and doesn't pass that to the tbllst based on the code above. So I know where the issue is, but I cannot seem to get around the fact it gets ignored if there's no visibility states. Quote
BIGAL Posted September 5, 2023 Posted September 5, 2023 If you can make (("Block1" ("vis1" 1) ("vis2" 1) ("vis3" 3) ("vis4" 1) ("vis5" 1)))(("Block2" ("vis1" 1) ("vis2" 1) ("vis3" 3) ("vis4" 1) ("vis5" 1))) Then the table reads the Block1 then the Vis's. (length blk) = 6 so repeat 5 times. If (length is 2 (("Block1" ("" 5)) so do extra check is vis "" for a block with no visibilty and skip that settext. Quote
Ryan W Posted September 6, 2023 Author Posted September 6, 2023 I got it, since its running a conditional, I simply added a (t to the end of the conditional check to add the block with no visibility states...been looking at the damn thing too long (foreach blk (setq lst (vl-sort lst '(lambda (a b) (< (car a) (car b))))) (cond ((listp (cadr blk)) (setq tbllst (append tbllst (list (cons (car blk) (itoa (apply '+ (mapcar 'cadr (cdr blk)))) ) ) ) ) (foreach vis (reverse (cdr blk)) (setq tbllst (append tbllst (list (cons (car vis) (itoa (cadr vis)))))) ) ) (t (setq tbllst (append tbllst (list (cons (car blk) (itoa (cadr blk))))))) ) ) Quote
Ryan W Posted September 7, 2023 Author Posted September 7, 2023 Ok, following up for the next part of the trouble If I take the existing code to the dynamic state, I want to generate a similar table, with a block name and the attributes for each block in a count. I know how extract the block name and get a count (from the count dynamics blocks, but instead of the LM:getvisibilityparametername I want to get the attributes of the block and count those and also get the parameter) Assume that I have only a single attribute per block I want to build a list based on selection that looks like this when built: (("Block-name" ("att1" 1) ("att2" 1) ("att" 3) ("att4" 1) ("att5" 1))) where Block-name is the name of the block and attx is the value of the attribute in that block instance (as a string), and the count (the second of the dotted pair) is how many blocks have that same value how he built the Count Attributes lisp doesn't give me a good place to start, as he's getting the values by the entity name and not getting the block name (like the dynamic block routine) I see a lot of solutions for attributes to tables, but none of them include the block name it's tied to, only the values of the attributes Quote
BIGAL Posted September 8, 2023 Posted September 8, 2023 You do it in a different way and can be done very easy again making the original list (blkname attvalue)(blkname attvalue)(blkname attvalue) as sort on the 2 values will make the list with blkname 1st then att values next. I posted the Gile count code above that will make the output (block val1 3)(block val2 4)...... The sort is posted above. I have been using this for years and it works I have counts for up to sort on 5 attributes deep. One tested block had 25 atts, sorted on 1st five. 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.