多个/快速另存为
大家好,今天,我不得不将多个dwg保存到不同的dwg版本中,结果是:
快速批量处理(我讨厌/尽量避免使用浏览器对话框,当我不需要时):
(defun C:SaveAsQuick ( / ftp k f L )
;| Type: AcSaveAsType enum
acR12_dxf: AutoCAD R12 DXF (*.dxf)
acR14_dwg: AutoCAD R14 DWG (*.dwg)
ac2000_dwg: AutoCAD 2000 DWG (*.dwg)
ac2000_dxf: AutoCAD 2000 DXF (*.dxf)
ac2000_Template: AutoCAD 2000 Drawing Template File (*.dwt)
ac2004_dwg: AutoCAD 2004 DWG (*.dwg)
ac2004_dxf: AutoCAD 2004 DXF (*.dxf)
ac2004_Template: AutoCAD 2004 Drawing Template File (*.dwt)
ac2007_dwg: AutoCAD 2007 DWG (*.dwg)
ac2007_dxf: AutoCAD 2007 DXF (*.dxf)
ac2007_Template: AutoCAD 2007 Drawing Template File (*.dwt)
ac2010_dwg: AutoCAD 2010 DWG (*.dwg)
ac2010_dxf: AutoCAD 2010 DXF (*.dxf)
ac2010_Template: AutoCAD 2010 Drawing Template File (*.dwt)
ac2013_dwg: AutoCAD 2013 DWG (*.dwg)
ac2013_dxf: AutoCAD 2013 DXF (*.dxf)
ac2013_Template: AutoCAD 2013 Drawing Template File (*.dwt)
acNative: A synonym for the latest drawing release. In this release, this value equals ac2013_dwg.
|;
;| https://knowledge.autodesk.com/support/autocad/learn-explore/caas/sfdcarticles/sfdcarticles/How-to-find-which-version-of-AutoCAD-was-used-to-create-save-a-DWG.html
The AC10xx versions are as follows:
AC1015 = AutoCAD 2000
AC1018 = AutoCAD 2004
AC1021 = AutoCAD 2007
AC1024 = AutoCAD 2010
AC1027 = AutoCAD 2013
AC1032 = AutoCAD 2018
|;
(cond
( (= 0 (getvar 'dwgtitled)) (alert "\nThe active drawing is unsaved!") )
(
(not
(setq ftp
(eval
(nth
(vl-position
(setq k
(progn
(setq L '("eXit" "R14" "2000" "2004" "2007" "2010" "2013"))
(setq f '((del L) (substr (apply 'strcat (mapcar '(lambda (x) (strcat del x)) L)) 2)))
(initget (f " " L)) (cond ( (getkword (strcat "Choose version [" (f "/" L) "] <eXit>: ")) ) ("eXit"))
); progn
); setq k
L
); vl-position
'(nil acR14_dwg ac2000_dwg ac2004_dwg ac2007_dwg ac2010_dwg ac2013_dwg)
); nth
); eval
); setq ftp
); not
(prompt "\nUser Exited.")
)
(
(
(lambda (doc)
(apply
'(lambda (a b c / pat des header)
(cond
( (findfile (setq pat (strcat a b "_" k c))) (alert (strcat "\nDrawing already exists: " pat)) )
( (vla-SaveAs doc pat ftp) nil)
( (progn (setq pat (findfile pat)) (setq des (open pat "r")) (setq header (substr (read-line des) 1 6))(close des) header)
(alert
(strcat "Drawing saved as "
(cond
(
(cdr
(assoc header
'(("AC1015" . "AutoCAD 2000")
("AC1018" . "AutoCAD 2004")
("AC1021" . "AutoCAD 2007")
("AC1024" . "AutoCAD 2010")
("AC1027" . "AutoCAD 2013")
("AC1032" . "AutoCAD 2018")
); list
); assoc
); cdr
)
("Unknown")
); cond
"."
); strcat
); alert
)
( (alert "\nUnable to find the saved copy.") )
); cond
)
(fnsplitl (vla-get-FullName doc))
)
)
(vla-get-ActiveDocument (vlax-get-acad-object))
)
)
); cond
(princ)
); defun C:SaveAsQuick
顺便提一下
最初的想法是将ODBX与SaveAs方法结合使用,但似乎失败了:
; Save As Multiple dwgs
(defun test ( / ftp tmp L new )
(cond
( (not LM:browseforfolder) (alert "You forgot to define 'LM:browseforfolder'") )
( (not LM:ODBX) (alert "You forgot to define 'LM:ODBX'") )
(
(not
(setq ftp
(
(lambda ( / f L )
(eval
(nth
(vl-position
(progn
(setq L '("eXit" "R14" "2000" "2004" "2007" "2010" "2013"))
(setq f '((del L) (substr (apply 'strcat (mapcar '(lambda (x) (strcat del x)) L)) 2)))
(initget (f " " L)) (cond ( (getkword (strcat "Choose version [" (f "/" L) "] <eXit>: ")) ) ("eXit"))
); progn
L
); vl-position
'(nil acR14_dwg ac2000_dwg ac2004_dwg ac2007_dwg ac2010_dwg ac2013_dwg)
); nth
); eval
); lambda
)
); setq ftp
); not
)
(
(not
(and
(setq tmp (LM:browseforfolder "Select Folder of Drawings to SaveAs" nil 512))
(setq L (mapcar (function (lambda ( x ) (strcat tmp "\\" x))) (vl-directory-files tmp "*.dwg" 1)))
)
)
)
( (not (setq new (LM:browseforfolder "Select Folder to Put the Copies" (strcat (getenv "userprofile") "\\Desktop\\") 0))) )
(
(LM:ODBX ; (LM:ODBX <fun> )
(function
(lambda ( doc ) ; object.SaveAs FileName [, FileType] [, SecurityParams]
;; Doesn't work because SaveAs changes the focus to the copied dwg file, hence the grip is lost
(vl-catch-all-apply (function (lambda nil (vla-SaveAs doc (strcat new "\\" (vla-get-Name doc)) ftp))))
)
)
L nil
)
)
); cond
(princ)
); defun 是的,odbx也有同样的问题。。。它只能按其名称保存“本机”格式。最后用脚本和autocadcore控制台完成了这项工作,所以至少我的系统在处理时没有挂断。
LM引用
选项:
1.obdx-
2.rlx的scr建议-?
3.TrueView-?
4、等等。。?? 谢谢你们的回复,
我从来没有真正的odbx任务要执行,所以我认为这是第一个。
在尝试时有似曾相识的感觉,我想我以前试过,但不记得了-哈哈
也许我会问议员他的RunAll能否做到,尽管我试过了,但还是失败了。
这是我的快速尝试,但没有发挥多少:
(defun define-test ( / tmp )
(if (setq tmp (LM:browseforfolder "Select Folder of Drawings to SaveAs" nil 512))
(progn
(eval
(append
'(defun-q test)
'( ( / f )
(setq f
(lambda (x)
(
(lambda (doc)
(or (= 0 (getvar 'dwgtitled)) (vla-SaveAs doc (strcat x "\\" (vla-get-Name doc)) ac2000_dwg) )
)
(vla-get-ActiveDocument (vlax-get-acad-object))
)
(princ)
)
)
); quote
(list (list 'f tmp))
); append
); eval
(vl-propagate 'test)
); progn
); if
); defun define-test
(_RunAll "(test)")
很抱歉我的回复太晚了-又是忙碌的日子了。
好主意!如果MP的代码可以工作,但它需要登录Swamp ATM,我不能忘记pw和恢复电子邮件pw。(它只能由另一台保存了pw的旧公司pc联机)
另一个简化
;(vl-bb-set 'test '((/ doc) (setq doc (vla-get-activedocument (vlax-get-acad-object))) (or (= 0 (getvar 'dwgtitled))
; (vla-saveas doc (strcat tmp "\\" (vla-get-name doc)) ac2000_dwg) (princ)))
;); <-i didn't test the code it requires vl-bb-ref , so not relavant
(mapcar 'set
'(tmp test)
(list (LM:browseforfolder "Select Folder of Drawings to SaveAs" nil 512)
'((/ doc)
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(or
(= 0 (getvar 'dwgtitled))
(if tmp (vla-saveas doc (strcat tmp "\\" (vla-get-name doc)) ac2000_dwg))
)
(princ)
)
)
)
(mapcar 'vl-propagate '(tmp test))
然而,只有当我为每个文档定义了一个全局“tmp”变量时,您才应该工作(这可能是无效的要求):
((/ F)
(SETQ F
(LAMBDA (X)
((LAMBDA (DOC)
(OR (= 0 (GETVAR 'DWGTITLED))
(vla-SaveAs
DOC
(STRCAT X "\\" (vla-get-Name DOC))
ac2000_dwg
)
)
)
(vla-get-ActiveDocument (vlax-get-acad-object))
)
(PRINC)
)
)
(F "C:\\Users\\Grrr\\Desktop\\Test") ; this path comes from the 'tmp' variable
)
是的,我知道你可能会说我的“tmp”是全局的,但实际上我可以将其包装在一个defun maker函数中,在那里它是局部的(因此在回复#4中修改了原始代码)。
抱歉导致误解(读了这篇文章后,我想你现在明白了)。
我无意硬编码路径,因为我更喜欢用文件夹浏览器来指定它。
你以前做过VBA吗你让我大吃一惊!现在我明白了为什么你这么擅长编写对象脚本了。
是的,这似乎是autodesk的一个缺点。。我以前从未尝试过VBA,直到一些论坛成员开始不断提到它,所以我决定“好吧,让我们看看它是什么样子”。
我(从LISP中)看到的第一个明显的优势是用户表单——将代码写入控件事件的概念。
虽然如果你用LISP'n'DCL来推动你自己,你可以复制这个程序(看起来我说的是对的人)。
但当我们谈论功能时,我不知道VBA是否还有其他优势。
我也有同样的观点,这取决于某个节目是否涵盖了我的规则:
[列表]
[*]替代了许多恼人/重复的手动步骤
[*]我很少使用这个程序(例如,绘图-一个人花几个小时绘图,最后才绘图)
[*]需要不到5分钟的处理时间(那时我喝咖啡,坐在电脑上/刷新)
[/列表]
总的来说,这听起来像是“多个SaveAs”的意图。
仍然感谢您的输入Rlx-我已经看到您做了很多ODBX ing,所以您对这些问题已经足够熟悉了。 我用VBA做的唯一一件事就是编写一个例程来打开一个图形,然后打印它或运行一个脚本。所以没什么大不了的。但在不再支持的产品上投入更多时间将是毫无意义的。VBA的一个主要优点是,它将AutoCAD视为一个对象而不是图形,因此您的代码不会像lisp那样失去焦点,因为lisp只在其自己的工作空间中运行。由于有了对话框编辑器,制作对话框变得更容易。但在编程方面。。。与其他语言相比,lisp没有那么快,也没有那么有限,但它更宽容(没有预先声明),您可以即时键入和测试。。。我之前说过,我宁愿快速地将一些东西粘贴在一起,并失去一些性能,然后首先必须为所有变量声明编写十页。但有时你当然需要表现。。。祝你的应用程序好运。
gr.Rlx
也许你忽略了帖子#5
((/ DOC)
(SETQ DOC (vla-get-ActiveDocument (vlax-get-acad-object)))
(OR (= 0 (GETVAR 'DWGTITLED))
(IF TMP ; you use the 'tmp' variable, but it will be null when passed to the other documents
(vla-SaveAs
DOC
(STRCAT TMP "\\" (vla-get-Name DOC))
ac2000_dwg
)
)
)
(PRINC)
)
“tmp”变量也全局设置为每个文档,即:符号为boundp
然而,我同意任何全局变量都不适合编码器。
不管我的作品与否,不用担心,只要你的应用程序能正常工作,那就太棒了!再加上MP的(_runall)是比脚本等有趣的想法。。
感谢您分享MP想法&多个savaAs想法非常有用
(mapcar 'vl-propagate '(tmp test))
现在有意义了,我的理解是,你只得到一次路径,然后在“测试”中重新定义(而我之前的帖子是传播变量“tmp”,如果我错了,请道歉)
我觉得这个概念差不多
-->defun-q列表
-->读取“STR”
(define-test ( / tmp ) ... )
附言:如果用户文件夹中包含较新版本的图纸,有什么例外吗?
特别同意短线航线 好了,这是离题了…:对不起的:
同意,如果我考虑最坏的情况:如果Autodesk出于某种原因决定不为未来的ACAD版本上载VBA启用程序。。
然后,它将迫使您运行一些MS Office应用程序,并通过其VBAIDE执行VB代码(这需要访问ACAD主对象)。
我理解你。。。假设您编写了这个很棒的VB程序,并向用户提供了“但您必须下载并安装VBA enabler才能使用”。
事实上,这个VB集成编辑器不是ACAD内置的(就像VLIDE一样)。。。烂透了。
感谢您的解释,现在我看到了与我们可爱的LISP相比的最终优势。
我认为这种语言不会很快消亡,因为:
[列表]
[*]理由1:资源投入量:教育资源+许多用户自己编写和使用了大量的。lsp例程
[*]理由2:编程语言的目的是什么为了解释他试图做什么(算法),人类更容易与计算机交互。
事实上,它相对容易学习,以速度和限制为代价,这使得它对程序员来说是用户友好和独特的。
这就像把自行车和汽车相比较——如果汽车能把你开得更远更快,那我们为什么还要骑自行车呢?
[/列表]
Rlx,作为我自己的用户,我将与您分享我的“性能”标准(性能指的是程序的速度,对吗?)。
这可能很明显,但无论如何:
这取决于每个绘图会话(执行特定任务)必须调用特定函数/程序的次数。
例如,假设“LINE”和“PLOT”命令是自定义的LISP函数,因此每个绘图会话通常会调用“LINE”200次,而“PLOT”仅调用3次。
你画画的时间是一个半小时。
由于频繁调用,调用“LINE”时会出现轻微延迟。。然而,如果“绘图”有明显的2-3秒延迟,这对你来说应该没什么大不了的(除非用户要求太高)。
这就是为什么比格尔在他的办公室里保存了一些关于每个人的报告(带有一个反应堆),关于谁在呼叫什么命令多少次(ACAD跟踪者)。
谢谢,奥尔霍,这只是一个附带的任务,给我带来了一个附带的问题(没有什么紧迫的),这激发了这个问题。
如果有一天我能想出解决办法,我会通知你们的。
您是对的,我没有注意到您传播了“tmp”变量。道歉!
你说得对,那正是我的意图。
在所有情况下,我们都通过defun-q/setq/set将未赋值列表作为值绑定到符号。
或者,如果你指的是组装/定义实际函数的方法,那么为了构建它,我的语法更容易:
(defun define tests(/s1 s2 s3 s4 symdefun argsdefun)(setq;我们想要硬编码的变量s1“Hello”s2“hanhphuc”,s3“its me”,s4“Grrr!”);setq(foreach x(list;(list'f…)可以“简化”更多,但我不想破坏#4中的语法(因此你会失去轨迹)(list'test1(list'f s1 s2 s3 s4))(list'test2(list'f s2 s3 s4”“)(list'test3(list'f s1“from”s4”“));列表[;为了避免进一步混淆,将参数绑定到此处:(setq symdefun(car x))(setq argsdefun(cadr x));定义:(eval(append(list'defun-q symdefun));[颜色=“深绿色”] Ok, here goes offtopic...:sorry:
Agreed, well if I think about the worst case: if Autodesk decides for some reason to not upload a VBA enabler for the future ACAD versions..
then it would force you to run some MS Office application and thru its VBAIDE to execute your VB code (which would require to access the ACAD primary object).
I understand you... say you write this awesome VB program, and you provide it to your users with the words "but you have to download and install VBA enabler in order to use it".
The fact that this VB integrated editor is not built-in to ACAD (just like VLIDE) ...sucks.
Thanks for explaining, now I see the eventual advantages compared to our lovely LISP.
And I don't think this language will die soon, because:
[*]Reason1: The invested amount of recourses: the educating ones + soo many users themselves have written and use a ton of .lsp routines
[*]Reason2: Whats the purpose of a programming language? - Its for a human being to interact easier with the computer, in order to explain what hes trying to do (algorithm).
The fact that its so relatively easy to learn, for the cost of speed & limitations - makes it user-friendly and unique for the programmer.
Its like comparing bikes with cars - if cars can drive you further and faster, still then why we drive bikes?
Rlx, as a user myself I'll share with you my 'performance' criteria (by performance you mean how fast the program is it, right?).
That might be obvious but anyway:
It depends on how many times the certain function/program must be called per drawing session (to do a certain task).
For instance lets say the "LINE" and "PLOT" commands were customly made LISP functions - so normaly per drawing session say you would call "LINE" 200 times and "PLOT" just 3 times.
The time of your drawing session say would be an hour and a half.
A slight delay when invoking "LINE" would be noticable, due the frequent calls.. however if theres a noticable 2-3 sec delay for "PLOT" it should not be a big deal for you (unless the user is too demanding).
So thats the reason BIGAL keeps some reports (with a reactor) of every one in his office, about who's calling what commands how many times (ACAD stalker).
Thanks, alhough that was just a side task that yielded a side problem for me (nothing urgent) that sparkled this question.
I'll keep you guys informed if one day I came up with a solution for this.
You are correct, I did not notice that you propagated the 'tmp' variable. Apologies!
You are correct, that was exactly my intention.
Well in all cases we bound an unevaluated lists as a values to our symbols via defun-q/setq/set.
Or if you mean about the approach of assembling/defining the actual function - mine syntax is easier in order to build it:
(defun define-tests ( / s1 s2 s3 s4 symdefun argsdefun )(setq ; Our variables we would want to hardcode s1 "Hello " s2 "hanhphuc," s3 " its me," s4 " Grrr! :)" ); setq(foreach x (list ; (list 'f ...) can be 'simplified' more, but I didn't wanted to ruin the syntax from #4 (so you would loose track) (list 'test1 (list 'f s1 s2 s3 s4)) (list 'test2 (list 'f s2 s3 s4 "")) (list 'test3 (list 'f s1 "from" s4 "")) ); list ; Just to not confuse further, bound the args here: (setq symdefun (car x)) (setq argsdefun (cadr x)) ; Define: (eval (append (list 'defun-q symdefun) ;
页:
[1]