using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Windows; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using EPPlus.Core.Extensions; using EPPlus.Core.Extensions.Attributes; using Microsoft.Win32; using Nice3point.Revit.Toolkit.External.Handlers; using OfficeOpenXml; using Szmedi.RvKits.Assists; namespace Szmedi.RvKits.InfoManager; 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 ParameterEditModel(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 = []; var doc = uiDocument.Document; try { var reference = uiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择提取参数的元素"); var elem = doc.GetElement(reference); if (elem == null) { return; } foreach (Parameter param in elem.Parameters) { if (param.IsReadOnly || param.StorageType == StorageType.ElementId || (param.HasValue || !string.IsNullOrEmpty(param.AsString()))) { continue; } models.Add(new ParameterEditModel { Name = param.Definition.Name }); } Items = [.. models.OrderBy(m => m.Name)]; } 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 = WinDialogAssists.CreateFilter("Excel文件", "xlsx"), InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), }; if (dialog.ShowDialog() != true) { return; } var excel = dialog.FileName; FileInfo fi = new(excel); var package = Items .ToWorksheet("参数表") .WithConfiguration(cfg => cfg.WithColumnConfiguration(c => c.AutoFit())) .ToExcelPackage(); package.SaveAs(fi); var result = MessageBox.Show("是否打开Excel表?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Process.Start(excel); } } [RelayCommand(CanExecute = nameof(HasItems))] private void WriteParams() { var doc = uiDocument.Document; var elements = IsSelectedItems ? uiDocument.Selection.GetElementIds().Select(id => doc.GetElement(id)).ToList() : [.. doc.OfAllModelCollector()]; if (elements == null) { MessageBox.Show("没有找到模型元素", "错误"); return; } StringBuilder sb = new(); handler.Raise(_ => { using (TransactionGroup transG = new(doc, "填写属性值")) { transG.Start(); foreach (var elem in elements) { if (elem.IsValidObject) { using Transaction trans = new(doc, "填写属性值"); //FailureHandlingOptions options = trans.GetFailureHandlingOptions(); //FailuresPreProcessor failuresProcessor = new(); //options.SetFailuresPreprocessor(failuresProcessor); //trans.SetFailureHandlingOptions(options); trans.Start(); Regex regex = new(@"^[A-Z]{2}-\d00-"); foreach (Parameter parameter in elem.Parameters) { //if (parameter.Definition.Name == "ID-100-编号") //{ // continue; //} //不为空时,跳过设置“/”或“0”即跳过已有值的情况 if (!(string.IsNullOrEmpty(parameter.AsString()) && string.IsNullOrEmpty(parameter.AsValueString()))) { continue; } //只针对轨道交通参数设置0或/ 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 (var item in Items.Where(item => !string.IsNullOrEmpty(item.Value))) //要修改的参数值,参数值为空,则清空参数值 foreach (var item in Items) { //if (item.Value==null) //{ // continue; //} var p1 = elem.GetParameters(item.Name).FirstOrDefault(); if (p1 == null) { sb.AppendLine($"构件类别:{elem.Category.Name};构件名:{elem.Name};构件ID:{elem.Id};参数名:{item.Name};异常原因:参数不存在"); continue; } if (p1.IsReadOnly) { sb.AppendLine($"构件类别:{elem.Category.Name};构件名:{elem.Name};构件ID:{elem.Id};参数名:{item.Name};异常原因:只读参数"); continue; } //if (p1 == null || p1.Definition.Name == "ID-100-编号") //{ // continue; //} try { //因为上方步骤已经将值全部修改为0或/,所以IsOverride或轨道交通参数值为/,0,两种情况都需要覆盖原值 if ( IsOverride || ( regex.IsMatch(p1.Definition.Name) && ( (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; } } } } 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) { LogAssists.WriteTxtFile("修改异常问题", sb.ToString()); } MessageBox.Show("修改参数完成!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); }); } [RelayCommand] private void BrowserExcelFile() { OpenFileDialog dialog = new() { CheckFileExists = true, Filter = WinDialogAssists.CreateFilter("Excel文件", "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) { FileInfo fi = new(path); using ExcelPackage package = new(fi); var worksheet = package.Workbook.Worksheets[1]; ////获取worksheet的行数 //int rows = worksheet .Dimension.End.Row; ////获取worksheet的列数 //int cols = worksheet .Dimension.End.Column; worksheet.TrimLastEmptyRows(); AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; try { Items = package.ToList(1, configuration => configuration.SkipCastingErrors()); //foreach (ParameterEditModel eamFacility in Items) { } //var groups = Facilities.GroupBy(x => x.Story); //foreach (var ZoomRBGroup in groups) //{ // if (ZoomRBGroup.Key == null) // { // continue; // } // StoryCodeMappers.Add(new() { Story = ZoomRBGroup.Key, }); //} //IsMapper = false; //IsComparison = false; //Instances.ForEach(ins => ins.IsMapped = false); } catch (EPPlus.Core.Extensions.Exceptions.ExcelValidationException ex) { System.Windows.MessageBox.Show("列名不存在或不匹配或检查表头是否存在换行或多余文字。", ex.Message); } finally { AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainOnAssemblyResolve; } } private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) { if (!args.Name.Contains("ComponentModel.Annotations")) { return null; } var assemblyFile = Path.Combine(GlobalVariables.DirAssembly, "System.ComponentModel.Annotations.dll"); return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null; } [RelayCommand] private void Init(int index) { Items = index == 0 ? GetInitCivilParameterList() : 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 ParameterEditModel { [ExcelTableColumn("参数名")] public string Name { get; set; } [ExcelTableColumn("参数值")] public string Value { get; set; } }