sieben 发表于 2014-6-17 15:45:39

Dim trx1 As Transaction = dbInsert.TransactionManager.StartTransaction
            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)
自己细心点吧

fatkids 发表于 2014-6-17 17:02:32

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呢?

sieben 发表于 2014-6-17 17:25:34

哦,我忘记了你原来的意图,我前面的修改应该错了;
应该是两个文件,两个数据库,两个transaction和两个blocktable

sieben 发表于 2014-6-17 17:28:11

    /// <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(); }
    }

fatkids 发表于 2014-6-18 09:33:06

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:37:14

本帖最后由 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不要和文件中的图块重名!

fatkids 发表于 2014-6-26 16:02:38

raohuan 发表于 2014-6-21 19:37 static/image/common/back.gif
Database ndb = new Database(false, true);
try
{


感谢raohuan!
该方法效率较高,满足需要。
但是会在块的列表中多出一个以当前文档命名的块,这个可以在后面程序中进行处理。
谢谢!
另外一个帖子正在看。我加你qq了,有机会来玩啊。
页: 1 [2]
查看完整版本: 菜鸟求助:关于两个文档之间BlockReference复制的问题!