两份图纸块同步,G版的思路
本帖最后由 panliang9 于 2024-4-12 13:35 编辑两份图纸,都处于打开的状态,如何让图块同步。
在这个贴子里,G版提供的代码,可以在A图中,插入B图,但是A图中的图块按B图的更新。
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=100770&page=1#pid579132
略微更改后,得到下面这个代码,这个代码中固定指向了一个固定的文件“D:\投影图\000.DWG”,执行代码后,就按照指定的文件“D:\投影图\000.DWG”更新本图的块。
现在的问题是,指定的文件必须是关闭的状态,如果是打开的,就不能更新。
现在想知道,有没有办法,同时打开的两份图纸A和B,用一个指令,可以让A图根据B图中的图块更新,同理,也可以让B图中根据A图中的同名图块更新。
我把A图依据B图更新图块的程序贴在下面,看大家有没有办法解决必须关闭文件才能更新这个问题。(奇怪,没法传附件,是怎么回事)
;; 自动更新本图的图块,不插入文件 base By Gu_xl
(defun c:es (/ DWGNAME DBXDOC ACVER DBXMODELSPACE BLOCKS DOC DBXBLOCKNAMES OBJS)
(setq DwgName "D:\\投影图\\000.DWG") ; 直接指定文件路径
(setq
DBXDOC (vla-GetInterfaceObject
(vlax-get-acad-object)
(if (< (setq acVer (atoi (getvar "ACADVER"))) 16)
"ObjectDBX.AxDbDocument"
(strcat "ObjectDBX.AxDbDocument." (itoa acVer))
)
)
)
(vla-open DBXDOC DWGNAME)
(setq DBXModelSpace (vla-get-ModelSpace DBXDOC))
(setq blocks (vla-get-blocks
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
)
)
(vlax-for blk (vla-get-blocks DBXDOC)
(if (not (or (eq :vlax-true (vla-get-isXRef blk))
(eq :vlax-true (vla-get-isLayout blk))
(= "*U" (substr (vla-get-name blk) 1 2))
(= "*D" (substr (vla-get-name blk) 1 2))
(= "*T" (substr (vla-get-name blk) 1 2))
)
)
(setq dbxblocknames (cons (vla-get-name blk) dbxblocknames))
)
)
(setq dbxblocknames
(vl-remove-if-not
'(lambda (x) (TBLSEARCH "BLOCK" x))
dbxblocknames
)
)
(if dbxblocknames
(progn
(foreach block dbxblocknames
(vlax-for obj (vla-item blocks block)
(vla-delete obj)
)
(setq objs nil)
(vlax-invoke
dbxDoc
'CopyObjects
(vlax-for a
(vla-item (vla-get-blocks DBXDOC) block)
(setq objs (cons a objs))
)
(vla-item blocks block)
)
)
(vla-regen doc :vlax-true)
(prompt (strcat "\n更新了" (itoa (length dbxblocknames)) "个图块!"))
)
(prompt "\n没有可更新的图块!")
)
(vlax-release-object DBXDOC)
(princ)
)
现在变通的解决方案是。
1、A图(很复杂的大图)
2、B图,临时用图,用来改A图上的块。
3、C图,用来保存需要更新的图,例如上面代码中的 “D:\投影图\000.DWG”
工作方法,永远不在复杂的A图上改块,速度慢。把A图中的块复制出来放到B图,B图改好后另存为C图,然后A图根据C图更新块。
下面是把B图另存为C的代码。
(defun c:ge (/ dwgname filedia cmddia)
;; 保存当前FILEDIA和CMDDIA的设置
(setq filedia (getvar "FILEDIA"))
(setq cmddia (getvar "CMDDIA"))
;; 关闭文件对话框和命令对话框
(setvar "FILEDIA" 0)
(setvar "CMDDIA" 0)
;; 设置新文件名
(setq dwgname "D:\\投影图\\000.DWG")
;; 执行写块命令
(command "_.wblock" dwgname "y" "*")
;; 恢复FILEDIA和CMDDIA的设置
(setvar "FILEDIA" filedia)
(setvar "CMDDIA" cmddia)
;; 提示用户
(princ "\n当前图形已另存为D:\\投影图\\000.DWG,但未打开。")
(princ)
)
本帖最后由 你有种再说一遍 于 2024-3-27 01:18 编辑
换个语言,然后你就知道跨图纸跨线程跨进程多好做了...
思路就是遍历图A块表产生一份hashmap,然后去和图B比较,
名称冲突的就深度克隆过去,覆盖模式.
再监控文档的图元改变事件,改块并冲突就深度克隆过去.
删除块呢?摇摇头.
...
块表本身就能索引的,我因为cad08索引功能出错(能够获取entity.isErase==true)才遍历构造hashmap...
lisp跨文档需要骚技巧,通讯也是...所以你会发现怎么难以直接控制下一份图的事件呢...
调用设计中心,重定义一下是否可行? lxl217114 发表于 2024-3-26 21:34
调用设计中心,重定义一下是否可行?
没看到有调用设计中心的例子。
G版的程序可以实现更新,但必须文件处于关闭状态,好象不关闭就无法访问数据库,一个变通的办法应该是将要访问的文件,另存为一个临时文件,然后访问这个临时文件,执行完毕后把这个临时文件删掉。
“lxl217114” 长老能不能出手尝试一下,大家走过路过的,希望都尝试一下。 panliang9 发表于 2024-3-27 08:34
lxl217114 发表于 2024-3-26 21:34
调用设计中心,重定义一下是否可行?
没看到有调用设计中心的例子。
从来没写过lsp代码,实在没这个能力。一直想学习写,但是还没开始。 这个东西不错,最好是能再支持属性块、动态块,这样就可以放心的修改动态块了
页:
[1]