i am using AI to write a script for setting viewports and it is telling me that It cant find my block labeled sheets any help would be greatly appreciated

i am using AI to write a script for setting viewports and it is telling me that It cant find my block labeled sheets any help would be greatly appreciated

djharo71
Explorer Explorer
2,937 Views
29 Replies
Message 1 of 30

i am using AI to write a script for setting viewports and it is telling me that It cant find my block labeled sheets any help would be greatly appreciated

djharo71
Explorer
Explorer

Here is the code it gave me and the error message.

 

(defun c:ZoomViewportsToSheets (/ doc layouts layoutName layout modelSpace blockName insPt vp sheetBlock sheetNumber)
(vl-load-com)

;; Document and Layouts
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(setq layouts (vla-get-Layouts doc))
(setq modelSpace (vla-get-ModelSpace doc))

;; Block names and attribute
(setq sheetBlockName "SHEETS"
attrName "SHEET_NUMBER")

;; Utility function to find a block by its attribute value in model space
(defun get-block-by-attribute (blockName attrValue / ss blk block found)
(setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 blockName) (cons 410 "Model"))))
(if (and ss (> (sslength ss) 0))
(progn
(setq blkList (ssnamex ss))
(foreach blk blkList
(setq block (vlax-ename->vla-object blk))
(setq found (get-attribute block attrName))
(princ (strcat "\nChecking block: " (vlax-get block 'EffectiveName) " with attribute value: " found))
(if (and found (eq (strcase found) (strcase attrValue)))
(return block)))))
nil)

;; Utility function to get an attribute value from a block by its tag
(defun get-attribute (block attrName / attributes attribute tag)
(setq attributes (vla-getattributes block))
(vlax-for att attributes
(setq tag (vla-get-tagstring att))
(if (eq (strcase tag) (strcase attrName))
(return (vla-get-TextString att))))
nil)

;; Main function to process each layout
(defun process-layout (layout)
(setq layoutName (vla-get-Name layout))
(if (/= layoutName "Model")
(progn
(princ (strcat "\nProcessing layout: " layoutName))
(setvar "CTAB" layoutName)

;; Get the SHEETS block in model space by layout number
(setq sheetBlock (get-block-by-attribute sheetBlockName layoutName))
(if sheetBlock
(progn
(princ (strcat "\nFound SHEETS block for layout: " layoutName))

;; Get the insertion point of the SHEETS block
(setq insPt (vlax-get sheetBlock 'InsertionPoint))

;; Find and configure the viewport in paper space
(vlax-for obj (vla-get-PaperSpace doc)
(if (and (eq (vla-get-ObjectName obj) "AcDbViewport") (not (vla-get-ModelType obj)))
(progn
(setq vp obj)
(princ (strcat "\nConfiguring viewport for layout: " layoutName))
(vla-put-DisplayLocked vp :vlax-false)
(vla-put-Center vp (vlax-3d-point (car insPt) (cadr insPt)))

;; Optionally adjust viewport size as needed, e.g., set width and height to fit block extents
(vla-put-Height vp 200.0) ;; Adjust as necessary
(vla-put-Width vp 200.0) ;; Adjust as necessary

(vla-put-DisplayLocked vp :vlax-true)
)
)
)

)
(princ (strcat "\nSHEETS block not found for layout: " layoutName)))
)
)
)

;; Iterate through each layout and process
(vlax-for layout layouts
(process-layout layout))

(princ "\nZoom Viewports to SHEETS completed.")
(princ)
)

(princ "\nRun the function 'c:ZoomViewportsToSheets' to execute the script.\n")
(princ)

 

 

then when i run it in autocad map 3d 

 

Command: ZOOMVIEWPORTSTOSHEETS
Processing layout: 03
SHEETS block not found for layout: 03
Processing layout: 04Regenerating layout.
Regenerating model.
SHEETS block not found for layout: 04
Processing layout: 05Regenerating layout.
Regenerating model.
SHEETS block not found for layout: 05
Processing layout: 06Regenerating layout.
Regenerating model.
SHEETS block not found for layout: 06
Processing layout: 07Regenerating layout.
Regenerating model.
SHEETS block not found for layout: 07
Processing layout: 08Regenerating layout.
Regenerating model.
SHEETS block not found for layout: 08
Zoom Viewports to SHEETS completed.

 

It basically runs through the sheets but does nothing because it claims to not see the blocks

0 Likes
2,938 Views
29 Replies
Replies (29)
Message 2 of 30

pendean
Community Legend
Community Legend

So it appears you want to be able to add a block of an outline in modelspace over an area, label it using the attribute in it, then wish for the LISP to run through each layout and create a viewport from the outline with the same matching number as the layout name. Is that correct?

 

What paper size is your outline generically called SHEETS is meant to be?

And at what plot scale since it appears to be of a static size? Or is that not important?

0 Likes
Message 3 of 30

djharo71
Explorer
Explorer
yes that is correct. the paper size is 11 x 17 and the scale is 50. I have
been working on some projects that have over 300 sheets lately and it takes
forever to set them up i also have blocks in paperspace for the cut sheets
they are labeled "MATCHLINE LEFT" "MATCHLINE RIGHT", AND "MATCHLINE
TOP" and "MATCHLINE BOTTOM" that i want to populate as well but i first
have to get it to recognize the sheets block. I would real appreciate any
help you can give

0 Likes
Message 4 of 30

paullimapa
Mentor
Mentor

as a quick review, do you have a return function that's defined elsewhere which is not included here because your code calls for this here:

(return block)

 and here:

(return (vla-get-TextString att))

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 30

ec-cad
Collaborator
Collaborator

AI has it's place, but doesn't quite know what to do with AutoLisp.

I see a couple of obvious errors. See comments in code window below.

 

;; Utility function to find a block by its attribute value in model space
(defun get-block-by-attribute (blockName attrValue / ss blk block found)
(setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 blockName) (cons 410 "Model"))))
(if (and ss (> (sslength ss) 0))
(progn
(setq blkList (ssnamex ss))
(foreach blk blkList
(setq block (vlax-ename->vla-object blk))
(setq found (get-attribute block attrName))
(princ (strcat "\nChecking block: " (vlax-get block 'EffectiveName) " with attribute value: " found))
(if (and found (eq (strcase found) (strcase attrValue)))  ;;;;; Should be attrName, attrValue is undefined
(return block))))) ;;;;;;;;; don't think 'return is a valid function ?, replace with just 'block and remove one ')
nil)

I don't see the symbol 'attrValue defined anywhere in the code, but it's referenced on line 11.

Never heard of a function called 'return  .. (return .. anything) , and nil) on the end ??

ECCAD

0 Likes
Message 6 of 30

ec-cad
Collaborator
Collaborator

My bad, attrValue is passed in to that function. DA.

 

ECCAD

0 Likes
Message 7 of 30

baksconstructor
Advocate
Advocate

 

This is ready-made artificial intelligence - AutoViewport 


Of course it is very interesting to call LISP artificial intelligence.... 🙂

0 Likes
Message 8 of 30

paullimapa
Mentor
Mentor

@djharo71 

I ended up correcting just this one function get-block-by-attribute to make it work.

Below you can take a look and compare how bad the AI code is compared to my corrected version:

;; Utility function to find a block with attribute tag name & value in model space
; Arguments:
; blockName = block name
; TagName = attribute tag name
; AttrValue = attribute value
; If found then return vl block object else nil
(defun get-block-by-attribute (blockName TagName attrValue / ss blk block found)
 (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blockName ",`*U*")) '(66 . 1) '(410 . "Model")))) ; get block matching name including dynamic blocks with attributes in model space
 (if (and ss (> (sslength ss) 0)) 
   (foreach blk (mapcar 'cadr (ssnamex ss)) ; convert entity names into list and loop
    (setq block (vlax-ename->vla-object blk))
    (if (eq (strcase blockName) (strcase (vlax-get block 'EffectiveName))) ; if dynamic block matches block name
      (foreach itm (vlax-invoke block 'getAttributes) ; get block attributes and loop
       (if (eq (strcase TagName) (strcase (vla-get-tagString itm))) ; chk if found attribute tag name
        (progn
         (if (eq (strcase (vla-get-textString itm)) (strcase attrValue)) ; chk if att text value matches with layout name
          (progn
           (princ (strcat "\nFound block: " blockName " with attribute value: " attrValue))
           (setq found block) ; save object to return
          ) ; progn       
         ) ; if
        ) ; progn
       ) ; if
      ) ; foreach
    ) ; if
   ) ; foreach
 ) ; if
 found
)

AI's version with all the errors:

;; Utility function to find a block by its attribute value in model space
(defun get-block-by-attribute (blockName attrValue / ss blk block found)
(setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 blockName) (cons 410 "Model"))))
(if (and ss (> (sslength ss) 0))
(progn
(setq blkList (ssnamex ss))
(foreach blk blkList
(setq block (vlax-ename->vla-object blk))
(setq found (get-attribute block attrName))
(princ (strcat "\nChecking block: " (vlax-get block 'EffectiveName) " with attribute value: " found))
(if (and found (eq (strcase found) (strcase attrValue)))
(return block)))))
nil)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 9 of 30

EnM4st3r
Advocate
Advocate

nah, he was saying he used AI to write his code, but it didnt work.

0 Likes
Message 10 of 30

paullimapa
Mentor
Mentor

and here's another function get-attribute I ended up modifying which AI came close but still not there...though this is no longer needed since my modified version of get-block-by-attribute already contains code within to achieve the same.

But again to demonstrate the differences, here's my modified version that works:

;; Utility function to get an attribute value from a block by its tag
(defun get-attribute (block attrName / attributes attribute tag val)
 (setq attributes (safearray-value (variant-value (vla-getattributes block))))
 (foreach att attributes
  (setq tag (vla-get-tagstring att))
  (if (eq (strcase tag) (strcase attrName))
    (setq val(vla-get-TextString att))
  )
 )
 val
)

Here's AI's version that fails:

;; Utility function to get an attribute value from a block by its tag
(defun get-attribute (block attrName / attributes attribute tag)
(setq attributes (vla-getattributes block))
(vlax-for att attributes
(setq tag (vla-get-tagstring att))
(if (eq (strcase tag) (strcase attrName))
(return (vla-get-TextString att))))
nil)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 11 of 30

djharo71
Explorer
Explorer
I am looking for someone to write some scripts for me that will help us
save some time my company will pay you. How much would you charge to help
me out, if you are interested can you send me an email with a cost estimate
at djharo71@gmail.com
0 Likes
Message 12 of 30

paullimapa
Mentor
Mentor

you may want to post in the classified section to get better feedback 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 13 of 30

paullimapa
Mentor
Mentor

Try this completed revised version of ZoomViewportsToSheets.lsp:

; ZoomViewportsToSheets Zoom Viewports to SHEETS
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/i-am-using-ai-to-write-a-script-for-setting-viewports-and-it-is/m-p/12785206/highlight/false#M466295
(defun c:ZoomViewportsToSheets 
;; localize functions & variables
 (/ attrName blockName doc layouts get-attribute get-block-by-attribute 
    layout layouts modelSpace process-layout 
    sheetBlockName sheetNumber 
 )
 (vl-load-com)

 (setq doc (vla-get-activedocument (vlax-get-acad-object)) ;; Document
       layouts (vla-get-Layouts doc)      ;; Layouts
       sheetBlockName "SHEETS"            ;; Block name 
       attrName "SHEET_NUMBER"            ;; attribute Tag name
 )

;; Utility function to find a block with attribute tag name & value in model space
; Arguments:
; blockName = block name
; TagName = attribute tag name
; AttrValue = attribute value
; If found then return vl block object else nil
(defun get-block-by-attribute (blockName TagName attrValue / block found ss)
 (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blockName ",`*U*")) '(66 . 1) '(410 . "Model")))) ; get block matching name including dynamic blocks with attributes in model space
 (if (and ss (> (sslength ss) 0)) 
   (foreach blk (mapcar 'cadr (ssnamex ss)) ; convert entity names into list and loop
    (setq block (vlax-ename->vla-object blk))
    (if (eq (strcase blockName) (strcase (vlax-get block 'EffectiveName))) ; if dynamic block matches block name
      (foreach itm (vlax-invoke block 'getAttributes) ; get block attributes and loop
       (if (eq (strcase TagName) (strcase (vla-get-tagString itm))) ; chk if found attribute tag name
        (progn
         (if (eq (strcase (vla-get-textString itm)) (strcase attrValue)) ; chk if att text value matches with layout name
          (progn
           (princ (strcat "\nFound block: " blockName " with attribute value: " attrValue))
           (setq found block) ; save object to return
          ) ; progn       
         ) ; if
        ) ; progn
       ) ; if
      ) ; foreach
    ) ; if
   ) ; foreach
 ) ; if
 found
)

;; Utility function to get an attribute value from a block by its tag
(defun get-attribute (block attrName / attributes tag val)
 (setq attributes (safearray-value (variant-value (vla-getattributes block))))
 (foreach att attributes
  (setq tag (vla-get-tagstring att))
  (if (eq (strcase tag) (strcase attrName))
    (setq val(vla-get-TextString att))
  )
 )
 val
)

;; function to process each layout
(defun process-layout (layout / layoutName ll ur sheetBlock ss vp)
 (setq layoutName (vla-get-Name layout))
 (if (/= layoutName "Model")
  (progn
   (princ (strcat "\nProcessing layout: " layoutName "\n"))
   (setvar "CTAB" layoutName)

;; find the SHEETS block containting attribute tag SHEET_NUMBER attribute value in model space matching the layout name 
   (setq sheetBlock (get-block-by-attribute sheetBlockName attrName layoutName))
   (if sheetBlock
    (progn
     (princ (strcat "\nFound SHEETS block for layout: " layoutName))

;; Get lower left & upper right of title block - only works if orthogonally placed
     (vla-GetBoundingBox sheetBlock 'll 'ur)

;; Find and configure the viewport in paper space
     (if (setq ss (ssget "_X" (list '(0 . "VIEWPORT") (cons 410 layoutName) '(-4 . ">=")'(69 . 2)))) ; get only vport & not pspace
      (progn
        (setq vp (vlax-ename->vla-object (ssname ss 0))) ; convert only the 1st vport found to vl obj
        (princ (strcat "\nConfiguring viewport for layout: " layoutName))
        (vla-put-DisplayLocked vp :vlax-false) ; unlock vp display
        (vla-put-MSpace doc :vlax-true) ; goto mspace
        (vla-ZoomWindow (vlax-get-acad-object) ll ur) ; zoom window with lower left & upper right coordinates
        (vla-put-MSpace doc :vlax-false) ; return to pspace

;; Optionally adjust viewport size as needed, e.g., set width and height to fit block extents
        (vla-put-Height vp 7.5) ;; Adjust as necessary
        (vla-put-Width vp 14.0) ;; Adjust as necessary

;; for setting vp scale to 1:50
        (vla-put-CustomScale vp (/ 1. 50))
;;
        (vla-put-DisplayLocked vp :vlax-true) ; lock vp display

;; zoom to layout extents
        (vla-zoomextents (vlax-get-acad-object))
      ) ; progn
     ) ; if
    ) ; progn
    (princ (strcat "\nMatching " sheetBlockName " Title Block not found for layout: " layoutName "\n"))
   ) ; if
  ) ; progn
 ) ; if
) 

;; begin main program
;; Iterate through each layout and process
(vlax-for layout layouts
 (process-layout layout)
)

(princ "\nZoom Viewports to SHEETS completed.")
(princ)
)

(princ "\nRun the function 'c:ZoomViewportsToSheets' to execute the script.\n")
(princ)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 14 of 30

Sea-Haven
Mentor
Mentor

Nice coding,

;; Get lower left & upper right of title block - only works if orthogonally placed

You can get around it this is walk along a pline other version is place orthogonally, two separate processes 1st  is make rectangs you can move, rotate or delete, add more rectangs. Then make layouts. For rotation you use Twistangle.

SeaHaven_0-1716345597641.png

SeaHaven_1-1716345738899.png

Happy to discuss not free but cheap.

 

 

 

Message 15 of 30

paullimapa
Mentor
Mentor

looks like a pretty nice tool you have there... I recall you introducing this on this thread as well.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 16 of 30

Sea-Haven
Mentor
Mentor

A big hint re angles (command "UCS" "Z" ang "plan" "")

Message 17 of 30

paullimapa
Mentor
Mentor

Looks like your app is an excellent competitor to AutoViewport

Do you also have a catchy name to go with it?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 18 of 30

djharo71
Explorer
Explorer
we called it ZOOMTOSHEETS and it works great. Thank you for the help. I am
now trying to write a script that will populate the matchlines for the
sheets. I have created blocks for them "MATCHLINE TOP", "MATCHLINE
BOTTOM", "MATCHLINE RIGHT", "MATCHLINE LEFT". So after running
zoomtosheets i can run another script that will populate the cut sheets or
matchlines. Any help would be awesome.

[image: image.png]
0 Likes
Message 19 of 30

paullimapa
Mentor
Mentor

No image attached but glad to have helped. You may want to start another post on this request and include dwg as well as block for match lines


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 20 of 30

Sea-Haven
Mentor
Mentor

The match sheets labelling is on the to do list, but low priority. If you look at the video it may have up to 4 sheets touching. The auto pline option has a sort of built in overlap.

 

As you know the rectang can use a ssget "F" to look for other rectangs but really no idea how to do labelling.

0 Likes