using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Windows; using Autodesk.Revit.DB; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Win32; using MiniExcelLibs.Attributes; using Nice3point.Revit.Toolkit.External.Handlers; using ShrlAlgoToolkit.RevitAddins; using ShrlAlgoToolkit.RevitAddins.Common.Assists; using ShrlAlgoToolkit.RevitAddins.Common.Extensions; namespace ShrlAlgoToolkit.RevitAddins.Standardizer; public partial class WriteParametersViewModel : ObservableObject { public WriteParametersViewModel(UIDocument uIDocument) { this.uiDocument = uIDocument; } private readonly ActionEventHandler handler = new(); [ObservableProperty] private bool isSelectedItems; [ObservableProperty] private bool isOverride; //record class ParameterModel(string Name, object Value); [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(ExportExcelCommand))] [NotifyCanExecuteChangedFor(nameof(WriteParamsCommand))] private List items; [ObservableProperty] private string excelPath; private readonly UIDocument uiDocument; private bool HasItems => Items?.Any() == true; [RelayCommand] private void GetParams() { Items = null; List models = []; Document doc = uiDocument.Document; try { Reference reference = uiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择提取参数的元素"); Element elem = doc.GetElement(reference); foreach (Parameter param in elem.Parameters) { if (!param.HasValue || string.IsNullOrEmpty(param.AsString())) { models.Add(new ParameterModel() { Name = param.Definition.Name }); } } Items = models.OrderBy(m => m.Name).ToList(); } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { } } [RelayCommand] private void OpenExcel() { if (ExcelPath.StartsWith("\"")) { ExcelPath = ExcelPath.TrimStart('\"'); } if (ExcelPath.EndsWith("\"")) { ExcelPath = ExcelPath.TrimEnd('\"'); } if (File.Exists(ExcelPath)) { FileInfo file = new(ExcelPath); if (file.Extension != ".xlsx") { MessageBox.Show("请选择xlsx格式的Excel文件"); } else { ReadExcel(ExcelPath); } } else { MessageBox.Show("文件路径有误"); } } [RelayCommand(CanExecute = nameof(HasItems))] private void ExportExcel() { SaveFileDialog dialog = new() { Filter = "Excel文件(xlsx)|*.xlsx", InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), }; if (dialog.ShowDialog() != true) { return; } string excel = dialog.FileName; FileInfo fi = new(excel); Dictionary data = new() { { "参数表", Items } }; data.SaveAsExcel(excel); MessageBoxResult result = MessageBox.Show("是否打开Excel表?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Process.Start(excel); } } [RelayCommand(CanExecute = nameof(HasItems))] private void WriteParams() { Document doc = uiDocument.Document; List elements = IsSelectedItems ? uiDocument.Selection.GetElementIds().Select(id => doc.GetElement(id)).ToList() : new FilteredElementCollector(doc, doc.ActiveView.Id) .WhereElementIsNotElementType() .ToElements() .Where( e => e.CanHaveTypeAssigned() && e.HasPhases() && e.get_BoundingBox(doc.ActiveView) != null && e.Category is { Parent: null, CategoryType: CategoryType.Model } ) .ToList(); StringBuilder sb = new(); handler.Raise(_ => { using (TransactionGroup transG = new(doc, "填写属性值")) { transG.Start(); foreach (Element elem in elements) { if (!elem.IsValidObject) { continue; } using Transaction trans = new(doc, "填写属性值"); //FailureHandlingOptions options = trans.GetFailureHandlingOptions(); //FailuresPreProcessor failuresProcessor = new(); //options.SetFailuresPreprocessor(failuresProcessor); //trans.SetFailureHandlingOptions(options); trans.Start(); Regex regex = new(@"^\D{2}-\d00"); //将“”空值填写“/” foreach (Parameter parameter in elem.Parameters) { //if (parameter.Definition.Name == "ID-100-编号") //{ // continue; //} //不为空时,跳过设置“/” if (!(string.IsNullOrEmpty(parameter.AsString()) && string.IsNullOrEmpty(parameter.AsValueString()))) { continue; } if (regex.IsMatch(parameter.Definition.Name) && !parameter.IsReadOnly) { if (parameter.StorageType is StorageType.Integer or StorageType.Double) { parameter.Set(0); } if (parameter.StorageType == StorageType.String) { parameter.Set("/"); } } } doc.Regenerate(); //填写表单中的数据 foreach (ParameterModel item in Items) { Parameter p1 = elem.GetParameters(item.Name).FirstOrDefault(); if (p1 == null) { sb.AppendLine($"构件类别:{elem.Category};构件名:{elem.Name};构件ID:{elem.Id};参数名:{item.Name};异常原因:参数不存在"); continue; } //if (p1.Definition.Name == "ID-100-编号") //{ // continue; //} try { if ( IsOverride || (p1.AsString() == "/" || p1.AsValueString() == "/") || (p1.AsString() == "0" || p1.AsValueString() == "0") ) //如果覆盖则填写,否则不操作 { if (p1?.IsReadOnly == false) { switch (p1.StorageType) { case StorageType.None: break; case StorageType.Integer: p1.Set(Convert.ToInt16(item.Value)); break; case StorageType.Double: p1.Set(Convert.ToDouble(item.Value)); break; case StorageType.String: p1.Set(Convert.ToString(item.Value)); break; case StorageType.ElementId: break; } } } //if (p1?.IsReadOnly == false) //{ // switch (p1.StorageType) // { // case StorageType.None: // break; // case StorageType.Integer: // p1.Set(Convert.ToInt16(item.Value)); // break; // case StorageType.Double: // p1.Set(Convert.ToDouble(item.Value)); // break; // case StorageType.String: // p1.Set(Convert.ToString(item.Value)); // break; // case StorageType.ElementId: // break; // } //} } catch (Exception exception) { sb.AppendLine( $"构件类别:{elem.Category};构件名:{elem.Name};构件ID:{elem.Id};参数名:{p1.Definition.Name};异常原因:{exception.Message}" ); } } trans.Commit(); } transG.Assimilate(); } if (sb.Length > 0) { LogAssist.WriteTextFile( sb.ToString(), "修改异常问题"); } MessageBox.Show("修改参数完成!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); }); } [RelayCommand] private void BrowserExcelFile() { OpenFileDialog dialog = new() { CheckFileExists = true, Filter = "Excel文件(*.xlsx)|*.xlsx", Multiselect = false, InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), }; if (dialog.ShowDialog() != true) { return; } //Items?.Clear(); ExcelPath = dialog.FileName; ReadExcel(dialog.FileName); } private void ReadExcel(string path) { Items= [.. path.ReadExcel()]; } private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) { if (!args.Name.Contains("ComponentModel.Annotations")) { return null; } string assemblyFile = Path.Combine(Variables.DirAssembly, "System.ComponentModel.Annotations.dll"); return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null; } [RelayCommand] private void Init(int index) { if (index == 0) { Items = GetInitCivilParameterList(); } else { Items = index == 1 ? GetInitMEPParameterList() : null; } } private List GetInitCivilParameterList() { return [ new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" }, new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" }, new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" }, new() { Name = "ID-200-BIM对象分类编码执行标准", Value = "《城市轨道交通工程信息模型分类和编码标准》SJG102" }, new() { Name = "CM-100-校审单位", Value = "数云科际(深圳)技术有限公司" }, new() { Name = "FM-200-产品寿命", Value = "100" }, new() { Name = "FM-200-使用年限", Value = "100" }, new() { Name = "TC-400-设计使用年限", Value = "100" } ]; } private List GetInitMEPParameterList() { return [ new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" }, new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" }, new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" }, new() { Name = "CM-100-校审单位", Value = "深圳市市政设计研究院有限公司" }, new() { Name = "CM-100-创建人及联系方式", Value = "/" }, ]; } } public class ParameterModel { [ExcelColumn(Name="参数名")] public string Name { get; set; } [ExcelColumn(Name ="参数值")] public string Value { get; set; } }