Author Topic: Last group in drawing  (Read 9577 times)

0 Members and 1 Guest are viewing this topic.

BillZndl

  • Guest
Re: Last group in drawing
« Reply #15 on: October 05, 2009, 01:39:24 PM »
For some reason, if I open the group dialog, then just rename a group and hit okay,
the group dialog closes but the main modeless form remains dead.

Is there a better way to prevent working with the modeless form
while another dialog is up or if another command is running?


The better way is to use the finally statement :

private void button6_Click(object sender, EventArgs e)
        {
          try
           {
            if (Autodesk.AutoCAD.ApplicationServices.Application.IsQuiescent)
            {
                base.Enabled = false;
                OpenGroupCommandDialog.CallGroupCommand();
            }
           }
          catch (SytemException exception)
            {
              Message.Show{ blah blah blah};
             }
          finally
             {
              base.Enabled = true;
             }
        }

The finally statement is executed no matter what.
 :-)


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: Last group in drawing
« Reply #16 on: October 10, 2009, 06:42:47 AM »
try this and see if it works   :laugh:

Code: [Select]
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcEd = Autodesk.AutoCAD.EditorInput;

[assembly: CommandClass(typeof(ExecMethod.Commands))]

namespace ExecMethod
{
 public class Commands
 {
  [CommandMethod("lastgroup")]
  static public void lastgroup()
  {
   try
   {
    AcAp.Document activeDocument = AcAp.Application.DocumentManager.MdiActiveDocument;
    AcEd.Editor editor = activeDocument.Editor;
    AcDb.Database database = HostApplicationServices.WorkingDatabase;
    AcDb.TransactionManager manager = activeDocument.TransactionManager;
    List<Int64> handleVals = new List<Int64>();

    using(Transaction transaction = manager.StartTransaction())
    {
     AcDb.DBDictionary groupDictionary =
       transaction.GetObject(database.GroupDictionaryId, OpenMode.ForRead)
          as AcDb.DBDictionary;

     foreach(DBDictionaryEntry item in groupDictionary)
     {
       AcDb.Group group =
         transaction.GetObject(item.Value, OpenMode.ForRead)
           as AcDb.Group;
       if (group.NumEntities > 0)
        handleVals.Add(item.Value.Handle.Value);
     }

     if(handleVals.Count > 0)
     {
      handleVals.Sort();
      handleVals.Reverse();
      AcDb.Group lastgroup =
        transaction.GetObject(database.GetObjectId
          (false, new Handle(handleVals[0]), 0), OpenMode.ForRead)
             as AcDb.Group;

      editor.WriteMessage(lastgroup.Name);
     }
    }
   }
   catch (System.Exception ex)
   {
    AcAp.Application.DocumentManager.
      MdiActiveDocument.Editor.WriteMessage
       ("\n{0}\n{1}", ex.Message, ex.StackTrace);
   }
  }
 }
}
« Last Edit: October 10, 2009, 07:08:18 AM by Daniel »

BillZndl

  • Guest
Re: Last group in drawing
« Reply #17 on: October 12, 2009, 06:45:00 AM »
Thanks, but no it doesn't work.
I keep getting "DBDictionaryEntry could not be found" error.
Probably because I'm using VS2005 ex and net 2.0?



 

BillZndl

  • Guest
Re: Last group in drawing
« Reply #18 on: October 12, 2009, 11:25:21 AM »
try this and see if it works   :laugh:

Okay, now that I take a better look at it, this does simplify what I was doing.

I never would've thought to sort the handle values directly, then get the objectId of the group from the value.  :-o

This also eliminates the sorted list, which I understand is the same as using 2 arrays, so I'll assume for now that the List<int64> is a more efficient way to handle things, not to mention the reverse method which the sorted list doesn't have.

I chose to not check the group for number of entities as I list them even if empty

and to obtain the Object id using the GetAt method (don't know if it's better than opening for read or not, I'm thinking it is ^-^).

The DBDictionaryEntry = DictionaryEntry on my platform.

Oh, one question, why do I see some using:
Code: [Select]
Group grp = (Group)tr.GetObject(db.GetObjectId(false, new Handle(handleVals[0]), 0), OpenMode.ForRead) as Group;When it works without using the "as Group":
Code: [Select]
Group grp = (Group)tr.GetObject(db.GetObjectId(false, new Handle(handleVals[0]), 0), OpenMode.ForRead);

Thanks for the tips!

Here's what I end up with, any critique appreciated, just don't get too carried away!  8-)

Code: [Select]
using System;
using System.Collections;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;


namespace PartGroupsMonitor
{
    public class LastGroupInDrawing
    {
        public string FindLastGroup()
        {
          Document doc = AcadApp.DocumentManager.MdiActiveDocument;         
          Database db = HostApplicationServices.WorkingDatabase;
          List<Int64> handleVals = new List<Int64>();

          using (DocumentLock dloc = doc.LockDocument())
          {
              using (Transaction tr = db.TransactionManager.StartTransaction())
              {
                  DBDictionary groups = (DBDictionary)tr.GetObject(db.GroupDictionaryId, OpenMode.ForRead);
                  ObjectIdCollection objIDs = new ObjectIdCollection();

                  foreach (DictionaryEntry DicEnt in groups)
                  {
                      ObjectId Did = groups.GetAt(DicEnt.Key.ToString());                     
                      handleVals.Add(Did.Handle.Value);                     
                  }
                  if (handleVals.Count > 0)                     
                  {
                      handleVals.Sort();
                      handleVals.Reverse();
                      Group grp = (Group)tr.GetObject(db.GetObjectId(false, new Handle(handleVals[0]), 0), OpenMode.ForRead);

                      return grp.Name;
                  }
                  else
                  {
                      return "No";
                  }
              }           
          }
       }       
       
   }
}









It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: Last group in drawing
« Reply #19 on: October 12, 2009, 11:26:50 AM »
it's not a Visual Studio issue or a .NET issue, it's a managed library issue.
this should work with Acad05


Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.LayerManager;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Colors;

using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;


[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
 public class Commands
 {
  [CommandMethod("lastgroup")]
  static public void lastgroup()
  {
   try
   {
    AcAp.Document activeDocument = AcAp.Application.DocumentManager.MdiActiveDocument;
    AcDb.Database database = HostApplicationServices.WorkingDatabase;
    AcDb.TransactionManager manager = activeDocument.TransactionManager;
    List<Int64> handleVals = new List<Int64>();

    using (Transaction transaction = manager.StartTransaction())
    {
     AcDb.DBDictionary groupDictionary =
       transaction.GetObject(database.GroupDictionaryId, OpenMode.ForRead)
          as AcDb.DBDictionary;

     foreach (System.Collections.DictionaryEntry item in groupDictionary)
     {
      ObjectId id = (ObjectId)item.Value;
      AcDb.Group group =
        transaction.GetObject(id, OpenMode.ForRead)
          as AcDb.Group;
      if (group.NumEntities > 0)
       handleVals.Add(id.Handle.Value);
     }

     if (handleVals.Count > 0)
     {
      handleVals.Sort();
      handleVals.Reverse();
      Handle hnd = new Handle();
      hnd.Value = handleVals[0];
      AcDb.Group lastgroup =
        transaction.GetObject(database.GetObjectId
          (false, hnd, 0), OpenMode.ForRead)
             as AcDb.Group;

      AcAp.CommandLinePrompts.Message(lastgroup.Name);
     }
    }
   }
   catch (System.Exception ex)
   {
    AcAp.CommandLinePrompts.Message
     (String.Format("\n{0}\n{1}", ex.Message, ex.StackTrace));
   }
  }
 }
}


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: Last group in drawing
« Reply #20 on: October 12, 2009, 11:31:50 AM »
oops, I see you got it  :-)