/
test_uralcp
/
columns_test
Обзор
Документация
Войти
/
test_uralcp
/
columns_test
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
master
ColumnDraft/CreateVRS.cs
276 строк
12 KB
Буравов Андрей Александрович
First BASH commit
28 ноя 2024, 12:50
28 ноя 2024, 12:50
0d2b500
Код
Авторство
О чём код?
using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.ExtensibleStorage; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using STP.ColumnDraft; using System; using System.Resources; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using System.IO; namespace ColumnDraft { internal class VRSCreator { static readonly int FirstValuesRowIndex = 5; public void CreateVRS(Document doc, ViewSheet sheet, ColumnData column, Element vrs, Transaction TRVRS) { TRVRS.Start(); //Получение всех таблиц FilteredElementCollector fec = new FilteredElementCollector(doc); List<string> schedulesNames = fec.OfClass(typeof(ViewSchedule)).Select(e => e.Name).ToList(); //Создание дубликата таблицы ViewSchedule vrsVS = vrs as ViewSchedule; ElementId steelScheduleId = vrsVS.Duplicate(ViewDuplicateOption.Duplicate); //Получение дубликата таблицы ViewSchedule steelSchedule = doc.GetElement(steelScheduleId) as ViewSchedule; ScheduleFieldId steelFilterField = null; //Создание уникального имени int steelN = 0; string steelBasisName = String.Format("{0} - ВРС", column.mark); while (schedulesNames.Contains(steelBasisName)) { if (steelN == 0) { steelBasisName = String.Format("{0} - ВРС(дубл.)", column.mark); } else { steelBasisName = String.Format("{0} - ВРС(дубл.{1})", column.mark, steelN); } if (steelN > 10) break; steelN++; } steelSchedule.Name = steelBasisName; //Поиск поля для присвоения значения текущей метки for (int i = 0; i < steelSchedule.Definition.GetFieldCount(); i++) { if (steelSchedule.Definition.GetField(i).GetName() == "Р.З._Метка основы") { steelFilterField = steelSchedule.Definition.GetFieldId(i); } } ScheduleFilter steelFilter = new ScheduleFilter(steelFilterField, ScheduleFilterType.Equal, column.mark); //Поиск фильтра int steelFilterIndex = -1; for (int i = 0; i < steelSchedule.Definition.GetFilterCount(); i++) { if (steelSchedule.Definition.GetFilter(i).FieldId.IntegerValue == steelFilterField.IntegerValue) { steelFilterIndex = i; } } //Если фильтр уже есть, то меняем значение, иначе добавляем фильтр if (steelFilterIndex >= 0) { steelSchedule.Definition.SetFilter(steelFilterIndex, steelFilter); } else steelSchedule.Definition.AddFilter(steelFilter); HashSet<string> VisibleColumnsWithAllCalculated; SteelScheduleColumn[] TableValuesWithAllCalculated; var TableValues = GetTableValues(steelSchedule, out var VisibleColumns); TRVRS.Commit(); TRVRS = new Transaction(doc, "Форматироване ВРС"); TRVRS.Start(); MakeAllCalculatedFieldsVisible(steelSchedule); steelSchedule.Document.Regenerate(); TableValuesWithAllCalculated = GetTableValues(steelSchedule, out VisibleColumnsWithAllCalculated); TRVRS.RollBack(); TRVRS.Start(); var schDef = steelSchedule.Definition; List<SteelScheduleColumn> visible0 = new List<SteelScheduleColumn>(); List<SteelScheduleColumn> notVisibleNot0 = new List<SteelScheduleColumn>(); foreach (var col in TableValues) if (!col.IsNonZeroColumn) visible0.Add(col); foreach (var col in TableValuesWithAllCalculated) { if (col.IsNonZeroColumn && !VisibleColumns.Contains(col.FullName)) notVisibleNot0.Add(col); } foreach (var col in visible0) schDef.GetField(col.fieldId).IsHidden = true; foreach (var col in notVisibleNot0) schDef.GetField(col.fieldId).IsHidden = false; ScheduleSheetInstance VRSInstance = ScheduleSheetInstance.Create(doc, sheet.Id, steelSchedule.Id, XYZ.Zero); BoundingBoxXYZ schBB = VRSInstance.get_BoundingBox(sheet); double ySize = schBB.Max.Y - schBB.Min.Y; double xSize = schBB.Max.X - schBB.Min.X; SizeData.VRSWidth = xSize; SizeData.VRSHeight = ySize; VRSInstance.Point = new XYZ( -(SizeData.Stamp.StampWidth + SizeData.Margins.HorizontalMargin + SizeData.VRSWidth), SizeData.SheetA1.Height - SizeData.Stamp.StampBorderWidth - SizeData.Margins.TopMarginVrs, 0 ); TRVRS.Commit(); } //Удаление пустых и нулевых столбцов static SteelScheduleColumn[] GetTableValues(ViewSchedule schedule, out HashSet<string> ColumnTitles) { ColumnTitles = new HashSet<string>(); var tableData = schedule.GetTableData().GetSectionData(SectionType.Body); var schDef = schedule.Definition; //все открытые столбцы по порядку var visibleCols = new List<ScheduleField>(); foreach (var o in schDef.GetFieldOrder()) { var f = schDef.GetField(o); if (!f.IsHidden) visibleCols.Add(f); } var AllVisibleFields = visibleCols.ToArray(); //Проверяем со второго столбца, первый - марка var result = new List<SteelScheduleColumn>(); var titles = new string[5]; for (int i = 1; i < AllVisibleFields.Length; i++) { var values = GetColumnValues(tableData, i); var newTitles = UpdateColumnTitles(tableData, titles, i); //если в знвчениях есть не пустая строка, которя не число - пропускаем if (newTitles.All(x => x == "")) continue; if (values.Any(x => !double.TryParse(x, out var parsedValue) && !string.IsNullOrEmpty(x))) continue; titles = newTitles; var newCol = new SteelScheduleColumn(AllVisibleFields[i], string.Join(" - ", titles), values); result.Add(newCol); ColumnTitles.Add(newCol.FullName); } return result.ToArray(); } struct SteelScheduleColumn { public readonly ScheduleFieldId fieldId; public readonly string FullName; public readonly bool IsNonZeroColumn; public readonly bool eightmmfield; public SteelScheduleColumn(ScheduleField field, string FullColumnName, string[] values) { fieldId = field.FieldId; FullName = FullColumnName; eightmmfield = false; //Если есть хоть одно значение, которое не пустая строка и не 0 - считаем, что столбец ненулевой IsNonZeroColumn = values.Any(x => (!double.TryParse(x, out var parsedValue) && !string.IsNullOrEmpty(x)) || parsedValue != 0); if (FullName == " - - - - ") { IsNonZeroColumn = true; eightmmfield = true; } } } /// <summary> /// Получение данных из одного столбца таблицы. /// </summary> /// <param name="tabData">Объект данных таблицы.</param> /// <param name="columnIndex"> Индекс получаемого столбца таблицы. </param> /// <remarks> /// </remarks> static string[] GetColumnValues(TableSectionData tabData, int columnIndex) { var valuesCount = tabData.NumberOfRows - FirstValuesRowIndex; if (valuesCount <= 0) throw new Exception("valuesCount <= 0"); var result = new string[valuesCount]; for (int i = 0; i < valuesCount; i++) result[i] = tabData.GetCellText(i + FirstValuesRowIndex, columnIndex); return result; } /// <summary> /// Метод получает полное название столбца (в ВРС оно многоступенчатое: тип арматуры, диаметр) /// </summary> /// <param name="tabData">Объект данных таблицы.</param> /// <param name="oldTitles"> Название предыдущего рассматриваемого столбца</param> /// <param name="columnIndex"> Индекс получаемого столбца таблицы. </param> /// <remarks> /// Примечание: В методе отдельно обрабатывается "столбец-костыль" - столбец шириной 2мм /// <br> для обеспечения ширины строк 8 мм.</br> /// <br>Для дальнейшей работы: если ширина срок стала неправильной,</br> /// вероятно, надо смотреть в название этого столбца, изменилось ли оно. /// </remarks> static string[] UpdateColumnTitles(TableSectionData tabData, string[] oldTitles, int columnIndex) { var newTitles = new string[5]; // сюда изначальные значения стоблцом поставим // чтобы потом проверить, что они не все нулевые var checkTitle = new string[5]; for (int i = 0; i < 5; i++) { checkTitle[i] = tabData.GetCellText(i, columnIndex); } bool isEmpty = checkTitle.All(x => x == ""); // если абсолютно целиком названия столбца пустые, это // столбец-костыль для обеспечения толщины строк 8 мми его // не надо менять или обрабатывать if (isEmpty) return checkTitle; // если не целиком - меняем for (int i = 0; i < 5; i++) { var currentValue = tabData.GetCellText(i, columnIndex); if (!string.IsNullOrEmpty(currentValue)) newTitles[i] = currentValue; else newTitles[i] = oldTitles[i]; } return newTitles; } /// <summary> /// Метод делает видимыми все рассчитываемые поля. /// </summary> /// <param name="schedule">Спецификация</param> /// <remarks> /// Примечание: этот метод - часть трюка с откатом транзакции. Получаем данные всех рассчитываемых /// <br>полей, если окажется, что в исходной спецификации скрытые поля имели значение >0, их откроем.</br> /// </remarks> static void MakeAllCalculatedFieldsVisible(ViewSchedule schedule) { var schDef = schedule.Definition; foreach (var o in schDef.GetFieldOrder()) { var f = schDef.GetField(o); if (f.IsHidden && f.IsCalculatedField) f.IsHidden = false; } } } }