Click here to Skip to main content
15,886,137 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to extract AutoCAD attribute block to excel


Excel Output[^]

My question is how to count duplicated items in array and add them to new column

What I have tried:

List<object[]> rooms = new List<object[]>();
            using (var tr = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject so in psr.Value)
                {
                    BlockReference bref = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead);                    
                    Autodesk.AutoCAD.DatabaseServices.AttributeCollection attcoll = bref.AttributeCollection;
                    object[] info = new object[4];
                    foreach (ObjectId id in attcoll)
                    {
                        AttributeReference atref = (AttributeReference)tr.GetObject(id, OpenMode.ForRead);

                        if (atref.Tag=="ROOM")
                        {
                            info[0] = atref.TextString;
                        }
                        if (atref.Tag=="ROOMID")
                        {
                            info[1] = atref.TextString;
                        }
                        if (atref.Tag=="ROOMAREA")
                        {
                            info[2] = atref.TextString;
                        }

                        if (!rooms.Contains(info))
                        {
                            rooms.Add(info);
                        }
                    }
                }
                tr.Commit();
            }
Posted
Comments
BillWoodruff 21-Feb-18 10:27am    
I don't see anything in your code that "counts." Define clearly what a "duplicate" is here.

1 solution

Instead of List<object[]> i'd use a Dictionary[^].

C#
Dictionary<string, int> myCounter = new Dictionary<string, int>();
using (var tr = db.TransactionManager.StartTransaction())
{
    foreach (SelectedObject so in psr.Value)
    {
        BlockReference bref = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead);                    
        Autodesk.AutoCAD.DatabaseServices.AttributeCollection attcoll = bref.AttributeCollection;
        foreach (ObjectId id in attcoll)
        {
            AttributeReference atref = (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
            if (atref.Tag.Contains("ROOM"))
                if (!myCounter.ContainsKey(atref.TextString))
                {
                    myCounter.Add(atref.TextString, 1);
                }
                else
                {
                    myCounter[atref.TextString] += 1; 
                }
        }
    }
}

//Dictionary object contains unique data with the number of occurences
Console.WriteLine("Key | Count");
foreach(var k in myCounter.Keys)
{
	Console.WriteLine("{0} | {1}", k, myCounter[k]);
}


Above code should return something like this:
Key | Count
ROOM | 5
ROOMID | 10
ROOMAREA | 15
 
Share this answer
 
v2
Comments
#realJSOP 21-Feb-18 13:20pm    
If you used a HashSet, you wouldn't need the line
if (!myCounter.ContainsKey(atref.TextString))
Trying to add an item that already exists in the HashSet collection would be ignored (without an exception being generated).
Maciej Los 21-Feb-18 13:29pm    
Good point!
Thank you, John. I'll use it next time ;)

[EDIT]
I've been trying to implement HashSet<CustomClass(Name, Count)> with IEqualityComparer<CustomClass>, but it does not satisfy me, because comparing objects by its name does not enables to increase count.
#realJSOP 21-Feb-18 14:21pm    
Why can't you use Linq to get the count of unique items within the collection?
Matt T Heffron 21-Feb-18 13:36pm    
But a HashSet won't give the count.
It is approximately equivalent to Dictionary<T, bool> but if the key is present the bool value is always true.
(Or am I missing something... ?)
Maciej Los 21-Feb-18 13:39pm    
Matt, maybe John wanted to point me to Hashtable :)
[EDIT]
Maybe not ;(
Hastable throws an error when key already exists.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900