Dim bt1 As BlockTable = dbInsert.BlockTableId.GetObject(OpenMode.ForRead)
----------------------------
Dim trx1 As Transaction = db.TransactionManager.StartTransaction
Dim bt1 As BlockTable = dbt.BlockTableId.GetObject(OpenMode.ForRead)
自己细心点吧 sieben 发表于 2014-6-17 15:45 static/image/common/back.gif
Dim trx1 As Transaction = dbInsert.TransactionManager.StartTransaction
Dim bt1 As Block ...
谢谢sieben!
你的意思是说两个transaction和两个blocktable都应该是一个文档的,是吗?
我是在两个文档之间复制blockreference,代码里分别为另个不同文档的transaction和blocktable。
是应该这样理解吗?怎么觉得有点怪怪的?
这样的话我该如何获取保存有blockreference的文档中的entity呢? 哦,我忘记了你原来的意图,我前面的修改应该错了;
应该是两个文件,两个数据库,两个transaction和两个blocktable /// <summary>
/// 使用一个新建的database从另外一个不打开的文件引入块记录
/// ImportBlock_DB里的ReadDwgFile方法在编译调试环境下会出错,错误为:尝试读取或写入受保护的内存
/// 但在正常AutoCAD启动装载程序情况下可用.
/// </summary>
/// <param name="fileName">另外一个文件的文件名</param>
/// <param name="blockName">引入的一个块记录名,若为空字符串"",将引入文件里面的全部图块</param>
/// <returns>成功返回true,否则返回false</returns>
static public StringCollection ImportBlock_DB(string fileName, string blockName)
{
if (!File.Exists(fileName)) return null;
Database sourceDb = new Database(false, true);
try
{
//se.WriteMessage("\nadb.ImportBlock_DB");
//下面的ReadDwgFile方法在编译调试环境下会出错,错误为:尝试读取或写入受保护的内存
//但在正常AutoCAD启动装载程序情况下可用.
sourceDb.ReadDwgFile(fileName, System.IO.FileShare.Read, false, "");
Database destDb = aApp.DocumentManager.MdiActiveDocument.Database;
ObjectIdCollection blockIds = new ObjectIdCollection();
StringCollection reValue = new StringCollection();
using (Transaction ctrans = sourceDb.TransactionManager.StartTransaction())
{
BlockTable cbt = (BlockTable)ctrans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);
if (blockName == "")
{
foreach (ObjectId btrId in cbt)
{
BlockTableRecord cbtr = (BlockTableRecord)ctrans.GetObject(btrId, OpenMode.ForRead, false);
if (!cbtr.IsAnonymous && !cbtr.IsLayout)
{
blockIds.Add(btrId);
reValue.Add(cbtr.Name);
}
cbtr.Dispose();
}
}
else if (cbt.Has(blockName))
{
blockIds.Add(cbt);
}
cbt.Dispose();
//ctrans.Commit();
}
if (blockIds.Count == 0)
{
return null;
}
else
{
IdMapping mapping = new IdMapping();
sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, new IdMapping(), DuplicateRecordCloning.Replace, false);
return reValue;
}
}
catch (System.Exception ex)
{
//se.WriteMessage("\nfileName = {0}, blockName = {1}", fileName, blockName);
se.WriteMessage(ex);
return null;
}
finally { sourceDb.Dispose(); }
} sieben 发表于 2014-6-17 17:28 static/image/common/back.gif
///
/// 使用一个新建的database从另外一个不打开的文件引入块记录
/// ImportBlock_DB里的 ...
多谢sieben!
我读了你的代码,觉得现在的方法关键应该在下面这里:
acCurDb.WblockCloneObjects(acObjIdColl, acBlkTblRecNewDoc.ObjectId, acIdMap, _
DuplicateRecordCloning.Ignore, False)
我该写了你的代码,改成VB.net的,代码如下:
Public Sub ImportBlock_DB()
Dim sourceDb As Database = New Database(False, True)
Try
' //se.WriteMessage("\nadb.ImportBlock_DB");
' //下面的ReadDwgFile方法在编译调试环境下会出错,错误为:尝试读取或写入受保护的内存
'//但在正常AutoCAD启动装载程序情况下可用.
Dim fileName As String = "C:\Program Files\AutoCAD 2010\Sample\Dynamic Blocks\Mechanical - Metric.dwg"
sourceDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndReadShare, False, "")
Dim destDb As Database = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database
Dim blockIds As ObjectIdCollection = New ObjectIdCollection()
' Dim reValue As StringCollection = New StringCollection()
Dim ctrans As Transaction = sourceDb.TransactionManager.StartTransaction()
Dim cbt As BlockTable = ctrans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False)
For Each btrId As ObjectId In cbt
Dim cbtr As BlockTableRecord = ctrans.GetObject(btrId, OpenMode.ForRead, False)
'If cbtr.IsAnonymous <> True And cbtr.IsLayout <> True Then
blockIds.Add(btrId)
cbtr.Dispose()
Next
cbt.Dispose()
Dim mapping As IdMapping = New IdMapping()
sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, New IdMapping(), DuplicateRecordCloning.Replace, False)
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
sourceDb.Dispose()
End Try
End Sub
代码执行完毕后,能够把需要的信息复制过来。但是AutoCAD会报错、死掉、退出,弹出发邮件到AutoDesk公司的窗口。
我想是因为这一句没写好:sourceDb.ReadDwgFile(fileName, System.IO.FileShare.Read, False, "")
我用的是AutoCAD2010 x64, ReadDwgFile的mode参数和你的不太一样。不知道我想的对不对!
为了不让AutoCAD死掉,我后面索性把需要的文档open,open后然后再把blocktable进行了复制,然后关掉文档。其方法就是你上面代码中提到的。
再次感谢Sieben。
本帖最后由 raohuan 于 2014-6-21 19:44 编辑
Database ndb = new Database(false, true);
try
{
ndb.ReadDwgFile(ExternalDwgFilelName, System.IO.FileShare.None, true, null);
db.Insert(FileName, ndb, false); //FileName:将外部文件以FileName为块名称合并到当前DWG数据库中,所以 FileName不要与其它块重名
}
catch (System.Exception ex)
{
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message);
return;
}
通过以上代码就将外部Dwg文件中的所有图块加到当前DWG中了,接下来的代码可直接调用。
注意,FileName不要和文件中的图块重名! raohuan 发表于 2014-6-21 19:37 static/image/common/back.gif
Database ndb = new Database(false, true);
try
{
感谢raohuan!
该方法效率较高,满足需要。
但是会在块的列表中多出一个以当前文档命名的块,这个可以在后面程序中进行处理。
谢谢!
另外一个帖子正在看。我加你qq了,有机会来玩啊。
页:
1
[2]