При вставке динамические блоки становятся статичес...
Erstellt am: 24. März 2026
Beantwortet mit GPT-5.4 Thinking von Chat01
Erstellt am: 24. März 2026
Beantwortet mit GPT-5.4 Thinking von Chat01
При вставке динамические блоки становятся статическими, это нужно исправить.
А также, по умолчанию поставить масштаб 2, но оставить выбор масштаба 1 или 2 в окне Dcl.
И нужно немного увеличить окно Dcl, чтобы поместился весь список блоков, без необходимости прокручивать.
Дать полный код.
; вставить блок по имени из списка, окно Dcl
; запрос масштаба одинаковый по Х-У, выбрать масштаб 2 или 1 в окне Dcl
(vl-load-com)
;; --- Список блоков (можно дополнять) ---
(setq AB:BlockList
'(
"Люк Л" "КО6" "КС7.3-6-9" "КС10.3-6-9" "КС15.3-6-9"
"ПП10" "ПП15" "ПП20" "МС1-рзр" "МС2-рзр"
"МС3-рзр" "МС4-рзр" "МС5-рзр" "МС6-рзр"
"МС7-рзр" "МС8-рзр"
)
)
;; Функция проверки блока (с защитой от nil)
(defun AB:BlockExistsP (blkName)
(if (and blkName (= (type blkName) 'STR) (tblsearch "BLOCK" blkName))
T
nil
)
)
;; Получение пространства (Модель/Лист)
(defun AB:GetCurrentSpace (doc)
(if (= (getvar "CVPORT") 1)
(vla-get-PaperSpace doc)
(vla-get-ModelSpace doc)
)
)
;; Создание DCL-файла
(defun AB:WriteDCLFile (/ fn f)
(setq fn (vl-filename-mktemp "ab_ins_" nil ".dcl"))
(setq f (open fn "w"))
(foreach line
'(
"ab_block_select : dialog {"
" label = "Параметры вставки";"
" : column {"
" : boxed_column {"
" label = "1. Выберите блок";"
" : list_box { key = "blk_list"; width = 25; height = 20; allow_accept = true; }"
" }"
" : boxed_radio_column {"
" label = "2. Выберите масштаб";"
" key = "sc_group";"
" : radio_button { label = "Масштаб 1"; key = "sc1"; value = "1"; }"
" : radio_button { label = "Масштаб 2"; key = "sc2"; }"
" }"
" spacer;"
" : row {"
" : button { label = "Вставить"; key = "accept"; is_default = true; fixed_width = true; width = 12; }"
" : button { label = "Отмена"; key = "cancel"; is_cancel = true; fixed_width = true; width = 12; }"
" }"
" }"
"}"
)
(write-line line f)
)
(close f)
fn
)
;; Функция вызова диалога
(defun AB:SelectBlockDCL (lst / dclFile dclId result idx sc_val)
(setq dclFile (AB:WriteDCLFile))
(setq dclId (load_dialog dclFile))
(setq result nil)
(if (and dclId (> dclId 0))
(progn
(if (new_dialog "ab_block_select" dclId)
(progn
;; Заполнение списка блоков
(start_list "blk_list")
(foreach item lst (add_list item))
(end_list)
text;; Начальное состояние (set_tile "blk_list" "0") (mode_tile "blk_list" 2) ;; Фокус на список ;; Обработка нажатия ОК (action_tile "accept" "(progn (setq idx (atoi (get_tile \"blk_list\"))) (if (= (get_tile \"sc2\") \"2\") ; по умолчанию масштаб 2 ???
(setq sc_val 1.0)
(setq sc_val 2.0)
text) (setq result (list (nth idx lst) sc_val)) (done_dialog 1) )" ) (action_tile "cancel" "(done_dialog 0)") (start_dialog) ) ) (unload_dialog dclId) )
)
;; Удаление временного файла
(if (and dclFile (findfile dclFile)) (vl-file-delete dclFile))
result
)
;; Основная команда
(defun c:InsDclWBlkListScl (/ doc res blk currentScale pt spc insObj)
(vl-load-com)
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
;; Вызов диалога
(setq res (AB:SelectBlockDCL AB:BlockList))
;; Проверка результата (res должен быть списком: ("ИмяБлока" Масштаб))
(if (and res (listp res) (car res))
(progn
(setq blk (car res)
currentScale (cadr res)
)
text;; Проверка существования блока (if (not (AB:BlockExistsP blk)) (alert (strcat "Ошибка: Блок \"" blk "\" не найден в чертеже!")) (progn (setq pt (getpoint (strcat "
Точка вставки [Блок: " blk " | Масштаб: " (rtos currentScale 2 1) "]: ")))
(if pt
(progn
(setq spc (AB:GetCurrentSpace doc))
(setq insObj
(vl-catch-all-apply
'vla-InsertBlock
(list
spc
(vlax-3d-point pt)
blk
(float currentScale) ;; X
(float currentScale) ;; Y
(float currentScale) ;; Z
0.0 ;; Угол
)
)
)
text(if (vl-catch-all-error-p insObj) (princ (strcat "
Ошибка вставки: " (vl-catch-all-error-message insObj)))
(princ (strcat "
Успешно: Блок "" blk "" вставлен."))
)
)
(princ "
Отмена: Точка не указана.")
)
)
)
)
(princ "
Команда отменена пользователем.")
)
(princ)
)
(princ "
Загружено успешно. Команда: InsDclBlkListScl")
(princ)
При вставке динамические блоки становятся статическими, это нужно исправить.
А также, по умолчанию поставить масштаб 2, но оставить выбор масштаба 1 или 2 в окне Dcl.
И нужно немного увеличить окно Dcl, чтобы поместился весь список блоков, без необходимости прокручивать.
Дать полный код.
; вставить блок по имени из списка, окно Dcl
; запрос масштаба одинаковый по Х-У, выбрать масштаб 2 или 1 в окне Dcl
(vl-load-com)
;; --- Список блоков (можно дополнять) ---
(setq AB:BlockList
'(
"Люк Л" "КО6" "КС7.3-6-9" "КС10.3-6-9" "КС15.3-6-9"
"ПП10" "ПП15" "ПП20" "МС1-рзр" "МС2-рзр"
"МС3-рзр" "МС4-рзр" "МС5-рзр" "МС6-рзр"
"МС7-рзр" "МС8-рзр"
)
)
;; Функция проверки блока (с защитой от nil)
(defun AB:BlockExistsP (blkName)
(if (and blkName (= (type blkName) 'STR) (tblsearch "BLOCK" blkName))
T
nil
)
)
;; Получение пространства (Модель/Лист)
(defun AB:GetCurrentSpace (doc)
(if (= (getvar "CVPORT") 1)
(vla-get-PaperSpace doc)
(vla-get-ModelSpace doc)
)
)
;; Создание DCL-файла
(defun AB:WriteDCLFile (/ fn f)
(setq fn (vl-filename-mktemp "ab_ins_" nil ".dcl"))
(setq f (open fn "w"))
(foreach line
'(
"ab_block_select : dialog {"
" label = "Параметры вставки";"
" : column {"
" : boxed_column {"
" label = "1. Выберите блок";"
" : list_box { key = "blk_list"; width = 25; height = 20; allow_accept = true; }"
" }"
" : boxed_radio_column {"
" label = "2. Выберите масштаб";"
" key = "sc_group";"
" : radio_button { label = "Масштаб 1"; key = "sc1"; value = "1"; }"
" : radio_button { label = "Масштаб 2"; key = "sc2"; }"
" }"
" spacer;"
" : row {"
" : button { label = "Вставить"; key = "accept"; is_default = true; fixed_width = true; width = 12; }"
" : button { label = "Отмена"; key = "cancel"; is_cancel = true; fixed_width = true; width = 12; }"
" }"
" }"
"}"
)
(write-line line f)
)
(close f)
fn
)
;; Функция вызова диалога
(defun AB:SelectBlockDCL (lst / dclFile dclId result idx sc_val)
(setq dclFile (AB:WriteDCLFile))
(setq dclId (load_dialog dclFile))
(setq result nil)
(if (and dclId (> dclId 0))
(progn
(if (new_dialog "ab_block_select" dclId)
(progn
;; Заполнение списка блоков
(start_list "blk_list")
(foreach item lst (add_list item))
(end_list)
text;; Начальное состояние (set_tile "blk_list" "0") (mode_tile "blk_list" 2) ;; Фокус на список ;; Обработка нажатия ОК (action_tile "accept" "(progn (setq idx (atoi (get_tile \"blk_list\"))) (if (= (get_tile \"sc2\") \"2\") ; по умолчанию масштаб 2 ???
(setq sc_val 1.0)
(setq sc_val 2.0)
text) (setq result (list (nth idx lst) sc_val)) (done_dialog 1) )" ) (action_tile "cancel" "(done_dialog 0)") (start_dialog) ) ) (unload_dialog dclId) )
)
;; Удаление временного файла
(if (and dclFile (findfile dclFile)) (vl-file-delete dclFile))
result
)
;; Основная команда
(defun c:InsDclWBlkListScl (/ doc res blk currentScale pt spc insObj)
(vl-load-com)
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
;; Вызов диалога
(setq res (AB:SelectBlockDCL AB:BlockList))
;; Проверка результата (res должен быть списком: ("ИмяБлока" Масштаб))
(if (and res (listp res) (car res))
(progn
(setq blk (car res)
currentScale (cadr res)
)
text;; Проверка существования блока (if (not (AB:BlockExistsP blk)) (alert (strcat "Ошибка: Блок \"" blk "\" не найден в чертеже!")) (progn (setq pt (getpoint (strcat "
Точка вставки [Блок: " blk " | Масштаб: " (rtos currentScale 2 1) "]: ")))
(if pt
(progn
(setq spc (AB:GetCurrentSpace doc))
(setq insObj
(vl-catch-all-apply
'vla-InsertBlock
(list
spc
(vlax-3d-point pt)
blk
(float currentScale) ;; X
(float currentScale) ;; Y
(float currentScale) ;; Z
0.0 ;; Угол
)
)
)
text(if (vl-catch-all-error-p insObj) (princ (strcat "
Ошибка вставки: " (vl-catch-all-error-message insObj)))
(princ (strcat "
Успешно: Блок "" blk "" вставлен."))
)
)
(princ "
Отмена: Точка не указана.")
)
)
)
)
(princ "
Команда отменена пользователем.")
)
(princ)
)
(princ "
Загружено успешно. Команда: InsDclBlkListScl")
(princ)
Ниже полный исправленный код.
Что изменено:
-INSERT, а не через vla-InsertBlock — так они сохраняют динамические свойства;InsDclBlkListScl и InsDclWBlkListScl.lisp; ========================================================== ; Вставка блока по имени из списка через DCL ; Динамические блоки сохраняются динамическими ; Масштаб по умолчанию = 2, выбор 1 или 2 в окне DCL ; ========================================================== (vl-load-com) ;; --- Список блоков (можно дополнять) --- (setq *AB:BlockList* '( "Люк Л" "КО6" "КС7.3-6-9" "КС10.3-6-9" "КС15.3-6-9" "ПП10" "ПП15" "ПП20" "МС1-рзр" "МС2-рзр" "МС3-рзр" "МС4-рзр" "МС5-рзр" "МС6-рзр" "МС7-рзр" "МС8-рзр" ) ) ;; ---------------------------------------------------------- ;; Проверка существования блока ;; ---------------------------------------------------------- (defun AB:BlockExistsP (blkName) (and (= (type blkName) 'STR) (tblsearch "BLOCK" blkName) ) ) ;; ---------------------------------------------------------- ;; Создание временного DCL-файла ;; ---------------------------------------------------------- (defun AB:WriteDCLFile (/ fn f) (setq fn (vl-filename-mktemp "ab_ins_" nil ".dcl")) (setq f (open fn "w")) (foreach line '( "ab_block_select : dialog {" " label = \"Параметры вставки\";" " : column {" " : boxed_column {" " label = \"1. Выберите блок\";" " : list_box {" " key = \"blk_list\";" " width = 32;" " height = 16;" " allow_accept = true;" " }" " }" " : boxed_radio_column {" " label = \"2. Выберите масштаб\";" " : radio_button { label = \"Масштаб 1\"; key = \"sc1\"; }" " : radio_button { label = \"Масштаб 2\"; key = \"sc2\"; }" " }" " spacer;" " : row {" " : button {" " label = \"Вставить\";" " key = \"accept\";" " is_default = true;" " fixed_width = true;" " width = 12;" " }" " : button {" " label = \"Отмена\";" " key = \"cancel\";" " is_cancel = true;" " fixed_width = true;" " width = 12;" " }" " }" " }" "}" ) (write-line line f) ) (close f) fn ) ;; ---------------------------------------------------------- ;; Диалог выбора блока и масштаба ;; Возвращает: (\"ИмяБлока\" Масштаб) или nil ;; ---------------------------------------------------------- (defun AB:SelectBlockDCL (lst / dclFile dclId dlgStatus idx sc_val result) (setq dclFile (AB:WriteDCLFile)) (setq dclId (load_dialog dclFile)) (setq result nil) (if (and dclId (> dclId 0)) (progn (if (new_dialog "ab_block_select" dclId) (progn ;; Заполнение списка блоков (start_list "blk_list") (foreach item lst (add_list item) ) (end_list) ;; Начальные значения (set_tile "blk_list" "0") (set_tile "sc2" "1") ; Масштаб 2 по умолчанию (mode_tile "blk_list" 2) ; Фокус на список ;; Кнопки (action_tile "accept" "(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") ;; Двойной щелчок по списку = Вставить (action_tile "blk_list" "(if (= $reason 4) (done_dialog 1))") (setq dlgStatus (start_dialog)) (if (= dlgStatus 1) (progn (setq idx (atoi (get_tile "blk_list"))) (setq sc_val (if (= (get_tile "sc1") "1") 1.0 2.0 ) ) (setq result (list (nth idx lst) sc_val)) ) ) ) ) (unload_dialog dclId) ) ) ;; Удаление временного DCL-файла (if (and dclFile (findfile dclFile)) (vl-file-delete dclFile) ) result ) ;; ---------------------------------------------------------- ;; Вставка блока через команду -INSERT ;; Это сохраняет динамичность динамических блоков ;; ---------------------------------------------------------- (defun AB:InsertBlockByCommand (blk pt scl / oldCmdecho insRes) (setq oldCmdecho (getvar "CMDECHO")) (setvar "CMDECHO" 0) (setq insRes (vl-catch-all-apply 'vl-cmdf (list "_.-INSERT" blk "_non" pt scl scl 0.0) ) ) (setvar "CMDECHO" oldCmdecho) insRes ) ;; ---------------------------------------------------------- ;; Основная команда ;; ---------------------------------------------------------- (defun AB:RunInsertBlockDialog (/ res blk currentScale pt insRes) (vl-load-com) ;; Вызов диалога (setq res (AB:SelectBlockDCL *AB:BlockList*)) ;; Проверка результата (if (and res (listp res) (car res)) (progn (setq blk (car res) currentScale (cadr res) ) ;; Проверка существования блока (if (not (AB:BlockExistsP blk)) (alert (strcat "Ошибка: блок \"" blk "\" не найден в чертеже.")) (progn (setq pt (getpoint (strcat "\nТочка вставки [Блок: " blk " | Масштаб: " (rtos currentScale 2 1) "]: " ) ) ) (if pt (progn ;; Вставка через -INSERT (setq insRes (AB:InsertBlockByCommand blk pt currentScale)) (if (vl-catch-all-error-p insRes) (princ (strcat "\nОшибка вставки: " (vl-catch-all-error-message insRes) ) ) (princ (strcat "\nУспешно: блок \"" blk "\" вставлен." ) ) ) ) (princ "\nОтмена: точка вставки не указана.") ) ) ) ) (princ "\nКоманда отменена пользователем.") ) (princ) ) ;; Основное имя команды (defun c:InsDclBlkListScl () (AB:RunInsertBlockDialog) ) ;; Дополнительное имя команды для совместимости (defun c:InsDclWBlkListScl () (AB:RunInsertBlockDialog) ) (princ "\nЗагружено успешно. Команды: InsDclBlkListScl, InsDclWBlkListScl") (princ)
Почему у вас ломалась динамика:
vla-InsertBlock;-INSERT.Если захотите, я сразу дам ещё версию, где список блоков автоматически берётся из чертежа, а не из вручную заданного списка.