Files
SzmediTools/Szmedi.RvKits/InfoManager/PropEditor/WriteParametersViewModel.cs
2026-01-16 17:07:43 +08:00

387 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<ParameterEditModel> items;
[ObservableProperty]
private string excelPath;
private readonly UIDocument uiDocument;
private bool HasItems => Items?.Any() == true;
[RelayCommand]
private void GetParams()
{
Items = null;
List<ParameterEditModel> 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<ParameterEditModel>(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<ParameterEditModel> 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<ParameterEditModel> 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 = "/" },
];
}
}
/// <summary>
/// 参数编辑的模型
/// </summary>
public class ParameterEditModel
{
[ExcelTableColumn("参数名")]
public string Name { get; set; }
[ExcelTableColumn("参数值")]
public string Value { get; set; }
}