using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using EPPlus.Core.Extensions; using EPPlus.Core.Extensions.Attributes; using Microsoft.Win32; using Nice3point.Revit.Toolkit.External.Handlers; using OfficeOpenXml; //using Szmedi.Toolkit.Assists; namespace Szmedi.Test; 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); ExcelPackage package = Items .ToWorksheet("参数表") .WithConfiguration(cfg => cfg.WithColumnConfiguration(c => c.AutoFit())) .ToExcelPackage(); package.SaveAs(fi); 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) { LogAssists.WriteTxtFile("修改异常问题", 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) { FileInfo fi = new(path); using ExcelPackage package = new(fi); ExcelWorksheet 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 (ParameterModel eamFacility in Items) { } //var groups = Facilities .GroupBy(x => x.Story); //foreach (var group in groups) //{ // if (group .Key == null) // { // continue; // } // StoryCodeMappers .Add(new() { Story = group.Key, }); //} //IsMapper = false; //IsComparison = false; //Instances .ForEach(ins => ins.IsMapped = false); } catch (EPPlus.Core.Extensions.Exceptions.ExcelValidationException) { System.Windows.MessageBox.Show("列名不存在或不匹配或检查表头是否存在换行。"); } finally { AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainOnAssemblyResolve; } } private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args) { if (!args.Name.Contains("ComponentModel.Annotations")) { return null; } string assemblyFile = Path.Combine(GlobalVariables.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 { [ExcelTableColumn("参数名")] public string Name { get; set; } [ExcelTableColumn("参数值")] public string Value { get; set; } }