pacificren 发表于 2007-2-8 10:35:00

用ActiveX方法在AutoCAD外操作块,请大家多帮助啊

<p>我使用的是C#的ActiveX方法操作AutoCAD的,同样的遍历实体方法,在AutoCAD之外与载入AutoCAD中有着天壤之别,当图元数多的时候非常慢。我的代码如下:</p><p>&nbsp;foreach (dbx.AcadEntity acadBF in doc.ModelSpace)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (acadBF.EntityName == "AcDbBlockReference")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbx.AcadBlockReference blkRef = (dbx.AcadBlockReference)acadBF;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (blkRef.Name.ToUpper() == "BTL")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[] atts = (object[])blkRef.GetAttributes();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//这锟梢匀〉锰崾咀侄?lt;/p&gt; </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; atts.Length; i++) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbx.AcadAttributeReference realattr = (dbx.AcadAttributeReference)atts;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (realattr.TagString == attrstr)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;realattr.TextString = valuestr;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc.Save();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc.Close(true,false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//app.Quit();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show("finish!");<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>我这样做是为了自动根据参数向一个图文件中填写块属性的,所以速度不能太慢。我现在正想做一个ARX命令作为填写属性的方法,在我的程序中调用。不知高手们还有没有更好的建议,比如能快速的找到图纸中的指定块(AcadBlockReference对象)。谢谢!</p><br/>

dfgs 发表于 2007-2-8 11:06:00

我想可以先用块名称得到一个选择集,这样就缩小了遍历的范围,再用for循环查找。

pacificren 发表于 2007-2-8 11:55:00

请<strong><font face="Verdana" color="#61b713">dfgs</font></strong>明示啊 写两句代码示范一下:)

dfgs 发表于 2007-2-8 16:51:00

C语言忘记得太多了,VBA中是<br/>dim ft(0 to 1) as integer<br/>dim fd(0 to 1) as varriant<br/>ft(0)=0<br/>fd(0)="Insert"<br/>ft(1)=2<br/>fd(1)="块名"<br/>s.select acselectionsetall,,,ft,fd<br/><br/><br/>我的问题从来没人回答,真郁闷<br/>

雪山飞狐_lzh 发表于 2007-2-8 21:17:00

<p>ObjectDBx里是没办法使用选择集的</p>

pacificren 发表于 2007-2-9 11:31:00

<p>感谢朋友们的支持!根据你们的提示,我写了如下代码:</p><p> short dtype = 100; <br/> IAcadSelectionSet sset = doc.SelectionSets.Add("ABC");<br/> sset.Select(dbx.AcSelect.acSelectionSetAll,null,null,dtype,"AcDbBlockReference");</p><p>我感觉我受不了了!总是提示Select方法的第4个参数FilterType类型不对,我就开始试了short、int、Int16、Int32、Int64都用上了,还是类型不对。疯了!我要改行!被这种问题捉弄真受不了!</p>

雪山飞狐_lzh 发表于 2007-2-10 17:58:00

FilterType类型:short[]

pacificren 发表于 2007-2-10 23:05:00

/// <summary>
/// 填写对应文件的BTL块的指定属性的值
/// </summary>
public void ReplaceSign(String attrstr,String valuestr)
{
   AutoCADConnector conn = new AutoCADConnector();
   app = conn.Application;
   IAcadDocument doc = app.Documents.Open(filepath,false,false);
   
   short[] filter = new short;
   filter = 100;
   filter = 2;
   Object[] dvalue = new Object;
   dvalue = "AcDbBlockReference";
   dvalue = "BTL";
   IAcadSelectionSet sset = doc.SelectionSets.Add("ABC");
   sset.Select(AcSelect.acSelectionSetAll,null,null,filter,dvalue);
   
   for (int i = 0;i<sset.Count;i++)
   {
    AcadBlockReference blkRef = (AcadBlockReference)sset.Item(i);
    object[] atts = (object[])blkRef.GetAttributes();
    for (int j = 0; j < atts.Length; j++)
    {
   AcadAttributeReference realattr = (AcadAttributeReference)atts;
   if (realattr.TagString == attrstr)
   {
      realattr.TextString = valuestr;
      doc.Save();
      doc.Close(true,false);
      MessageBox.Show("finish!");
      return;
   }
    }
   }
   doc.Close(false,false);
}
感谢lzh741206的提示!感谢同志们的帮助!感谢明经!这是我的完整方法代码,速度很快,共享了!(我发的图片都很正规,可惜版主还是无情的CUT了...)

页: [1]
查看完整版本: 用ActiveX方法在AutoCAD外操作块,请大家多帮助啊