Jump to content

Block definition modification - adding 2 attributes.


Recommended Posts

Posted

I need to modify a few block definitions per drawing by adding  2 new attributes. Fixed location, they wont be visible, so I do not care if they are overlapping with other content or not. I use them as a "meta data" storage. Now, what's the best way to do it? I'm considering reinserting the block (prepared separately, with required modifications) or editing the block definition in place.

The number of drawings and blocks is too large for manual modifications. I'm OK with LISP as well, but I will be populating the data from excel, so VBA seems to be the natural choice.

 

Any advice if there is abetter way of doing it? Any opinions, comments, are more than welcome. I'm at the "brain storm" stage 🌩️

 

P.S. I currently open the block editor, paste the 2 attributes, close block editor, attsync, done. Maybe recreating that process in a scripted way with LISP would be easier?

Posted

Probably the same either way.

 

LISP/Script would be quite capable, lot's of code around for adding attributes, pretty sure Lee Mac has something.

 

VBA, IMO, might have a slight advantage running on multiple drawings.

 

.NET or Python an option?

  • Like 1
Posted (edited)

Thanks! I'm OK to do it drawing by drawing. I can script handling the batch. I think in python 🤓, so definitely yes. .NET - never used it.

I just found out the expresstools command blockreplace, but I'm struggling to convince it to use external file as the new block. I might dig into Lee Mac library...

I prepared the new block as external file, but  I'm not asked to redefine the block even when inserting with full file path. Possibly some system variable controls that (*).

 

Edit: * https://help.autodesk.com/view/ACD/2022/ENU/?guid=GUID-15A13868-7582-4CCD-A8FC-9AF2D05E689C BLOCKREDEFINEMODE

Edited by pefi
add link
Posted (edited)

Looks like a lot can be done with -bedit, -insert, -bsave, -bclose, attsync . I just need to put it together, bur I think I have a solution.

1. Prepare external drawing with attributes for adding

2. Open the drawing that needs to be modified (easily scripted for batch work)

 

Script:
 

(defun c:add_to_block_from_file ( / )
   	;Add attribues or anything else from external  file to a block definition
   	(setq block_name "BLOCK_NAME")
   	(setq att_file_path "C:\\PATH_TO_THE_FILE_FOR_ADDING.dwg") ;Use \\ in the path!
	(command "-bedit" block_name)
	(command "insert" att_file_path "E"  "Y"  "0,0" "1" "1" "0")
	(command "bsave")
	(command "bclose" "")
	(command "attsync" "Name" block_name)
)

 

at this moment the blocks contain the new attributes so the drawing can be modified or saved.

 

 

 

Edited by pefi
Posted

You mention reading from Excel, its not a problem you can read cells from CAD, so if you have multiple blocks can be done.

 

It would be simple to add to your defun say two columns in Excel Blocknames & dwgname with path. Need a sample Excel.

  • Like 1
Posted

Thank you very much! I'm not sure if I understand you, you mean reading excel directly using AutoLISP? I never tried to do anything with excel and LISP together. When I have data in excel I use VBA and calling LISP scripts from VBA.

The sample data set attached -  there are 4 columns, file, bhd_ins - block handle that needs to get the "data injection", bhd_type and bhd_line - are the names of attributes in that block. The block handles in the sample set correspond to the real handles on the sample drawing. The content of bhd_type and bhd_line is made up, but that won't make a difference.

 

 

sample_drawing.dwg handle_table.xlsx

Posted (edited)

This is read an Excel example it just reads an open spreadsheet, and shows the result of a read cells. You could make a list of the cells.

For your task you will probably need to use OBDX as you may have different dwg names, OBDX will allow you to change multiple dwgs.

 

; https://www.cadtutor.net/forum/topic/98627-block-definition-modification-adding-2-attributes/
; Excel link by AlanH Aug 2025

(defun wow ( / myxl)

; thanks to Lee-mac for this defun
; 58 is Colon

; thanks to Lee-mac for this defun 
; www.lee-mac.com
; 44 is comma 9 is tab 34 is space 58 is colon
(defun csv->lst58 ( str / pos )
	(if (setq pos (vl-string-position 58 str))
		(cons (substr str 1 pos) (csv->lst58 (substr str (+ pos 2))))
		(list str)
    )
)

; get range
(defun AH:getrangexl ( / lst1 myrange lst1)
  (setq lst1 '())
  (setq myrange (vlax-get-property (vlax-get-property (vlax-get-property  myxl "ActiveSheet") 'UsedRange) 'address))
  (setq lst1 (csv->lst58 myrange))
  (setq st (vl-string-subst "" "$" (vl-string-subst "" "$" (nth 0 lst1) )))
  (setq end (vl-string-subst "" "$" (vl-string-subst "" "$" (nth 1 lst1) )))
  (setq row1 (cadr (columnrow st)))
  (setq endrow (cadr (columnrow end)))
  (setq endcol (car (columnrow end)))
)

; Alpha2Number - Converts Alpha string into Number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
;   Str$ = String to convert
; Syntax example: (Alpha2Number "ABC") = 731
;-------------------------------------------------------------------------------
(defun Alpha2Number (Str$ / Num#)
  (if (= 0 (setq Num# (strlen Str$)))
    0
    (+ (* (- (ascii (strcase (substr Str$ 1 1))) 64) (expt 26 (1- Num#)))
       (Alpha2Number (substr Str$ 2))
    )
  )
)

 ; ColumnRow - Returns a list of the Column and Row number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
;   Cell$ = Cell ID
; Syntax example: (ColumnRow "ABC987") = '(731 987)
;default to "A1" if there's a problem
;-------------------------------------------------------------------------------
(defun ColumnRow (Cell$ / Column$ Char$ Row#)
  (setq Column$ "")
  (while (< 64 (ascii (setq Char$ (strcase (substr Cell$ 1 1)))) 91)
    (setq Column$ (strcat Column$ Char$)
          Cell$ (substr Cell$ 2)
    )
  )
  (if (and (/= Column$ "") (numberp (setq Row# (read Cell$))))
    (list (Alpha2Number Column$) Row#)
    '(1 1)
  )
)

;;	Thanks to fixo
(defun getcell2 (row column / )
  (setq cells (vlax-get-property  (vlax-get-property myxl "ActiveSheet") "Cells"))
  (setq cell (vlax-get (vlax-variant-value  (vlax-get-property cells "Item" row column)) 'value))
)

(defun openxl ( / )
(setq myxl (vl-catch-all-apply 'vlax-get-or-create-object '("Excel.Application")))
  (if (vl-catch-all-error-p myxl)
    (progn
      (prompt "\nError: Could not start Excel.")
      (exit)
    )
  )
(if (=  (vlax-get-property  (vlax-get-property myXL 'WorkBooks) 'count) 0)
    (vlax-invoke-method (vlax-get-property myXL 'WorkBooks) 'Add)
)
(vla-put-visible myXL :vlax-true)
(vlax-put-property myxl 'ScreenUpdating :vlax-true)
(vlax-put-property myXL 'DisplayAlerts :vlax-true)
(princ)
)

; starts here 

(openxl)
(AH:getrangexl)

; ignore 1st line
(setq row (+ row1 1))
(repeat (- endrow 1)
(setq dwgname (getcell2 row 1))
(setq bhd_inst (getcell2 row 2))
(setq bhd_line (getcell2 row 3))
(setq bhd_type (getcell2 row 4))
(princ (strcat"\n" dwgname " " bhd_inst " " bhd_line " " bhd_type))
(setq row (1+ row))
;***********************************
; do your thing here 
;***********************************
)

(if (not (vlax-object-released-p myXL))(progn(vlax-release-object myXL)(setq myXL nil)))

(princ)
)
              
(wow)

 

Edited by BIGAL

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...