Hi All,
I need some help:
In Thorsten's original code, he was only counting the number of each block in a particular space; my problem is I need to count the number of each block that has a "Floor" attribute set to (for instance) "Floor G".
This left with the problem of how to store "BlockName, FloorName, AND Count"?
My solution for this was to create a Dictionary<TKey,TValue> using the following class as the TKey:
public class BomRow
{
public string BlockName { get; set; }
public string FloorName {get; set; }
}
This then presents me with the problem of how to check whether there is already a block with the BlockName "myblock1" and FloorName "Floor G".
In the preceding example from Thorsten he used this:
if(dict.ContainsKey(name)) dict[name]++;
else dict.Add(name,1);
But try as I might using:
public static void BCount()
{
var doc = AcadApp.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var dict = new Dictionary<string, int>();
var lst = new Dictionary<BomRow,int>();
var sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "INSERT") });
var pso = new PromptSelectionOptions();
pso.MessageForAdding = "Select blocks (or enter for all): ";
pso.AllowDuplicates = false;
var psr = ed.GetSelection(pso, sf);
// Error it's not, actually
if (psr.Status == PromptStatus.Error) psr = ed.SelectAll(sf);
// Ensure that the selection isn't empty
if (psr.Status == PromptStatus.OK && psr.Value.Count > 0)
{
using (var tr = db.TransactionManager.StartTransaction())
{
foreach (SelectedObject so in psr.Value)
{
var bref = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead);
var Floor = "";
var attrefcoll = bref.AttributeCollection;
if (attrefcoll.Count > 0)
{
foreach (ObjectId attrefid in attrefcoll)
{
var attref = (AttributeReference)tr.GetObject(attrefid, OpenMode.ForRead);
switch (attref.Tag)
{
case "FLOOR":
Floor = attref.TextString;
break;
}
}
}
string name;
try { name = bref.Name; }
catch { name = ""; };
var bomrow = new BomRow
{
BlockName = name,
FloorName = Floor,
};
//this next line simply doesn't work - and I don't know why!?
if (lst.ContainsKey(bomrow)) lst[bomrow]++;
else lst.Add(bomrow, 1);
if (dict.ContainsKey(name)) dict[name]++;
else dict.Add(name, 1);
}
tr.Commit();
}
var arr3 = Array.CreateInstance(typeof(object), lst.Count, 3);
var j = 0;
foreach (KeyValuePair<BomRow, int> entry in lst)
{
arr3.SetValue(entry.Key.BlockName, j, 0);
arr3.SetValue(entry.Key.FloorName, j, 1);
arr3.SetValue(entry.Value, j, 2);
j++;
}
//amended this line to include an extra column for my FloorName attribute.
BlockCountUtils.WriteToExcel(new object[] { "Block Name", "Floor Name", "Count" }, arr3);
}
}
public class BomRow
{
public string BlockName { get; set; }
public string FloorName {get; set; }
}
I always end up with a line for every block rather than a count of each block on each floor.
Can anyone shed any light on what I'm missing/doing wrong?