Hi,
i'm trying to export the schedule elements to Excel with the same order as it is in Revit Schedule. I retrieved the sorting field of the schedule and try to apply it to elements list with no luck. For now my goal is just to apply one sort/group field and apply multiple sorting condition as i progress. Hope someone can help me.
here is the schedule
here is my code which not working
private IEnumerable<Element> ScheduledElement(Document doc,ViewSchedule view) { var sort = (from ScheduleSortGroupField i in view.Definition.GetSortGroupFields() select view.Definition.GetField(i.FieldId)).First(); IEnumerable<Element> elementsOnSchedule = new FilteredElementCollector(doc, view.Id) .WhereElementIsNotElementType() .OrderBy(c => c.LookupParameter(sort.GetName())); return elementsOnSchedule; }
Thanks in advance
Hi,
i'm trying to export the schedule elements to Excel with the same order as it is in Revit Schedule. I retrieved the sorting field of the schedule and try to apply it to elements list with no luck. For now my goal is just to apply one sort/group field and apply multiple sorting condition as i progress. Hope someone can help me.
here is the schedule
here is my code which not working
private IEnumerable<Element> ScheduledElement(Document doc,ViewSchedule view) { var sort = (from ScheduleSortGroupField i in view.Definition.GetSortGroupFields() select view.Definition.GetField(i.FieldId)).First(); IEnumerable<Element> elementsOnSchedule = new FilteredElementCollector(doc, view.Id) .WhereElementIsNotElementType() .OrderBy(c => c.LookupParameter(sort.GetName())); return elementsOnSchedule; }
Thanks in advance
Fair59 presents a very comprehensive and well explained solution to Replicate Graphical Column Schedule Sort Order with C# by implementing a custom ColumnMarkComparer class implementing IComparer<FamilyInstance>.
I very strongly expect that you can implement something similar to solve your issue as well.
Fair59 presents a very comprehensive and well explained solution to Replicate Graphical Column Schedule Sort Order with C# by implementing a custom ColumnMarkComparer class implementing IComparer<FamilyInstance>.
I very strongly expect that you can implement something similar to solve your issue as well.
Hi @jeremytammik ,
i have manage to sort using IComparer. however, when field StrorageType is ElementId and String it gives me error. also i wonder how to get value for sorting if the sort/group field is not accessible in element parameter ( eg. Count, Calculated Field).
here is my code:
private List<Element> ScheduledElement(Document doc,ViewSchedule view) { List<Element> elementsOnSchedule = new FilteredElementCollector(doc, view.Id) .WhereElementIsNotElementType() .ToElements().ToList(); if(view.Definition.GetSortGroupFields().Count != 0) { elementsOnSchedule.Sort(new sortElement(view)); } return elementsOnSchedule; }
IComparer Class:
public class sortElement : IComparer<Element> { private ViewSchedule vs {get; set;} public sortElement(ViewSchedule view) { vs = view; } public int Compare(Element x, Element y) { var sortField = (from i in vs.Definition.GetSortGroupFields() select i).First(); var field = vs.Definition.GetField(sortField.FieldId); var Param1 = x.LookupParameter(field.GetName()); var Param2 = y.LookupParameter(field.GetName()); if (Param1.StorageType == StorageType.Integer) { return Param1.AsInteger().CompareTo(Param2.AsInteger()); } else if (Param1.StorageType == StorageType.Double) { return Param1.AsDouble().CompareTo(Param2.AsDouble()); } else if (Param1.StorageType == StorageType.String) { return Param1.AsString().CompareTo(Param2.AsString()); } else if (Param1.StorageType == StorageType.ElementId) { return Param1.AsValueString().CompareTo(Param2.AsValueString()); } return 0; } }
thanks for helping
Hi @jeremytammik ,
i have manage to sort using IComparer. however, when field StrorageType is ElementId and String it gives me error. also i wonder how to get value for sorting if the sort/group field is not accessible in element parameter ( eg. Count, Calculated Field).
here is my code:
private List<Element> ScheduledElement(Document doc,ViewSchedule view) { List<Element> elementsOnSchedule = new FilteredElementCollector(doc, view.Id) .WhereElementIsNotElementType() .ToElements().ToList(); if(view.Definition.GetSortGroupFields().Count != 0) { elementsOnSchedule.Sort(new sortElement(view)); } return elementsOnSchedule; }
IComparer Class:
public class sortElement : IComparer<Element> { private ViewSchedule vs {get; set;} public sortElement(ViewSchedule view) { vs = view; } public int Compare(Element x, Element y) { var sortField = (from i in vs.Definition.GetSortGroupFields() select i).First(); var field = vs.Definition.GetField(sortField.FieldId); var Param1 = x.LookupParameter(field.GetName()); var Param2 = y.LookupParameter(field.GetName()); if (Param1.StorageType == StorageType.Integer) { return Param1.AsInteger().CompareTo(Param2.AsInteger()); } else if (Param1.StorageType == StorageType.Double) { return Param1.AsDouble().CompareTo(Param2.AsDouble()); } else if (Param1.StorageType == StorageType.String) { return Param1.AsString().CompareTo(Param2.AsString()); } else if (Param1.StorageType == StorageType.ElementId) { return Param1.AsValueString().CompareTo(Param2.AsValueString()); } return 0; } }
thanks for helping
follow-up on ElementId and string error. i have figured out that i need to use string.compare.
😅
my only issue now is how to get value if the sort field is not accessible from element(eg. count, formula, etc.)
follow-up on ElementId and string error. i have figured out that i need to use string.compare.
😅
my only issue now is how to get value if the sort field is not accessible from element(eg. count, formula, etc.)
hi @Anonymous,
Hope below code will resolve your issue for grouping/sorting. You can change parameter value.
SchedulableField schedulableFieldForBaseLevel = def.GetSchedulableFields().FirstOrDefault(
sf => sf.ParameterId == new ElementId(BuiltInParameter.SCHEDULE_BASE_LEVEL_PARAM));
if (schedulableFieldForBaseLevel != null)
{
baseLevelField = def.AddField(schedulableFieldForBaseLevel);
}
if (baseLevelField != null)
{
var sortGroupField = new ScheduleSortGroupField(baseLevelField.FieldId);
sortGroupField.ShowHeader = true;
sortGroupField.SortOrder = ScheduleSortOrder.Ascending;
def.InsertSortGroupField(sortGroupField, 0);
}
hi @Anonymous,
Hope below code will resolve your issue for grouping/sorting. You can change parameter value.
SchedulableField schedulableFieldForBaseLevel = def.GetSchedulableFields().FirstOrDefault(
sf => sf.ParameterId == new ElementId(BuiltInParameter.SCHEDULE_BASE_LEVEL_PARAM));
if (schedulableFieldForBaseLevel != null)
{
baseLevelField = def.AddField(schedulableFieldForBaseLevel);
}
if (baseLevelField != null)
{
var sortGroupField = new ScheduleSortGroupField(baseLevelField.FieldId);
sortGroupField.ShowHeader = true;
sortGroupField.SortOrder = ScheduleSortOrder.Ascending;
def.InsertSortGroupField(sortGroupField, 0);
}
Can't find what you're looking for? Ask the community or share your knowledge.