Files
SzmediTools/Szmedi.RvKits/InfoManager/PropEditor/MappingElementCodeViewModel.cs
2025-09-16 16:06:41 +08:00

222 lines
9.2 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.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit.DB;
using EPPlus.Core.Extensions;
using Microsoft.Win32;
using Nice3point.Revit.Toolkit.External.Handlers;
using OfficeOpenXml;
namespace Szmedi.RvKits.ModelManager
{
public partial class MappingElementCodeViewModel : ObservableObject
{
private readonly ActionEventHandler handler = new();
[ObservableProperty]
private string excelPath;
[ObservableProperty]
private ExcelWorksheet selectedSheet;
[ObservableProperty]
private bool isFuzzyMatch = true;
[ObservableProperty]
private bool isIdMapping;
/// <summary>
/// 选择的列
/// </summary>
[ObservableProperty]
private KeyValuePair<int, string> selectedColumn;
[ObservableProperty]
private ExcelWorksheets sheets;
/// <summary>
/// 第一行,表头的数据
/// </summary>
[ObservableProperty]
private IEnumerable<KeyValuePair<int, string>> columns;
private ExcelPackage excelPackage;
[RelayCommand]
private void WriteParameters()
{
handler.Raise(uiapp =>
{
var sb = new StringBuilder();
var doc = uiapp.ActiveUIDocument.Document;
//匹配的元素在第几列
var col = SelectedColumn.Key;
//匹配的属性条目名称
var paramNameMapped = SelectedColumn.Value;
doc.InvokeGroup(
_ =>
{
//从第二行开始
for (int m = SelectedSheet.Dimension.Start.Row + 1, n = SelectedSheet.Dimension.End.Row; m <= n; m++)
{
//找到值
var val = SelectedSheet.GetValue(m, col);
Element elementMapped = null;
var excelValue = val.ToString();
if (paramNameMapped.ToUpper() == "ID")
{
if (IsFuzzyMatch)
{
excelValue = excelValue.Trim().ToLower();
}
var id = Convert.ToInt32(excelValue);
elementMapped = doc.GetElement(new ElementId(id));
if (elementMapped != null)
break;
}
else
{
elementMapped = doc.OfAllModelCollector()?.WhereElementIsNotElementType().FirstOrDefault(
e =>
{
if (e.GetParameters(paramNameMapped).Count == 0)
{
return false;
}
return e.GetParameters(paramNameMapped).Any(p =>
{
var paramValue = p.GetValue().ToString();
if (IsFuzzyMatch)
{
paramValue = paramValue.Trim().ToLower();
excelValue = excelValue.Trim().ToLower();
}
return paramValue == excelValue;
});
});
}
if (elementMapped == null)
{
sb.AppendLine(
$"工作簿:《{Path.GetFileNameWithoutExtension(ExcelPath)}》 表:<{SelectedSheet.Name}> 行号: {m} 未发现匹配的模型。");
continue;
}
//不存在的属性
var noExistProps = Columns.Where(
item => elementMapped.GetParameters(item.Value).Count == 0
&& item.Value.ToUpper() != "ID");
if (noExistProps.Any())
{
if (elementMapped is FamilyInstance instance)
{
if (!instance.Symbol.Family.IsEditable)
{
sb.AppendLine($"族不可编辑Id:{instance.Id}-类型名:{instance.Symbol.FamilyName}");
continue;
}
var famdoc = doc.EditFamily(instance.Symbol.Family);
famdoc.Invoke(
ts =>
{
foreach (var item in noExistProps)
{
famdoc.FamilyManager
.AddParameter(
item.Value,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
ParameterType.Text,
true);
}
},
"添加缺失的族参数属性条目");
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
else
{
doc.Invoke(ts =>
{
foreach (var item in noExistProps)
{
SharedParameterAssists.AddOrAttachSharedParameter(doc, item.Value, categories: elementMapped.Category);
}
}, "添加缺失的共享参数属性条目");
}
}
doc.Invoke(ts =>
{
foreach (var item in Columns)
{
var paramsToWrite = elementMapped.GetParameters(item.Value);
var v = SelectedSheet.GetValue(m, item.Key);
//if(paramToWrite == null)
//{
// //sb.AppendLine($"元素Id:[{elementMaped.Id}] 元素:{elementMaped.Name} 属性: {item.Value} 未发现。");
// continue;
//}
foreach (var param in paramsToWrite)
{
param?.SetValue(v);
}
}
},
"属性填写");
}
}, "属性匹配");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "处理结果");
}
//LogAssists.WriteTxtFile("log", sb.ToString());
});
}
partial void OnSelectedSheetChanged(ExcelWorksheet value)
{
//第一行的所有列
Columns = value.GetColumns(1).Where(r => !string.IsNullOrEmpty(r.Value));
}
[RelayCommand]
private void OnDrop(DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files is { Length: > 0 })
{
ExcelPath = files[0]; // 读取文件路径并赋值给 FilePath 属性
}
}
}
[RelayCommand]
private void SelectExcelPath()
{
var dialog = new OpenFileDialog()
{
Filter = "Excel文件(*.xlsx)|*.xlsx",
Title = "请选择Excel文件",
};
if (dialog.ShowDialog() == true)
{
ExcelPath = dialog.FileName;
excelPackage = new(new System.IO.FileInfo(dialog.FileName));
Sheets = excelPackage.Workbook.Worksheets;
}
}
}
}