Document.CloseAndDiscard()关闭文档的问题
本帖最后由 sealive 于 2014-8-13 19:04 编辑代码如下:
<CommandMethod("CLA", CommandFlags.Session)> Public Sub CloseAll()
Dim FileNames() = {"c:\drawing1.dwg", "c:\drawing2.dwg", "c:\drawing3.dwg"}
For Each FileName As String In FileNames
Application.DocumentManager.Open(FileName, False)
Zoom(New Point3d(), New Point3d(), New Point3d(), 1.01075)
Dim db As Database = HostApplicationServices.WorkingDatabase
Using Trans As Transaction = db.TransactionManager.StartTransaction()
db.SaveAs(db.Filename, True, DwgVersion.Current, db.SecurityParameters)
Trans.Commit()
End Using
db.Dispose()
Next
For Each acDoc As Document In Application.DocumentManager
acDoc.CloseAndDiscard()
Next
End Sub
用上面的代码连续打开多张图纸,执行ZOOM操作后保存文件,无论是在保存后的循环里关闭文件,还是单独再开一个循环关闭文档,都会产生致命的错误导致CAD程序崩溃。逐步调试时发现,for each acDoc As Documentin Application.DocumentManager取得的acDoc变量值在循环到新打开的图时值会变为“变量未指定到对象的实例”的信息,而在执行CLA命令前已经打开的文档就不存此问题,且可以成功关闭,不知道原因是什么?(关闭当前活动的文档有问题吗?)
也试过acDoc.SendStringToExcute("CLOSE" & vbcr,false,true,true)方法,也不成功,提示为:eNoDocument。 文档锁上 是这样:For Each acDoc As Document In Application.DocumentManager
Using LockDoc As DocumentLock = acDoc.LockDocument()
acDoc.CloseAndDiscard()
End Using
Next
还是直接:Dim FileNames() = {"c:\drawing1.dwg", "c:\drawing2.dwg", "c:\drawing3.dwg"}
For Each FileName As String In FileNames
Dim acDoc As Document = Application.DocumentManager.Open(FileName, False)
Zoom(New Point3d(), New Point3d(), New Point3d(), 1.01075)
Using LockDoc As DocumentLock = acDoc.LockDocument()
Dim db As Database = HostApplicationServices.WorkingDatabase
Using Trans As Transaction = db.TransactionManager.StartTransaction()
db.SaveAs(db.Filename, True, DwgVersion.Current, db.SecurityParameters)
Trans.Commit()
End Using
db.Dispose()
acDoc.CloseAndDiscard()
End Using
Next
好像不行! Zoom也锁住试试 本帖最后由 sealive 于 2014-8-13 21:52 编辑
问题好像不在锁,打开多个文件和保存以及关闭都在一个定义命令中,命令始终在执行之中,这时去访问DocumentCollection文档的数量是对的,但新打开的文件好像ACAD的主程序无法获得其document对象。看过kean的批量关闭文档,没有锁,可以成功。唯一的区别是我的文档也是用程序批量打开(而kean的例子里批量关闭的文档是提前手工打开的),缩放后保存,又要批量关闭。就出错了。 我觉得是可行的 只是没找到正确的路 呵呵
先设置文档集合的当前文档试试。
而且你要最先锁当前文档 本帖最后由 sealive 于 2014-8-15 18:17 编辑
试过了,我觉得这应该是acad的一个bug(只是打开了文档而没用把文档加入到DocumentManager集合,导致访问集合时无对象的实例)(锁文档会提示eNoDocument),如果文档是手工打开的而不是程序打开的,上面的方法不用锁文档都可以执行,而程序打开就不行。程序打开文档后,去查询documentCollection的count属性还是在运行命令前文档的数目,新打开的没有计算在内,新打开的文档对象提示“未将对象设置到引用对象的实例”。此时退出命令,程序打开的文档都在,此时单独用程序执行close,仍然无法获得新打开的文档对象的实例。后来没办法改用com顺利解决了此问题。
事实证明我错了,自己程序有bug!看10楼。但com的方法缩放,关闭文档确实比.net方便些! 实在不行先用teigha吧 进程外用com也行 本帖最后由 sealive 于 2014-8-15 18:19 编辑
今天又测试了一下,是调用Autocad.net手册上的zoom函数的问题,虽然外面锁定文件但标准的zoom函数内也再访问document对象,修改了函数的定义,把document对象按地址作为参数传入到zoom函数,然后锁定文档问题解决了。看来是理解的问题,呵呵!
Dim FileNames() = {"c:\drawing1.dwg", "c:\drawing2.dwg", "c:\drawing3.dwg"}
For Each FileName As String In FileNames
Dim acDoc As Document = Application.DocumentManager.Open(FileName, False)
Using docLock as Document=Application.DocumentManager.MdiActiveDocument.LockDocument()
Zoom(acDoc,New Point3d(), New Point3d(), New Point3d(), 1.01075)
Dim db As Database = HostApplicationServices.WorkingDatabase
Using Trans As Transaction = db.TransactionManager.StartTransaction()
db.SaveAs(db.Filename, True, DwgVersion.Current, db.SecurityParameters)
Trans.Commit()
End Using
db.Dispose()
End Using
acDoc.CloseAndDiscard()
Next
谢谢版主的指点!
页:
[1]
2