.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AutoCAD Table and Datalink

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
sabine
1550 Views, 6 Replies

AutoCAD Table and Datalink

Hi,

how can I find the ids of all Autocad tables and the associated datalinks in a drawing? I can't find the right filter for the selection. I now how to update update the datalinks, but I need the right ids.

 

I want to update all datalinks automatically to prevent this:

sabine_0-1587994770007.png

 

I have several tables in each drawing and it takes time to update alle data connections manualy.

 

Thanks

Sabine

6 REPLIES 6
Message 2 of 7
Alexander.Rivilis
in reply to: sabine

This sample can help you:

 

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcEd = Autodesk.AutoCAD.EditorInput;
 
[assembly: CommandClass(typeof(TestUnref.MyCommands))]
 
namespace TestUnref
{
  public class MyCommands
  {
    // Print name of unused/unreferenced DataLink's
    [CommandMethod("TestUnrefDlink")]
    public void TestUnrefDlink()
    {
      AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
      AcDb.Database db = doc.Database;
      AcEd.Editor ed = doc.Editor;
      AcDb.ObjectIdCollection ids = new AcDb.ObjectIdCollection();
      // Имена DataLink
      ed.WriteMessage("\nUnused/Unreferenced DataLink: ");
      AcDb.ObjectId idLinkDict = db.DataLinkDictionaryId;
      if (!idLinkDict.IsNull) {
        using (AcDb.DBDictionary dLinkDict = db.DataLinkDictionaryId.Open(OpenMode.ForRead) as AcDb.DBDictionary) {
          foreach (AcDb.DBDictionaryEntry ent in dLinkDict) ids.Add(ent.Value);
        }
        foreach (AcDb.ObjectId id in ids) {
          using (AcDb.DataLink dLink = id.Open(OpenMode.ForRead) as AcDb.DataLink) {
            bool bIsValid = true;
            if (!dLink.IsValid) {
              bIsValid = false;
            } else {
              bIsValid = false;
              foreach (AcDb.ObjectId id_target in dLink.GetTargets()) {
                if (id_target.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AcDb.Entity)))) {
                  bIsValid = true;
                  break;
                }
              }
            }
            if (!bIsValid) {
              ed.WriteMessage("\n\tName={0} Link={1}", dLink.Name, dLink.ConnectionString);
              dLink.UpgradeOpen();
              dLink.Erase(); // Delete it
            }
          }
        }
      }
    }
  }
}

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 3 of 7
norman.yuan
in reply to: sabine

If your issue is that the DataLinks in the drawing are out of sync (linked Excel sheet file has been moved, for example) (sorry, I do not know the language showing in your attached picture), then, there is no need to deal with tables at all. You simply use Database.DataLinkDinctionaryId to open the DataLinkDictionary and loop through each DataLink to see if the linked source file exists; if not you update the link's source file path while you can.

 

This discussion thread might be of help:

https://forums.autodesk.com/t5/visual-basic-customization/how-do-i-re-path-data-links-using-vba-with... 

 

If you really want to deal with table that uses DataLink, for example, you want to change the DatatLink to this table to a new one, or you want to knowwhich DataLink a table is linked, you can call

 

Table.GetDataLink()

Table.SetDataLink()

 

HTH

 

Norman Yuan

Drive CAD With Code

EESignature

Message 4 of 7
sabine
in reply to: norman.yuan

After I moved to AutoCAD 2020 this problem occured. I had this problem never bevor. I could load a block with the new table and an existing table and the datalink was working fine.

But now I must open the xref and have to update the dataconnection by right-clicking on the warning. The warning means "Reload necessary". After that the dataconnection works fine and the problems are gone.

 

Sabine

Message 5 of 7
norman.yuan
in reply to: sabine

Well, I am not sure what have happened to your drawings/AutoCAD 2020 move, from your short description. Now that you post in .NET programming forum, I assume you want to implement some kind of fix by .NET code. If so, as I suggested in previous reply, you use code to loop through DataLinks in drawing, check the source path, if not matched, you need to repath it. If the source file is there, you can simply call DataLink.Update() to have it "reloaded".

 

Norman Yuan

Drive CAD With Code

EESignature

Message 6 of 7
sabine
in reply to: norman.yuan

That's my plan.  🙂

 

Thanks

Sabine

Message 7 of 7
sabine
in reply to: Alexander.Rivilis

Thanks Alexander! Your code helped me to write a solution for my problem. Here is my working result:

 

public static void ReloadTable()
{
  Autodesk.AutoCAD.ApplicationServices.Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  Database acCurDb = acDoc.Database;
  Editor ed = acDoc.Editor;
  
  ObjectIdCollection ids = new ObjectIdCollection();
  ObjectId idLinkDict = acCurDb.DataLinkDictionaryId;
  
  try
  {
    using (Autodesk.AutoCAD.DatabaseServices.Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
    {
      if (!idLinkDict.IsNull)
      {
        DBDictionary dLinkDict = (DBDictionary)acTrans.GetObject(idLinkDict, OpenMode.ForRead);
        foreach (DBDictionaryEntry ent in dLinkDict)
        {
          ids.Add(ent.Value);
        }
        
        foreach (ObjectId id in ids)
        {
          DataLink dLink = (DataLink)acTrans.GetObject(id, OpenMode.ForWrite);
          bool bIsValid = true;
          if (!dLink.IsValid)
          {
            bIsValid = false;
          }
          else
          {
            bIsValid = false;
            foreach (ObjectId id_target in dLink.GetTargets())
            {
              if (id_target.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Entity))))
              {
                bIsValid = true;
                break;
              }
            }
          }
          if (bIsValid)
          {
            dLink.Update(UpdateDirection.SourceToData, UpdateOption.None);
          }
        }
      }
      acTrans.Commit();
    }
  }
  catch (System.Exception ex)
  {
    MessageBox.Show(ex.Message);
  }
}

 

Sabine

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report