创建一个计数循环 C#
Create a count loop c#
我正在使用 C# 通过 REVIT 创建宏。我想做的是按特定顺序对对象进行编号,它们按放置级别排序。我希望代码循环遍历第一级,对对象进行计数并对其进行编号,然后转到第二级进行计数并使用之前级别的引用开始编号
例如,如果第一组对象的编号从 1 到 10,那么下一组对象将从 11 开始编号,直到这组新对象的计数为止,所以如果它们是 5,则编号将一直到 15,依此类推
这是我试过的代码。问题是编号现在每次都从 1 开始。
public void UniqueTag()
{
Document document = Application.ActiveUIDocument.Document;
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> AllWindows = collector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).ToList(); // gets only placed instances
Transaction tran = new Transaction(document, "Tags Modification");
tran.Start();
int start = 1;
foreach (Element window in AllWindows)
{
string WindowLevel = window.LookupParameter("Level").AsValueString();
FilteredElementCollector LevelCollector = new FilteredElementCollector(document);
ICollection<Element> levels = LevelCollector.OfClass(typeof(Level)).ToElements();
foreach (Level le in levels)
{
var LevelName = le.Name;
if (WindowLevel == LevelName)
{
var query = from element in LevelCollector where element.Name == LevelName select element;
List<Element> level = query.ToList<Element>();
ElementId levelId = level[0].Id;
ElementLevelFilter levelFilter = new ElementLevelFilter(levelId);
LevelCollector = new FilteredElementCollector(document);
ICollection<Element> allWindowssOnLevel = LevelCollector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).WherePasses(levelFilter).ToElements();
int count = allWindowssOnLevel.Count;
for (int i = start; i <= count ; i++) // work correct for the first loop, need to be changed for the second loop
{
foreach (Element e in allWindowssOnLevel)
{
var tag = e.GetParameters("Tag#")[0].Set(i++);
start=count+1;
}//End of foreach allWindowssOnLevel
}//End of for
}//End of if
}//End of foreach levels
}//End of foreachAllWindows
tran.Commit();
} // End of UniqueTag
更新
这个版本的代码在所有循环之外开始计数,在第一级正确编号 windows 然后跳过第二级,在第三级从最后一个标签开始正确编号 windows +1。如果在第三个之后有更多级别,其中 windows 的 none 会被编号。
我认为您的错误在于您将标记 # 设为循环的本地。您应该在所有循环之外声明 int
,因为您希望在循环层内修改它。事实上,你将它设置为在每个级别从 1 开始,这是你所有问题的根源。
我还看到我认为是整个循环的轻微结构错误:您的第一个循环是查看整个文档中的每个 window。然后,你看水平,然后你回头看水平上的windows。这意味着您要查看每个 Element
至少 两次。不仅如此,您还将执行一个可能非常长的循环。如果你有 15 个级别,每个级别有 50 windows,这意味着你将按如下方式执行:
foreach (Element window in AllWindows) //750 iterations
{
foreach (Level le in levels) //15 iterations
{
for (int i = start; i <= count ; i++) //50 iterations
{
foreach ((Element e in allWindowssOnLevel) //50 iterations
{ //It should also be noted that this is going through the same set of elements as the for loop.
当您完成最后的 foreach
循环时,您已经完成了 50 次迭代;在 for
循环结束时 - 2500 次迭代;在 foreach (Level le in levels)
循环结束时 - 37,500 次迭代;到 foreach (Element window in AllWindows)
循环结束时 - 28,125,000 次迭代。全部到 750 windows。我认为您应该将其细化为 类似 :
的内容
int iCtr = 1;
foreach (Level le in levels)
{
var query = from element in LevelCollector where element.Name == LevelName select element;
List<Element> level = query.ToList<Element>();
ElementId levelId = level[0].Id;
ElementLevelFilter levelFilter = new ElementLevelFilter(levelId);
var LevelCollector = new FilteredElementCollector(document);
ICollection<Element> allWindowssOnLevel = LevelCollector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).WherePasses(levelFilter).ToElements();
foreach (Element pElt in allWindowsOnLevel)
{
var tag = e.GetParameters("Tag#")[0].Set(iCtr);
iCtr+=1; //only increments when we set a tag #
} //End of foreach - only runs #OfWindowsOnLevel times/level
}//end of foreach (Level ... ) - only runs #OfLevels
//if we had 15 floor of 50 windows, we only looped 750 times - not 28mil...
希望对您有所帮助。我不得不经常处理 Revit 中的节点标签,这并不总是那么容易。
我正在使用 C# 通过 REVIT 创建宏。我想做的是按特定顺序对对象进行编号,它们按放置级别排序。我希望代码循环遍历第一级,对对象进行计数并对其进行编号,然后转到第二级进行计数并使用之前级别的引用开始编号 例如,如果第一组对象的编号从 1 到 10,那么下一组对象将从 11 开始编号,直到这组新对象的计数为止,所以如果它们是 5,则编号将一直到 15,依此类推
这是我试过的代码。问题是编号现在每次都从 1 开始。
public void UniqueTag()
{
Document document = Application.ActiveUIDocument.Document;
FilteredElementCollector collector = new FilteredElementCollector(document);
IList<Element> AllWindows = collector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).ToList(); // gets only placed instances
Transaction tran = new Transaction(document, "Tags Modification");
tran.Start();
int start = 1;
foreach (Element window in AllWindows)
{
string WindowLevel = window.LookupParameter("Level").AsValueString();
FilteredElementCollector LevelCollector = new FilteredElementCollector(document);
ICollection<Element> levels = LevelCollector.OfClass(typeof(Level)).ToElements();
foreach (Level le in levels)
{
var LevelName = le.Name;
if (WindowLevel == LevelName)
{
var query = from element in LevelCollector where element.Name == LevelName select element;
List<Element> level = query.ToList<Element>();
ElementId levelId = level[0].Id;
ElementLevelFilter levelFilter = new ElementLevelFilter(levelId);
LevelCollector = new FilteredElementCollector(document);
ICollection<Element> allWindowssOnLevel = LevelCollector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).WherePasses(levelFilter).ToElements();
int count = allWindowssOnLevel.Count;
for (int i = start; i <= count ; i++) // work correct for the first loop, need to be changed for the second loop
{
foreach (Element e in allWindowssOnLevel)
{
var tag = e.GetParameters("Tag#")[0].Set(i++);
start=count+1;
}//End of foreach allWindowssOnLevel
}//End of for
}//End of if
}//End of foreach levels
}//End of foreachAllWindows
tran.Commit();
} // End of UniqueTag
更新 这个版本的代码在所有循环之外开始计数,在第一级正确编号 windows 然后跳过第二级,在第三级从最后一个标签开始正确编号 windows +1。如果在第三个之后有更多级别,其中 windows 的 none 会被编号。
我认为您的错误在于您将标记 # 设为循环的本地。您应该在所有循环之外声明 int
,因为您希望在循环层内修改它。事实上,你将它设置为在每个级别从 1 开始,这是你所有问题的根源。
我还看到我认为是整个循环的轻微结构错误:您的第一个循环是查看整个文档中的每个 window。然后,你看水平,然后你回头看水平上的windows。这意味着您要查看每个 Element
至少 两次。不仅如此,您还将执行一个可能非常长的循环。如果你有 15 个级别,每个级别有 50 windows,这意味着你将按如下方式执行:
foreach (Element window in AllWindows) //750 iterations
{
foreach (Level le in levels) //15 iterations
{
for (int i = start; i <= count ; i++) //50 iterations
{
foreach ((Element e in allWindowssOnLevel) //50 iterations
{ //It should also be noted that this is going through the same set of elements as the for loop.
当您完成最后的 foreach
循环时,您已经完成了 50 次迭代;在 for
循环结束时 - 2500 次迭代;在 foreach (Level le in levels)
循环结束时 - 37,500 次迭代;到 foreach (Element window in AllWindows)
循环结束时 - 28,125,000 次迭代。全部到 750 windows。我认为您应该将其细化为 类似 :
int iCtr = 1;
foreach (Level le in levels)
{
var query = from element in LevelCollector where element.Name == LevelName select element;
List<Element> level = query.ToList<Element>();
ElementId levelId = level[0].Id;
ElementLevelFilter levelFilter = new ElementLevelFilter(levelId);
var LevelCollector = new FilteredElementCollector(document);
ICollection<Element> allWindowssOnLevel = LevelCollector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance)).WherePasses(levelFilter).ToElements();
foreach (Element pElt in allWindowsOnLevel)
{
var tag = e.GetParameters("Tag#")[0].Set(iCtr);
iCtr+=1; //only increments when we set a tag #
} //End of foreach - only runs #OfWindowsOnLevel times/level
}//end of foreach (Level ... ) - only runs #OfLevels
//if we had 15 floor of 50 windows, we only looped 750 times - not 28mil...
希望对您有所帮助。我不得不经常处理 Revit 中的节点标签,这并不总是那么容易。