箭头_Row 发表于 2024-4-15 01:17:06

C# 更新圖框日期工具

本帖最后由 箭头_Row 于 2024-4-15 01:59 编辑

功能介紹:更新圖框日期

三種不同圖框繪製方式:
一、以外部參照方式插入到dwg中;
二、以塊方式插入到dwg中;
三、以屬性塊方式插入到dwg中。

下述代碼中命令的大致書寫邏輯:
第一個命令適用于固定名稱的以外部參照插入到dwg中的方式,大型工裝項目的常規繪製方式;
第二個命令適配上述描述的三種不同繪製方式,且未有具體塊名的繪製方式,通用性更優。


具體詳見如下代碼:
如何優化下述代碼?感覺行數有點多,另未封裝及業務邏輯與具體的功能邏輯未完全區分開;


另:Env.Printl("\n图中无图框块,结束命令。");中可取消\n,因以往書寫習慣了,實際測試后對打印無影響,故未替換去除\n。

namespace ArrowTools;
public class UpdateTime
{
    public static string DateFormat => DateTime.Today.ToString("yyyy.MM.dd");
   
    public void CzV_Update_BlockRef_Time()
    {
      OpFilter filter = OpFilter.Build(e => e.Dxf(0) == "INSERT" & e.Dxf(2) == Layers.TK_Block);
      PromptSelectionResult psr = Env.Editor.SelectAll(filter);
      if (psr.Status != PromptStatus.OK)
      {
            Env.Printl("\n图中无图框块,结束命令。");
            return;
      }

      bool UnhaveDate = true;
      using DBTrans tr = new();
      foreach (var id in psr.Value.GetObjectIds())
      {
            var br = (BlockReference)tr.GetObject(id);
            var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord);
            if (btr.IsFromExternalReference)
            {
                using DBTrans trRef = new(btr.GetXrefDatabase(true).Filename);
                foreach (var idref in trRef.ModelSpace)
                {
                  var ent = trRef.GetObject(idref);

                  if (ent is DBText dBText)
                  {
                        bool isDateFormat = DateTime.TryParse(dBText.TextString, out _);
                        if (isDateFormat)
                        {
                            UnhaveDate = false;
                            if (dBText.TextString != DateFormat)
                            {
                              dBText.UpgradeOpen();
                              dBText.TextString = DateFormat;
                              dBText.DowngradeOpen();
                              trRef.Database.SaveAs(btr.GetXrefDatabase(true).Filename, DwgVersion.Current);

                              tr.XrefFactory(XrefModes.Reload); // 直接更新外部参照块
                              Env.Printl("\n日期已更新,且已重载外部参照!");
                              return;
                            }
                            else
                            {
                              Env.Printl("\n日期已为最新日期,不需更新!");
                              return;
                            }
                        }
                  }
                }
            }
      }

      // 如果上面没有返回结束,证明图框中日期格式错误!
      if (UnhaveDate)
            Env.Printl("\n图框中不包含日期,调整后重试!");
    }

   
    public void CzV_Update_SelectBlock_Time()
    {
      PromptEntityOptions entOpts = new("\n选择外部参照块或块(包含日期格式)");
      entOpts.SetRejectMessage("\n必须选择外部参照块或块。");
      entOpts.AddAllowedClass(typeof(BlockReference), false);

      PromptEntityResult per = Env.Editor.GetEntity(entOpts);
      if (per.Status != PromptStatus.OK)
      {
            Env.Printl("\n未选择图框块(包含日期格式),结束命令。");
            return;
      }

      bool UnhaveDate = true;
      using DBTrans tr = new();

      var br = (BlockReference)tr.GetObject(per.ObjectId);
      var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord);
      if (btr.IsFromExternalReference)
      {
            using DBTrans trRef = new(btr.GetXrefDatabase(true).Filename);
            foreach (var idref in trRef.ModelSpace)
            {
                var ent = trRef.GetObject(idref);

                if (ent is DBText dBText)
                {
                  bool isDateFormat = DateTime.TryParse(dBText.TextString, out _);
                  if (isDateFormat)
                  {
                        UnhaveDate = false;
                        if (dBText.TextString != DateFormat)
                        {
                            dBText.UpgradeOpen();
                            dBText.TextString = DateFormat;
                            dBText.DowngradeOpen();
                            trRef.Database.SaveAs(btr.GetXrefDatabase(true).Filename, DwgVersion.Current);

                            tr.XrefFactory(XrefModes.Reload); // 直接更新外部参照块
                            Env.Printl("\n日期已更新,且已重载外部参照!");
                            return;
                        }
                        else
                        {
                            Env.Printl("\n日期已为最新日期,不需更新!");
                            return;
                        }
                  }
                }
            }
      }
      else
      {
            foreach (var id in btr)
            {
                var ent = (Entity)tr.GetObject(id);

                if (ent is DBText dBText)
                {
                  bool isDateFormat = DateTime.TryParse(dBText.TextString, out _);
                  if (isDateFormat)
                  {
                        UnhaveDate = false;
                        if (dBText.TextString != DateFormat)
                        {
                            dBText.UpgradeOpen();
                            dBText.TextString = DateFormat;
                            dBText.DowngradeOpen();

                            tr.Editor?.Regen();
                            Env.Printl("\n日期已更新!");
                            return;
                        }
                        else
                        {
                            Env.Printl("\n日期已为最新日期,不需更新!");
                            return;
                        }
                  }
                }
            }
            if (br.AttributeCollection.Count > 0)
            {
                foreach (var attObj in br.GetAttributes())
                {
                  bool isDateFormat = DateTime.TryParse(attObj.TextString, out _);
                  if (isDateFormat)
                  {
                        OpFilter filter = OpFilter.Build(e => e.Dxf(0) == "INSERT" & e.Dxf(2) == br.Name);
                        PromptSelectionResult psr = Env.Editor.SelectAll(filter);

                        tr.UpdateBlockDate(psr.Value, attObj.Tag, out int dateEdeited, out int unEdeited);
                        if (dateEdeited > 0)
                        {
                            Env.Printl($"\n全图日期已更新数量:{dateEdeited}!");
                        }
                        else
                            Env.Printl("\n日期已为最新日期,不需更新!");
                        return;
                  }
                }
            }
      }

      // 如果上面没有返回结束,证明图框中日期格式错误!
      if (UnhaveDate)
            Env.Printl("\n图框中不包含日期,调整后重试!");
    }
}

public static class UpdateBlockTimes
{
    /// <summary>
    /// 更新圖框日期
    /// </summary>
    /// <param name="tr"></param>
    /// <param name="ss">選擇集結果</param>
    /// <param name="attTag">日期标签</param>
    /// <param name="dateEdeited">日期被修改數量</param>
    /// <param name="unEdeited">日期未被修改數量</param>
    public static void UpdateBlockDate(this DBTrans tr, SelectionSet ss, string attTag, out int dateEdeited, out int unEdeited)
    {
      dateEdeited = 0;
      unEdeited = 0;

      foreach (var id in ss.GetObjectIds())
      {
            var blkatt = (BlockReference)tr.GetObject(id, openMode: OpenMode.ForRead);

            if (blkatt.AttributeCollection.Count > 0)
                foreach (var attObj in blkatt.GetAttributes())
                {
                  if (attObj.Tag == attTag)
                  {
                        if (attObj.TextString != UpdateTime.DateFormat)
                        {
                            attObj.UpgradeOpen();
                            attObj.TextString = UpdateTime.DateFormat;
                            dateEdeited++;
                            attObj.DowngradeOpen();
                        }
                        else
                            unEdeited++;
                  }
                }
      }
    }
}



qq1254582201 发表于 2024-4-18 15:51:33

属性块,属性文字。字段自动更新你值得拥有

26140810 发表于 2024-4-15 01:32:54

lxl217114 发表于 2024-4-15 08:16:40

感谢分享,点赞有了

luzhmu 发表于 2024-4-15 10:24:03

感谢分享,点赞

mashanjie 发表于 2024-4-15 21:27:33

建议作者来个图示意一下:handshake那样会更直观

你有种再说一遍 发表于 2024-4-17 21:30:33

不要写过滤器了啊,难道你都不看我文章,直接多线程构造索引.

箭头_Row 发表于 2024-4-18 21:09:11

你有种再说一遍 发表于 2024-4-17 21:30
不要写过滤器了啊,难道你都不看我文章,直接多线程构造索引.

多線程構造索引在哪個帖子里?

箭头_Row 发表于 2024-4-18 21:12:14

qq1254582201 发表于 2024-4-18 15:51
属性块,属性文字。字段自动更新你值得拥有

問題是字段很多人不知道怎麼用,重新保存一次日期就會變,發給甲方或第三方老是投訴很煩。這個所見即所得。

你有种再说一遍 发表于 2024-4-18 22:08:05

箭头_Row 发表于 2024-4-18 21:09
多線程構造索引在哪個帖子里?

就是打开图纸事件上面写一个并行遍历句柄,获取全图的图元类型add到词典
页: [1]
查看完整版本: C# 更新圖框日期工具