Skip to content

Instantly share code, notes, and snippets.

@boumer7
Created June 4, 2024 12:49
Show Gist options
  • Save boumer7/4c23e555f02ec8f444add19dc911c18d to your computer and use it in GitHub Desktop.
Save boumer7/4c23e555f02ec8f444add19dc911c18d to your computer and use it in GitHub Desktop.
/// <summary>
/// Инициализация вновь созданного объекта.
/// Вызывается на клиенте (или на сервере в клиентском скрипте)
/// сразу после установки значений по умолчанию в атрибутах
/// </summary>
/// <param name="obj">Объект, который инициализируем</param>
/// <param name="initialValues">Список значений для инициализации атрибутов объекта</param>
/// <remarks>Метод вызывается в порядке от шаблонов-родителей к детям-модификаторам.</remarks>
public override void OnInitialize(InfoObject obj, Dictionary<string, object> initialValues)
{
UpdateItemList(obj);
obj["InitFinished"] = true;
}
/// <summary>
/// Вызывается внутри скриптового (клиентского и серверного) кода перед передачей
/// серверу команды на изменение объектов.
/// Обработчики вызываются в порядке от родительских шаблонов к дочерним и модификаторам.
/// </summary>
/// <param name="obj">Объект, изменения в котором собираемся отправлять на сервер</param>
/// <remarks>Физически может вызываться как на клиенте, так и на сервере, если сохранение иницировано
/// например серверным методом, или другим скриптовым кодом.
/// Исключения, вышедшие их этого метода, предотвращают сохранение объекта.
/// Пользователю показывается сообщение.
/// Следует иметь в виду, что этот метод может вызываться несколько раз для одних и тех же входных данных.
/// Такое бывает в случае нескольких неуспешных попыток пользователя сохранить объект. В этом случае,
/// если метод изменяет что-ли в объектах, на которых у исходного набора есть ссылки, то повторные вызовы
/// метода могут привести к использованию уже измененных связанных скриптовых оболочек.
/// Возможно для таких объектов понадобится вызывать CancelChanges() либо EnsureObjectInSaveSet(), чтобы
/// эти измененные объекты попали в новый контекст очередной попытки сохранения.
/// Метод вызывается в порядке от шаблонов-родителей к детям-модификаторам.
/// [ReplaceMaster] атрибут позволяет из скрипта модификатора отключить обработчик мастер-шаблона</remarks>
public override void OnBeforeSendChangesToServer(InfoObject obj)
{
var fileName = obj.GetString("Name").Replace(':', '_').Replace('/', '_');
var replaceDots = Service.GetCommonRegistryValue<int>(@"KB20Root\CommonSettings\KB20_Unloading_str\ReplaceDots\Value", 1) == 1;
if (replaceDots)
fileName = fileName.Replace('.', '_');
// Нужно ли выгружать из PLM или Создавать в PLM Тех.Док.
if (obj.GetBoolean("UnloadFromPLM"))
{
var exportType = obj.GetNamedValue("ExportType");
switch (exportType.ValueAsString)
{
case "FILES":
{
var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
ExportFilesToFolder(fbd.SelectedPath, obj.GetAttribute("ExportData"));
}
break;
case "PDF":
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
ExportPDFToFolder(fbd.SelectedPath, obj.GetAttribute("ExportData"));
}
break;
case "CSV":
{
var fileDialog = new SaveFileDialog()
{
AddExtension = true,
AutoUpgradeEnabled = true,
Filter = "Файл разделенный табуляцией (*.csv)|*.csv|All files (*.*)|*.*",
DefaultExt = "csv",
FileName = fileName
};
fileDialog.ShowDialog();
try
{
StreamWriter sw = new StreamWriter(fileDialog.FileName, false, Encoding.Unicode);
var exportDataAttr = obj.GetAttribute("ExportData");
switch (obj.GetNamedValue("LevelType").ValueAsString)
{
case "SINGLE": // "Уровень в одну колонку":
ExportAsSingleLevel(sw, exportDataAttr);
break;
case "MULTI": // "Подуровни в свои столбцы":
ExportAsMultiLevel(sw, exportDataAttr);
break;
}
sw.Close();
}
catch { throw new FileNotFoundException("Файл не выбран"); }
}
break;
case "XLSX":
{
var fileDialog = new SaveFileDialog()
{
AddExtension = true,
AutoUpgradeEnabled = true,
Filter = "Книга Excel (*.xlsx)|*.xlsx",
DefaultExt = "xlsx",
FileName = fileName
};
if (fileDialog.ShowDialog() == DialogResult.OK)
{
var excel = new Excel();
excel.Visible = false;
excel.CreateBook();
excel.OpenWorksheet(1);
var exportDataAttr = obj.GetAttribute("ExportData");
switch (obj.GetNamedValue("LevelType").ValueAsString)
{
case "SINGLE": // "Уровень в одну колонку":
ExportAsSingleLevelExcel(excel, exportDataAttr);
break;
case "MULTI": // "Подуровни в свои столбцы":
ExportAsMultiLevelExcel(excel, exportDataAttr);
break;
}
excel.SaveAs(fileDialog.FileName);
excel.CloseBook();
excel.Quit();
excel.Kill();
}
else { throw new FileNotFoundException("Файл не выбран"); }
}
break;
}
} // если не указана выгрузка, то создаём объекты в PLM.
else
{
var parent = obj.GetInfoObject("Parent");
var optionsDialog = new InfoObject(obj, @"InfoObjects\KB20.Unloading_str\Dialogs\GenDocs");
if (Service.UI.ShowObjectProperties(optionsDialog, false))
{
bool genDocsExcel = optionsDialog.GetBoolean("GenDocsExcel");
bool genDocsPrt = optionsDialog.GetBoolean("GenDocsPrt");
bool genDocsPDF = optionsDialog.GetBoolean("GenDocsPDF");
string date = DateTime.Now.ToShortDateString();
//Формируем имя будущих файлов.
var pc = parent.GetInfoObject("ProductConfiguration");
string name = pc.GetString("Name");
string designation = pc.GetString("Designation");
//Складываем Имя Документа.
var ordName = string.Format("{0} {1} {2}.xlsx", date, designation, name).Replace(':', '_');
if (replaceDots)
ordName = ordName.Replace('.', '_');
string path = Path.GetTempPath();
path = Path.Combine(path, ordName);
var exportDataAttr = obj.GetAttribute("ExportData");
if (genDocsExcel)
{
Excel excel = new Excel();
excel.Visible = false;
excel.CreateBook();
excel.OpenWorksheet(1);
var attrDefs = exportDataAttr.SubItemTemplate.AttributeDefsModified.OrderBy(o => o.GroupKey);
int columnCounter = 1;
foreach (var attrDef in attrDefs)
{
excel.SetCell(1, columnCounter, attrDef.NameUI);
int rowCounter = 2;
foreach (var ce in exportDataAttr.CollectionElements)
{
excel.SetCell(rowCounter, columnCounter, ce[attrDef.NameKey] == null ? " " : ce[attrDef.NameKey].ToString());
rowCounter++;
}
columnCounter++;
}
excel.SaveAs(path);
excel.CloseBook();
excel.Quit();
excel.Kill();
UploadFile(path, obj);
File.Delete(path);
}
}
}
}
private void UploadFile(string path, InfoObject obj)
{
var BaseDocTemplate = Service.GetTemplate(@"InfoObjects\STD\Documents\Document\TechnicalDocument");
var BaseVerTemplate = Service.GetTemplate(@"InfoObjects\STD\Documents\DocumentVersion\TechnicalDocumentVersion");
Template DocTemplate;
Template VerTemplate;
if (obj.Template != null && BaseDocTemplate != null && BaseVerTemplate != null)
{
DocTemplate = BaseDocTemplate;
if (DocTemplate != null)
{
VerTemplate = DocTemplate.GetCreatableTemplates(BaseVerTemplate).DefaultIfEmpty(BaseVerTemplate).FirstOrDefault();
var parentFolder = obj.GetDataContainer("ParFolder");
if (VerTemplate != null && parentFolder != null)
{
using (Service.EnterNewGroupOperation())
{
var Doc = new InfoObject(parentFolder, DocTemplate);
var Ver = new InfoObject(Doc, VerTemplate);
var pc = obj.GetInfoObject("Parent.ProductConfiguration");
Doc["ActualVersion"] = Ver;
Ver["DoNotGeneratePreview"] = true;
Ver["DocumentDesignation"] = pc["Designation"];
Ver["ProductName"] = pc["Name"];
Ver.GetAttribute("Body").Value.UploadFile(path);
Doc.IsBySystem = false;
Ver.IsBySystem = false;
Service.SaveChanges();
}
}
}
}
}
private void ExportFilesToFolder(string root, EntityAttribute exportDataAttr)
{
List<string> operNames = exportDataAttr.CollectionElements.Select(ce => ce.GetString("Oper_name")).Distinct().ToList();
foreach (string operName in operNames)
{
string opf = operName;
if (operName == "" || operName == null || operName == string.Empty)
opf = "Other";
string cf = Path.Combine(root, opf);
if (!Directory.Exists(cf))
Directory.CreateDirectory(cf);
List<object> versions = (from vr in exportDataAttr.CollectionElements
where vr["Oper_name"].ToString() == operName && vr["OriginalDocument"] != null
select vr["OriginalDocument"]).Distinct().ToList();
foreach (InfoObject version in versions)
{
FileDesc fd = version.GetFile("Body");
Stream savestream = fd.DownloadingDataStream;
FileStream fs = File.Create(cf + "\\" + fd.OriginalName);
savestream.Copy(fs);
fs.Close();
}
}
}
private void ExportPDFToFolder(string root, EntityAttribute exportDataAttr)
{
string pdfDirectory = Path.Combine(root, "PDFs");
if (!Directory.Exists(pdfDirectory))
Directory.CreateDirectory(pdfDirectory);
// возьмём все атрибуты, где тип - ссылка на объект или список ссылок на объекты
var targetAttrs = exportDataAttr.SubItemTemplate.AttributeDefsModified.Where(ad => ad != null && (ad.DataType == AttributeDefBase.DataTypeEnum.LinkToInfoObject || ad.DataType == AttributeDefBase.DataTypeEnum.SetOfInfoObjectLinks));
Set<InfoObject> ios = new Set<InfoObject>();
foreach (var ce in exportDataAttr.CollectionElements)
{
foreach (var attrDef in targetAttrs)
{
var attr = ce.GetAttribute(attrDef);
if (attr == null || attr.IsEmpty)
continue;
if (attrDef.DataType == AttributeDefBase.DataTypeEnum.LinkToInfoObject)
{
var io = attr.Value.Value as InfoObject;
if (io == null)
continue;
ios.AddOnce(io);
}
else if (attrDef.DataType == AttributeDefBase.DataTypeEnum.SetOfInfoObjectLinks)
ios.AddMany(attr.LinkedInfoObjects);
}
}
foreach (var io in ios)
{
var body = io.GetFile("Body");
if (body == null)
continue;
if (Path.GetExtension(body.OriginalName).ToUpper() == ".PDF")
{
Stream savestream = body.DownloadingDataStream;
FileStream fs = File.Create(Path.Combine(pdfDirectory, body.OriginalName));
savestream.Copy(fs);
fs.Close();
savestream.Close();
}
}
}
private bool ExportAsMultiLevelExcel(Excel xl, EntityAttribute ed)
{
// 1 get max level
// 2 generate attrs list
// 3 write header
// 4 write data
int maxlevel = 0;
foreach (CollectionElement el in ed.CollectionElements)
{
int curlevctr = el["Level"].SafeToString().Split(new Char[] { '.' }).Length;
if (maxlevel < curlevctr)
maxlevel = curlevctr;
}
//2
List<string> attrnames = new List<string>();
CollectionElement rootel = ed.CreateCollectionElement();
var attrDefs = rootel.Template.AttributeDefsModified.OrderBy(o => o.GroupKey);
int cl = 1;
for (int i = 0; i < maxlevel; i++)
{
xl.SetCell(1, cl, ("Уровень " + i.ToString()));
cl++;
}
foreach (var attrDef in attrDefs)
{
if (attrDef.NameKey != "Level")
{
attrnames.Add(attrDef.NameKey);
xl.SetCell(1, cl, attrDef.NameUI);
cl++;
}
}
//4
/*
4.1 в цикле генерируем строку для записи в файл
4.1.1 генерация столбцов цровней
4.1.2 генерация атрибутов
4.1.3 запись строки
*/
//4.1
int rw = 2;
foreach (CollectionElement el in ed.CollectionElements)
{
//4.1.1
string[] levels = el["Level"].SafeToString().Split(new Char[] { '.' });
cl = 1;
for (int i = 0; i < maxlevel; i++)
{
if (i < levels.Length)
{
xl.SetCell(rw, cl, levels[i]);
}
cl++;
}
//4.1.2
foreach (string an in attrnames)
{
xl.SetCell(rw, cl, (an == "Quantity" && el.GetFloat(an) == 0.0 ? "" : el[an].SafeToString()));
cl++;
}
rw++;
}
return true;
}
private bool ExportAsSingleLevelExcel(Excel xl, EntityAttribute ed)
{
List<string> attrnames = new List<string>();
CollectionElement rootel = ed.CreateCollectionElement();
var attrDefs = rootel.Template.AttributeDefsModified.OrderBy(o => o.GroupKey);
int cl = 1;
foreach (var attrDef in attrDefs)
{
attrnames.Add(attrDef.NameKey);
xl.SetCell(1, cl, attrDef.NameUI);
cl++;
}
cl = 1;
int rw = 2;
foreach (CollectionElement cel in ed.CollectionElements)
{
cl = 1;
foreach (string attrname in attrnames)
{
xl.SetCell(rw, cl, (attrname == "Quantity" && cel.GetFloat(attrname) == 0.0 ? "" : cel[attrname].SafeToString()));
cl++;
}
rw++;
}
return true;
}
private void ExportAsSingleLevel(StreamWriter sw, EntityAttribute ed)
{
List<string> attrnames = new List<string>();
CollectionElement rootel = ed.CreateCollectionElement();
var attrDefs = rootel.Template.AttributeDefsModified.OrderBy(o => o.GroupKey);
string header = "";
foreach (var attrDef in attrDefs)
{
attrnames.Add(attrDef.NameKey);
header += attrDef.NameUI + "\t";
}
sw.WriteLine(header);
foreach (CollectionElement cel in ed.CollectionElements)
{
string data = "";
foreach (string attrname in attrnames)
{
data += (attrname == "Quantity" && cel.GetFloat(attrname) == 0.0 ? "" : cel[attrname].SafeToString()) + "\t";
}
sw.WriteLine(data);
}
}
private void ExportAsMultiLevel(StreamWriter sw, EntityAttribute ed)
{
// 1 get max level
// 2 generate attrs list
// 3 write header
// 4 write data
//1
int maxlevel = 0;
foreach (CollectionElement el in ed.CollectionElements)
{
int curlevctr = el["Level"].SafeToString().Split(new Char[] { '.' }).Length;
if (maxlevel < curlevctr)
maxlevel = curlevctr;
}
//2
List<string> attrnames = new List<string>();
CollectionElement rootel = ed.CreateCollectionElement();
var attrDefs = rootel.Template.AttributeDefsModified.OrderBy(o => o.GroupKey);
string header = "";
for (int i = 0; i < maxlevel; i++)
{
header += ("Уровень" + i.ToString()) + "\t";
}
foreach (var attrDef in attrDefs)
{
if (attrDef.NameKey != "Level")
{
attrnames.Add(attrDef.NameKey);
header += attrDef.NameUI + "\t";
}
}
//3
sw.WriteLine(header);
//4
/*
4.1 в цикле генерируем строку для записи в файл
4.1.1 генерация столбцов уровней
4.1.2 генерация атрибутов
4.1.3 запись строки
*/
//4.1
foreach (CollectionElement el in ed.CollectionElements)
{
string data = "";
//4.1.1
string[] levels = el["Level"].SafeToString().Split(new Char[] { '.' });
for (int i = 0; i < maxlevel; i++)
{
if (i < levels.Length)
{
data += levels[i];
}
data += "\t";
}
//4.1.2
foreach (string an in attrnames)
{
data += (an == "Quantity" && el.GetFloat(an) == 0.0 ? "" : el[an].SafeToString()) + "\t";
}
//4.1.3
sw.WriteLine(data);
}
}
#region функции работы с Excel
// Выравнивание по горизонтали
public enum XlAlignHorizontal
{
xlGeneral = 1, // По значению
xlLeft = -4131, // По левому краю (отступ)
xlCenter = -4108, // По центру
xlRight = -4152, // По правому краю (отступ)
xlFill = 5, // С заполнением
xlJustify = -4130, // По ширине
xlCenterAcrossSelection = 7, // По центру выделения
xlDistributed = -4117 // Распределенный (отступ)
}
// Выравнивание по вертикали
public enum XlAlignVertical
{
xlTop = 1, // По верхнему краю
xlCenter = -4108, // По центру
xlBottom = -4107, // По нижнему краю
xlJustify = -4130, // По высоте
xlDistributed = -4117 // Распределенный
}
// Ориентация страницы
public enum XlPageOrientation
{
xlPortrait = 1, //Книжный
xlLandscape = 2 // Альбомный
}
// Вид границы
public enum XlBordersIndex
{
xlDiagonalDown = 5, // Border running from the upper left-hand corner to the lower right of each cell in the range.
xlDiagonalUp = 6, // Border running from the lower left-hand corner to the upper right of each cell in the range.
xlEdgeBottom = 9, // Border at the bottom of the range.
xlEdgeLeft = 7, // Border at the left-hand edge of the range.
xlEdgeRight = 10, // Border at the right-hand edge of the range.
xlEdgeTop = 8, // Border at the top of the range.
xlInsideHorizontal = 12, // Horizontal borders for all cells in the range except borders on the outside of the range.
xlInsideVertical = 11 // Vertical borders for all the cells in the range except borders on the outside of the range.
}
// Стиль линии для границы
public enum XlLineStyle
{
xlContinuous = 1, // Continuous line.
xlDash = -4115, // Dashed line.
xlDashDot = 4, // Alternating dashes and dots.
xlDashDotDot = 5, // Dash followed by two dots.
xlDot = -4118, // Dotted line.
xlDouble = -4119, // Double line.
xlLineStyleNone = -4142, // No line.
xlSlantDashDot = 13 // Slanted dashes.
}
// Толщина линии границы
public enum XlBorderWeight
{
xlHairline = 1, // Hairline (thinnest border).
xlMedium = -4138, // Medium.
xlThick = 4, // Thick (widest border).
xlThin = 2 // Thin.
}
// Расположение агрегации сгруппированных строк
public enum XlSummaryRow
{
xlSummaryAbove = 0, // Сверху
xlSummaryBelow = 1 // Снизу
}
public class Excel : IDisposable
{
object FExcel = null;
object FWorkbooks, FWorkbook, FWorksheets, FWorksheet, FRange;
// Конструктор
public Excel()
{
FExcel = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
}
// Деструктор
public void Dispose()
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(FWorkbooks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(FWorkbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(FWorksheets);
System.Runtime.InteropServices.Marshal.ReleaseComObject(FWorksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(FRange);
System.Runtime.InteropServices.Marshal.ReleaseComObject(FExcel);
}
catch { }
finally
{
FWorkbooks = null;
FWorkbook = null;
FWorksheets = null;
FWorksheet = null;
FRange = null;
FExcel = null;
}
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
public void Kill()
{
int id;
var Hwnd = (int)FExcel.GetType().InvokeMember(
"Hwnd", System.Reflection.BindingFlags.GetProperty, null, FExcel, null);
GetWindowThreadProcessId(Hwnd, out id);
Process.GetProcessById(id).Kill();
}
// Видимость
public bool Visible
{
get
{
return Convert.ToBoolean(FExcel.GetType().InvokeMember(
"Visible", System.Reflection.BindingFlags.GetProperty, null, FExcel, null));
}
set
{
FExcel.GetType().InvokeMember(
"Visible", System.Reflection.BindingFlags.SetProperty, null, FExcel, new object[] { value });
}
}
// Формула ячейки
public void FormulaR1C1(string AAddress, object AFormula)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"Activate", System.Reflection.BindingFlags.InvokeMethod, null, FRange, null);
object cellActive = FExcel.GetType().InvokeMember(
"ActiveCell", System.Reflection.BindingFlags.GetProperty, null, FExcel, null);
cellActive.GetType().InvokeMember(
"FormulaR1C1", System.Reflection.BindingFlags.SetProperty, null, cellActive, new object[] { AFormula });
cellActive = null;
}
// Открыть книгу
public void OpenBook(string AFilePath)
{
FWorkbooks = FExcel.GetType().InvokeMember(
"Workbooks", System.Reflection.BindingFlags.GetProperty, null, FExcel, null);
FWorkbook = FWorkbooks.GetType().InvokeMember(
"Open", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbooks, new object[] { AFilePath, true });
FWorksheets = FWorkbook.GetType().InvokeMember(
"Worksheets", System.Reflection.BindingFlags.GetProperty, null, FWorkbook, null);
FWorksheet = FWorksheets.GetType().InvokeMember(
"Item", System.Reflection.BindingFlags.GetProperty, null, FWorksheets, new object[] { 1 });
}
// Выбрать страницу
public void OpenWorksheet(int AIndex)
{
FWorksheet = FWorksheets.GetType().InvokeMember(
"Item", System.Reflection.BindingFlags.GetProperty, null, FWorksheets, new object[] { AIndex });
}
// Создать книгу
public void CreateBook()
{
FWorkbooks = FExcel.GetType().InvokeMember(
"Workbooks", System.Reflection.BindingFlags.GetProperty, null, FExcel, null);
FWorkbook = FWorkbooks.GetType().InvokeMember(
"Add", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbooks, null);
FWorksheets = FWorkbook.GetType().InvokeMember(
"Worksheets", System.Reflection.BindingFlags.GetProperty, null, FWorkbook, null);
FWorksheet = FWorksheets.GetType().InvokeMember(
"Item", System.Reflection.BindingFlags.GetProperty, null, FWorksheets, new object[] { 1 });
}
// Закрыть книгу
public void CloseBook()
{
FWorkbook.GetType().InvokeMember(
"Close", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbook, new object[] { false });
}
// Закрыть приложение
public void Quit()
{
FExcel.GetType().InvokeMember(
"Quit", System.Reflection.BindingFlags.InvokeMethod, null, FExcel, null);
}
// Сохранить как
public void SaveAs(string Path)
{
FWorkbook.GetType().InvokeMember(
"SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbook, new object[] { Path });
}
// Показать диалог предпросмотра печати
public void PrintPreview(bool EnableChanges)
{
FWorkbook.GetType().InvokeMember(
"PrintPreview", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbook, new object[] { EnableChanges });
}
// Ширина столбца
public void ColumnWidth(string AAddress, double AWidth)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"ColumnWidth", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AWidth });
}
// Перенос строк
public void SetWrapText(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"WrapText", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { true });
}
// Высота строки
public void RowHeight(string AAddress, double AHeight)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"RowHeight", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AHeight });
}
// Объединение ячеек
public void MergeCells(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"Merge", System.Reflection.BindingFlags.InvokeMethod, null, FRange, null);
}
// Применение шрифта к ячейке
public void SetFont(string AAddress, Font AFont)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object objFont = FRange.GetType().InvokeMember(
"Font", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
objFont.GetType().InvokeMember(
"Size", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Size });
objFont.GetType().InvokeMember(
"Bold", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Bold });
objFont.GetType().InvokeMember(
"Name", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Name });
//objFont.GetType().InvokeMember(
// "Height", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Height });
objFont.GetType().InvokeMember(
"Strikethrough", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Strikeout });
objFont = null;
}
// Применение шрифта к ячейке и цвета шрифта
public void SetFont(string AAddress, Font AFont, Color AColor)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object objFont = FRange.GetType().InvokeMember(
"Font", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
objFont.GetType().InvokeMember(
"Size", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Size });
objFont.GetType().InvokeMember(
"Bold", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Bold });
objFont.GetType().InvokeMember(
"Italic", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Italic });
objFont.GetType().InvokeMember(
"Strikethrough", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Strikeout });
objFont.GetType().InvokeMember(
"Name", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Name });
//objFont.GetType().InvokeMember(
// "LineHeight", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AFont.Height });
if (AColor != null)
{
objFont.GetType().InvokeMember(
"Color", System.Reflection.BindingFlags.SetProperty, null, objFont, new object[] { AColor.ToArgb() });
}
objFont = null;
}
// Применение цвета и способа заливки к ячейке
public void SetColor(string AAddress, int AColorIndex, int APatternIndex)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object objInterior = FRange.GetType().InvokeMember(
"Interior", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
objInterior.GetType().InvokeMember(
"ColorIndex", System.Reflection.BindingFlags.SetProperty, null, objInterior, new object[] { AColorIndex });
objInterior.GetType().InvokeMember(
"Pattern", System.Reflection.BindingFlags.SetProperty, null, objInterior, new object[] { APatternIndex });
objInterior = null;
}
// Установка ориентации страницы
public void SetOrientation(XlPageOrientation AOrientation)
{
object pageSetup = FWorksheet.GetType().InvokeMember(
"PageSetup", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, null);
pageSetup.GetType().InvokeMember(
"Orientation", System.Reflection.BindingFlags.SetProperty, null, pageSetup, new object[] { AOrientation });
}
// Установка зума
public void SetZoom(int APercent)
{
object pageSetup = FWorksheet.GetType().InvokeMember(
"PageSetup", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, null);
pageSetup.GetType().InvokeMember(
"Zoom", System.Reflection.BindingFlags.SetProperty, null, pageSetup, new object[] { APercent });
}
// Запись значения в ячейку
public void SetValue(string AAddress, string AValue)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AValue });
}
public void SetCell(int row, int col, string value)
{
object cells = FWorksheet.GetType().InvokeMember(
"Cells", System.Reflection.BindingFlags.GetProperty, null, (object)FWorksheet, new object[] { row, col });
cells.GetType().InvokeMember(
"NumberFormat", System.Reflection.BindingFlags.SetProperty, null, cells, new object[] { "@" });
cells.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.SetProperty, null, cells, new object[] { value });
}
// Запись значения в ячейку с форматом
public void SetValue(string AAddress, string AValue, string AFormat)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"NumberFormat", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AFormat });
FRange.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AValue });
}
// Запись значения в ячейку с форматом и культурой
public void SetValue(string AAddress, string AValue, string AFormat, CultureInfo ACulture)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"NumberFormat", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AFormat }, ACulture);
FRange.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AValue });
}
// Получить значение с ячейки
public string GetValue(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
return FRange.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.GetProperty, null, FRange, null).ToString();
}
// Установка одной границы ячейки
public void SetCellBorder(string AAddress, XlBordersIndex AIndex, XlLineStyle ALineStyle, XlBorderWeight AWeight)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object border = FRange.GetType().InvokeMember(
"Borders", System.Reflection.BindingFlags.GetProperty, null, FRange, new object[] { AIndex });
border.GetType().InvokeMember(
"LineStyle", System.Reflection.BindingFlags.SetProperty, null, border, new object[] { ALineStyle });
border.GetType().InvokeMember(
"Weight", System.Reflection.BindingFlags.SetProperty, null, border, new object[] { AWeight });
border = null;
}
// Установка всех границ ячейки
public void SetCellBorderAll(string AAddress, XlBordersIndex[] AIndex, XlLineStyle[] ALineStyle, XlBorderWeight[] AWeight)
{
for (int i = 0; i <= AIndex.Length - 1; i++)
this.SetCellBorder(AAddress, AIndex[i], ALineStyle[i], AWeight[i]);
}
// Установка всех границ диапазона ячеек
public void SetRangeBorders(string AAddress, XlLineStyle ALineStyle, XlBorderWeight AWeight)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object borders = FRange.GetType().InvokeMember(
"Borders", System.Reflection.BindingFlags.GetProperty, null, FRange, new object[] { });
borders.GetType().InvokeMember(
"LineStyle", System.Reflection.BindingFlags.SetProperty, null, borders, new object[] { ALineStyle });
borders.GetType().InvokeMember(
"Weight", System.Reflection.BindingFlags.SetProperty, null, borders, new object[] { AWeight });
borders = null;
}
// Установка границы вокруг диапазона ячеек
public void BorderAround(string AAddress, XlLineStyle ALineStyle, XlBorderWeight AWeight)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"BorderAround", System.Reflection.BindingFlags.InvokeMethod, null, FRange, new object[] { ALineStyle, AWeight, 0, null });
}
// Расположение агрегации сгруппированных строк
public void LocationSummaryRows(XlSummaryRow ASummaryRow)
{
object sheet = FWorkbook.GetType().InvokeMember(
"ActiveSheet", System.Reflection.BindingFlags.GetProperty, null, FWorkbook, null);
object outline = sheet.GetType().InvokeMember(
"Outline", System.Reflection.BindingFlags.GetProperty, null, sheet, null);
outline.GetType().InvokeMember(
"SummaryRow", System.Reflection.BindingFlags.SetProperty, null, outline, new object[] { ASummaryRow });
}
// Группировка строк
public void GroupRows(string AAddress, bool AIsGrouping)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object rows = FRange.GetType().InvokeMember(
"Rows", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
if (AIsGrouping)
rows.GetType().InvokeMember("Group", System.Reflection.BindingFlags.GetProperty, null, rows, null);
else
rows.GetType().InvokeMember("Ungroup", System.Reflection.BindingFlags.GetProperty, null, rows, null);
rows = null;
}
// Группировка столбцов
public void GroupColumns(string AAddress, bool AIsGrouping)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object columns = FRange.GetType().InvokeMember("Columns", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
if (AIsGrouping)
columns.GetType().InvokeMember("Group", System.Reflection.BindingFlags.GetProperty, null, columns, null);
else
columns.GetType().InvokeMember("Ungroup", System.Reflection.BindingFlags.GetProperty, null, columns, null);
}
// Выравнивание по горизонтали
public void AlignHorizontal(string AAddress, XlAlignHorizontal AAlign)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"HorizontalAlignment", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AAlign });
}
// Выравнивание по вертикали
public void AlignVertical(string AAddress, XlAlignVertical AAlign)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
FRange.GetType().InvokeMember(
"VerticalAlignment", System.Reflection.BindingFlags.SetProperty, null, FRange, new object[] { AAlign });
}
// Вертикальный разрыв страницы
public void PageBreakerVertical(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object pageBreak = FWorksheet.GetType().InvokeMember(
"VPageBreaks", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, null);
pageBreak.GetType().InvokeMember(
"Add", System.Reflection.BindingFlags.InvokeMethod, null, pageBreak, new object[] { FRange });
pageBreak = null;
}
// Горизонтальный разрыв страницы
public void PageBreakerHorizontal(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object pageBreak = FWorksheet.GetType().InvokeMember(
"HPageBreaks", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, null);
pageBreak.GetType().InvokeMember(
"Add", System.Reflection.BindingFlags.InvokeMethod, null, pageBreak, new object[] { FRange });
pageBreak = null;
}
// Получить имя столбца по номеру
// (1 = A, 2 = B...27 = AA...703 = AAA...)
public static string GetColNameFromIndex(int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
// Получить номер стобца по имени
// (A = 1, B = 2...AA = 27...AAA = 703...)
public static int GetColNumberFromName(string columnName)
{
char[] characters = columnName.ToUpperInvariant().ToCharArray();
int sum = 0;
for (int i = 0; i < characters.Length; i++)
{
sum *= 26;
sum += (characters[i] - 'A' + 1);
}
return sum;
}
// Автоматическое выравнивание размеров столбцов
public void AutoFit(string AAddress)
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
object cols = FRange.GetType().InvokeMember("Columns", System.Reflection.BindingFlags.GetProperty, null, FRange, null);
cols.GetType().InvokeMember("AutoFit", System.Reflection.BindingFlags.InvokeMethod, null, cols, null);
cols = null;
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
#endregion
/// <summary>
/// Нотификация об изменении какого-либо атрибута объекта
/// </summary>
/// <param name="obj">Объект, чей атрибут изменился</param>
/// <param name="attr">Собственно изменившийся атрибут либо null, если изменилось сразу много атрибутов</param>
/// <remarks>Метод вызывается по месту изменения значения атрибута. Это может происходить как на клиенте,
/// так и на сервере. В том числе внутри обработки операции сохранения, где вложенные вызовы сохранения
/// заблокированы (приводят к исключению).
/// Метод вызывается в порядке от родителей к детям-модификаторам </remarks>
public override void OnAttributeChanged(InfoObject obj, EntityAttribute attr)
{
bool inited = obj.GetBoolean("InitFinished");
if (!inited)
return;
// Изменения атрибутов в ходе обработки операции сохранения или просто на сервере
// обычно не требуют дополнительной обработки. завершаем метод в этом случае.
if (Service.IsInSaveProcessing || Service.RunningOnServer || Service.IsImportOperation)
return;
if (attr.NameKey == "Multiplicate" || attr.NameKey == "NotSetLevelAndQuantityForRootAssy")
UpdateItemList(obj);
}
// AA Отсюда начинается формирование непосредственно самих значений атрибутов
// АА Выше - функции экспорта-импорта в Excel и др.
Dictionary<string, string[]> attrNamesDict;
EntityAttribute exportDataAttr;
StringBuilder errors;
bool multiply, setRootLevel;
// StringBuilder debug_;
// AA ExportDialog - переменная для инф. объекта ExportDialogDev (Выгрузка разраб.)
private void UpdateItemList(InfoObject exportDialog)
{
// АА коллекция атрибутируемых элементов
exportDataAttr = exportDialog.GetAttribute("ExportData");
exportDataAttr.CollectionElements.Clear();
attrNamesDict = new Dictionary<string, string[]>();
errors = new StringBuilder();
/* АА ExportDialog: UnloadFromPLM, Name, LevelType, ExportType, Parent, ParFolder и др. */
// АА Умножать количество деталей на количество подсборок (да/нет)
multiply = exportDialog.GetBoolean("Multiplicate");
// АА Не устанавливать количество и уровень для корневой сборки (да/нет)
setRootLevel = !exportDialog.GetBoolean("NotSetLevelAndQuantityForRootAssy");
// АА Assy - Assembly
// АА ссылка на информационный объект "Родитель"
var pvc = exportDialog.GetInfoObject("Parent");
//вывод всех атрибутов родителя
//errors.Append(string.Join(", ", pvc.AllAttributes));
// проверка на бесконечный цикл
var callerChain = new Stack<TID>();
callerChain.Push(pvc.Id);
// наличие этого объекта означает, что есть цикл
var looper = CheckLoop(pvc, callerChain);
if (looper == null)
{
// наполняем словарь ключей атрибутов с добавление массива тэгов
foreach (var attrDef in exportDataAttr.SubItemTemplate.AttributeDefsModified){
attrNamesDict.Add(attrDef.NameKey, attrDef.Tags.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
};
/* АА Вывод для значений массива для дебага*/
/* foreach (var attrDef in exportDataAttr.SubItemTemplate.AttributeDefsModified)
{
errors.AppendLine($"{attrDef} ({attrDef.NameKey}) : {attrDef.Tags};");
}
*/
// string result = string.Join(", ", attrNamesDict);
//string dictAsString = string.Join(Environment.NewLine, attrNamesDict.Select(kv => $"{kv.Key}: [{string.Join(", ", kv.Value)}]"));
// errors.Append(dictAsString);
var rootLevel = setRootLevel ? "0" : "";
var rootQuant = setRootLevel ? -1 : 0;
// заполняем таблицу
FillItems(pvc, null, rootQuant, rootLevel, true);
}
else
errors.AppendLine("Предупреждение! Обнаружен <font color=\"Green\"> бесконечный цикл </font> в ИИВ <a href=\"" + Service.UI.FormatLink((ScriptingObject)looper, true) + "\">" + looper.ToString() + "</a>. Обновление списка не возможно. <br>");
if (errors.Length > 0)
{
Form rep = new Form();
WebBrowser br = new WebBrowser();
br.Parent = rep;
br.Dock = DockStyle.Fill;
br.DocumentText = errors.ToString();
rep.ShowDialog();
}
}
private InfoObject CheckLoop(InfoObject target, Stack<TID> callerChain)
{
if (target == null)
return null;
InfoObject looper = null;
foreach (var product in target.GetCollectionElements("Items").Safe().Select(ce => ce.GetInfoObject("ProductItem")).SkipNull())
{
if (callerChain.Contains(product.Id))
looper = target;
// выход из цикла при первоначальном нахождении лупера
if (looper != null)
break;
callerChain.Push(product.Id);
looper = CheckLoop(product, callerChain);
callerChain.Pop();
// точка выныривания из рекурсии
if (looper != null)
break;
}
return looper;
}
// FillItems(pvc, null, rootQuant, rootLevel, true) вызов из UpdateItemList;
private void FillItems(InfoObject pvc, CollectionElement sourceElement, double quantity, string level, bool isRoot)
{
if (pvc == null)
{
var parent = sourceElement == null ? null : sourceElement.OwnerObject as InfoObject;
errors.AppendLine(string.Format("Предупреждение! <font color=\"Green\"> Отсутствует изделие </font>{0}. Получение атрибутов для данной записи невозможно. <br>",
parent == null ? "" : "в составе <a href =\"" + Service.UI.FormatLink((ScriptingObject)parent, true) + "\">" + parent.ToString() + "</a>"));
return;
}
var productConfiguration = pvc.GetInfoObject("ProductConfiguration");
var productVersion = pvc.GetInfoObject("ProductVersion");
// AA Родитель-изделие для версии изделия
var izdelie = productVersion.GetInfoObject("LinkToOriginalObject");
// АА Получение доступа к контейнеру ЭРИ Изделия
var ParentContainer = izdelie.ContainerOriginal;
var parameters = ParentContainer.GetAttribute("Parameters");
StringBuilder parameters_string = new StringBuilder();
var FSCValue = "Не указано";
var PN_MentorValue = "Не указано";
var ManufacturerValue = "Не указано";
var OriginalContainer = ParentContainer.ToString();
var nameIzdelie = izdelie.GetString("Name");
Dictionary<string, string> calculatedAttrs = new Dictionary<string, string>();
foreach (var item in parameters.CollectionElements) {
string attrName = item.GetString("NameInStandard");
if (attrName == "FSC" || attrName == "P/N Mentor" || attrName == "Производитель")
{
calculatedAttrs[attrName] = item.GetString("NameKeyTable");
//parameters_string.Append($"{attrName}: {calculatedAttrs[attrName]} ");
}
}
// OK
// parameters_string.Append($"FSC: {fsc_attr}; PN Mentor: {pn_mentor_attr}");
//
bool collectMode = false;
foreach (var param in ParentContainer.AllAttributes){
if (param.NameKey == "Name" && param.Value.ValueAsString == nameIzdelie){
collectMode = true;
}
if (collectMode && param.NameKey != "Order"){
if (calculatedAttrs["FSC"] == param.NameKey){
FSCValue = param.Value.ValueAsString;
}else if (calculatedAttrs["P/N Mentor"] == param.NameKey){
PN_MentorValue = param.Value.ValueAsString;
}else if (calculatedAttrs["Производитель"] == param.NameKey){
ManufacturerValue = param.Value.ValueAsString;
}
}else{
collectMode = false;
}
}
collectMode = false;
var allAttributes = ParentContainer.AllAttributes.ToList();
for (int i = allAttributes.Count - 1; i >= 0; i--) {
var param = allAttributes[i];
if (param.NameKey == "Name" && param.Value.ValueAsString == nameIzdelie){
collectMode = true;
}
if (collectMode && param.NameKey != "Order"){
if (calculatedAttrs["FSC"] == param.NameKey){
FSCValue = param.Value.ValueAsString;
}else if (calculatedAttrs["P/N Mentor"] == param.NameKey){
PN_MentorValue = param.Value.ValueAsString;
}else if (calculatedAttrs["Производитель"] == param.NameKey){
ManufacturerValue = param.Value.ValueAsString;
}
}else{
collectMode = false;
}
}
collectMode = false;
//Service.UI.ShowMessage(string.Join(", ", parameters_string));
/*bool collectMode = false;
bool orderMet = false;
foreach (var param in ParentContainer.AllAttributes) {
if (param.NameKey == "Name" && param.Value.ValueAsString == nameIzdelie)
{
collectMode = true;
continue;
}
if (collectMode) {
if (param.NameKey == "Order")
{
orderMet = true;
break;
}
if (calculatedAttrs.ContainsValue(param.NameKey))
{
if (param.NameKey == calculatedAttrs["FSC"])
{
FSCValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["P/N Mentor"])
{
PN_MentorValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["Производитель"])
{
ManufacturerValue = param.Value.ValueAsString;
}
}
}
}
if (!orderMet) {
for (int i = ParentContainer.AllAttributes.Count() - 1; i >= 0; i--)
{
var param = ParentContainer.AllAttributes.ElementAt(i);
if (param.NameKey == "Order")
{
break;
}
if (calculatedAttrs.ContainsValue(param.NameKey))
{
if (param.NameKey == calculatedAttrs["FSC"])
{
FSCValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["P/N Mentor"])
{
PN_MentorValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["Производитель"])
{
ManufacturerValue = param.Value.ValueAsString;
}
}
}
}
Service.UI.ShowMessage(string.Join(", ", parameters_string));
//parameters_string.Append($"FSC: {FSCValue} PN Mentor: {PN_MentorValue} Manuf.: {ManufacturerValue}");
// Clipboard.SetText(parameters_string.ToString());
/*
foreach (var param in ParentContainer.AllAttributes)
{
if (param.NameKey.Contains("attr") || param.NameKey.Contains("Name") || param.NameKey.Contains("Order")){
parameters_string.Append($"{param.NameKey} : {param.Value.Value}");
}
if (param.NameKey == "Name" && param.Value.ValueAsString == nameIzdelie)
{
attrReadMode = true;
}
if (attrReadMode && param.NameKey == "Order")
{
attrReadMode = false;
break;
}
if (attrReadMode && calculatedAttrs.ContainsValue(param.NameKey))
{
if (param.NameKey == calculatedAttrs["FSC"])
{
FSCValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["P/N Mentor"])
{
PN_MentorValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["Производитель"])
{
ManufacturerValue = param.Value.ValueAsString;
}
}
}
Clipboard.SetText(parameters_string.ToString());
for (int i = ParentContainer.AllAttributes.Count() - 1; i >= 0; i--) {
var param = ParentContainer.AllAttributes.ElementAt(i);
if (param.NameKey == "Name" && param.Value.ValueAsString == nameIzdelie) {
attrReadMode = true;
}
if (attrReadMode && param.NameKey == "Order") {
attrReadMode = false;
}
if (attrReadMode && calculatedAttrs.ContainsValue(param.NameKey))
{
if (param.NameKey == calculatedAttrs["FSC"])
{
FSCValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["P/N Mentor"])
{
PN_MentorValue = param.Value.ValueAsString;
}
if (param.NameKey == calculatedAttrs["Производитель"])
{
ManufacturerValue = param.Value.ValueAsString;
}
}
}
//parameters_string.Append($"{FSCValue}, {PN_MentorValue}, {ManufacturerValue}");
//Service.UI.ShowMessage(string.Join(", ", parameters_string));
/*
var fsc_inner_value = "";
var pn_mentor_inner_value = "";
foreach (var param in ParentContainer.AllAttributes) {
parameters_string.Append($"{param.NameKey}: {param.Value.Value} ");
if (param.NameKey == fsc_attr){
fsc_inner_value = param.Value.Value.ToString();
}
if (param.NameKey == pn_mentor_attr){
pn_mentor_inner_value = param.Value.Value.ToString();
}
if (param.NameKey == "Name" && param.Value.Value.ToString() == nameIzdelie){
if (fsc_inner_value != ""){
FSCValue = fsc_inner_value;
}
if (pn_mentor_inner_value != ""){
PN_MentorValue = pn_mentor_inner_value;
}
fsc_inner_value = "";
pn_mentor_inner_value = "";
}
} */
var documentVersion = pvc.GetInfoObject("ProductVersion.OriginalDocument");
var newCE = exportDataAttr.AddCollectionElement();
if (!isRoot || setRootLevel)
newCE["Quantity"] = quantity;
newCE["ProductItem"] = pvc;
newCE["OriginalDocument"] = documentVersion;
newCE["Level"] = level;
newCE["FSC"] = FSCValue;
newCE["PN_Mentor"] = PN_MentorValue;
newCE["OriginalContainer"] = OriginalContainer;
newCE["Manufacturer"] = ManufacturerValue;
// определения атрибутов, которые будут заполняться вручную
var manualyHandledAttributes = new[] { "Quantity", "Level", "ProductItem", "OriginalDocument",
"FSC", "PN_Mentor", "OriginalContainer", "Manufacturer"};
// AA attrNamesDict - словарь ключей из моей коллекции атрибутов "Экспортируемые элементы"
foreach (var kvp in attrNamesDict)
{
var attrName = kvp.Key;
var attrTags = kvp.Value;
// АА Этим можно вывести "Part Number" из коллекции Экспорт. элементы
// errors.AppendLine($"{attrName} |");
// пропустим ручные атрибуты
if (manualyHandledAttributes.Contains(attrName))
continue;
// пропустим авторассчётные атрибуты чтоб они сами считались
// AA Авторассчётные атрибуты - те, которые имеют включённое автовычисление и собств. скрипт (подлинник STEP и подлинник PDF)
if (newCE.GetAttributeDef(attrName).AutoCalculationKind == AttributeDefBase.AutoCalculationKindEnum.Calculating)
{
newCE.GetAttribute(attrName).TurnToCalculated();
continue;
}
if (newCE.GetAttributeDef(attrName).AutoCalculationKind != AttributeDefBase.AutoCalculationKindEnum.None){
continue;
}
IAttributableObject valueSource = pvc;
// если в тэгах содержится ключевое слово, то нужно использовать другой источник данных
if (attrTags.Any(str => str.StartsWith("DataSource")))
{
var sourceString = attrTags.First(str => str.StartsWith("DataSource"));
if (sourceString.Contains("Version"))
valueSource = productVersion;
else if (sourceString.Contains("Configuration"))
valueSource = productConfiguration;
else if (sourceString.Contains("Element") && sourceElement != null)
valueSource = sourceElement;
}
if (valueSource == null)
errors.AppendLine("<font color=\"Yellow\">Предупреждение!</font> атрибут <font color=\"Green\">" + attrName + "</font> не может быть выгружен из ИИВ <a href=\"" + Service.UI.FormatLink((ScriptingObject)pvc, true) + "\">" + pvc.ToString() + "</a> с тэгами <font color=\"Green\">" + attrTags.ToString() + "</font> <br>");
else{
newCE[attrName] = valueSource[attrName];
}
}
int levelCounter = 1;
// АА песочница с выводом функций и атрибутов элемента
/*
foreach (var itemz in pvc.GetCollectionElements("Items")) {
errors.Append(itemz.GetString("Part_Number"));
}
*/
foreach (var item in pvc.GetCollectionElements("Items").Safe().OrderBy(ce=>ce.GetString("SortedKey")))
{
// aa
// item - это Name + Quantity
var childQuantity = item.GetDouble("Quantity");
/*
if (item.ToString().Contains("C331")){
errors.Append(item);
}
*/
if (!isRoot && multiply)
childQuantity *= quantity;
var childLevel = string.Format("{0}{1}", isRoot ? "" : level + ".", levelCounter++.ToString());
// errors.Append(string.Join(", ", item.GetInfoObject("ProductItem").AllAttributes));
// АА Эта часть заполняет данными в интерфейсе
FillItems(item.GetInfoObject("ProductItem"), item, childQuantity, childLevel, false);
}
}
/// <summary>
/// Возвращает запрошенное представление объекта в UI.
/// </summary>
/// <param name="obj">Объект для которого требуется UI представление</param>
/// <param name="dataKind">Запрашиваемый вид данных (название, иконки, превью)</param>
/// <param name="context">Контекст вызова для доступа к списку формируемых дополнительных иконок</param>
/// <returns>null если следует использовать вариант по умолчанию,
/// String для названий объекта (форматированный HTML тэгами для NameDetails и RichName),
/// CustomIcon (или строковый ключ иконки в общем ImageListе) и AdditionalIcon[] или CustomIcon[] (или массив ключей) для иконок,
/// Image (или BlobDesc) для превью,
/// Color для раскраски элементов в дереве и списке,
/// FontStyle для указания стиля шрифта в дереве и списке</returns>
/// <remarks> Вызывается в основном клиентским UI кодом.
/// Название объекта может запрашиваться и серверным кодом.
/// Исключения, вышедшие их этого метода, отправляются в серверный отчет об ошибке без показа сообщения пользователю.</remarks>
public override Object GetUIData( InfoObject obj, AttributableDataObject.UIDataKind dataKind, UIDataInvokeContext context )
{
switch( dataKind )
{
// Имя по умолчанию
case AttributableDataObject.UIDataKind.Name:
break;
// Хранимое в базе имя
case AttributableDataObject.UIDataKind.NameForSearchInDb:
break;
// Прочие имена для разных контекстов использования
case AttributableDataObject.UIDataKind.NameForTreeView:
case AttributableDataObject.UIDataKind.NameForListView:
case AttributableDataObject.UIDataKind.NameForSearchResultListView:
case AttributableDataObject.UIDataKind.NameForHyperlink:
case AttributableDataObject.UIDataKind.NameForHyperlinkInGrid:
case AttributableDataObject.UIDataKind.NameForMultiLine:
break;
// Форматированная HTML тэгами строка - заголовок карточки объекта
case AttributableDataObject.UIDataKind.RichName:
break;
// Форматированная HTML тэгами строка, дополняющая название объекта в дереве
case AttributableDataObject.UIDataKind.NameDetails:
break;
case AttributableDataObject.UIDataKind.Tooltip:
// Текстовая строка всплывающей подсказки
break;
case AttributableDataObject.UIDataKind.MainIcon:
case AttributableDataObject.UIDataKind.MainIconForHyperLink:
case AttributableDataObject.UIDataKind.MainIconForHyperLinkInGrid:
// Следует вернуть или существующий объект CustomIcon или
// строковый ключ иконки в системном ImageList клиента.
// См. Service.UI.ImageListManager
break;
case AttributableDataObject.UIDataKind.MainOverlayIcon:
case AttributableDataObject.UIDataKind.MainOverlayIconForHyperLink:
case AttributableDataObject.UIDataKind.MainOverlayIconForHyperLinkInGrid:
// Следует вернуть или существующий объект CustomIcon или
// строковый ключ иконки в системном ImageList клиента.
// См. Service.UI.ImageListManager
break;
case AttributableDataObject.UIDataKind.AdditionalIcons:
// Дополнительные иконки складываются со всех родительских шаблонов в упорядоченное множество context.AdditionalIcons.
// Следует вернуть массив AdditionalIcon с настроенными ключами, изображением, всплывающей подсказкой и параметрами сортировки.
// Либо устаревший вариант: вернуть или IEnumerable<CustomIcon> существующих объектов CustomIcon или
// IEnumerable<String> строковых ключей иконок в системном ImageList клиента.
// См. Service.UI.ImageListManager
// Также можно вернуть IEnumerable< KeyValuePair<String, String|CustomIcon|Object> >. В этом случае
// результирующий набор иконок формируется по таким правилам:
// Сначала идут иконки с разными ключами (KeyValuePair.Key), сортированные по возрастанию этого ключа.
// Затем идут иконки с пустыми (или не указанными) ключами в порядке добавления (от родительских шаблонов к дочерним)
break;
case AttributableDataObject.UIDataKind.AdditionalIconsForListView:
case AttributableDataObject.UIDataKind.AdditionalIconsForHyperLink:
case AttributableDataObject.UIDataKind.AdditionalIconsForHyperLinkInGrid:
// См. AdditionalIcons
// По умолчанию используются AdditionalIcons
break;
case AttributableDataObject.UIDataKind.Preview:
// Следует вернуть или BlobDesc с бинарными данными изображения, либо объект Image
break;
case AttributableDataObject.UIDataKind.ColorForTreeView:
case AttributableDataObject.UIDataKind.ColorForListView:
case AttributableDataObject.UIDataKind.ColorForHyperLink:
case AttributableDataObject.UIDataKind.ColorForHyperLinkInGrid:
// Следует вернуть значение типа Color
break;
case AttributableDataObject.UIDataKind.FontStyleForTreeView:
case AttributableDataObject.UIDataKind.FontStyleForListView:
// Следует вернуть значение типа FontStyle
break;
case AttributableDataObject.UIDataKind.PropertiesWindowTitle:
// Заголовок плавающего окна с карточкой объекта
break;
}
return null;
}
/// <summary>
/// Возвращает список виртуальных определений атрибутов для отображения в карточке объекта
/// </summary>
/// <param name="obj">Объект, для которого запрашиваются виртуальные атрибуты</param>
/// <param name="defs">Список добавленных виртуальных определений атрибутов</param>
/// <remarks>Вызывается в порядке от родительских шаблонов к дочерним и модификаторам</remarks>
public override void GetVirtualAttributeDefs( InfoObject obj, List<AttributeDefVirtual> defs )
{
//var def = new AttributeDefVirtual( obj.Template, "p1", "Название атрибута", AttributeDefBase.DataTypeEnum.Text );
//def.DisplayType = AttributeDefBase.DisplayTypeEnum.TextBox;
//def.PageNameKey = "Main";
//defs.Add( def );
}
/// <summary>
/// Вызывается клиентским кодом UI перед показом карточки объекта.
/// </summary>
/// <param name="obj">Объект, чья карточка показывается</param>
/// <param name="propertySheet">Ссылка на интерфейс доступа к штатной карточке атрибутируемого объекта</param>
/// <remarks>Вызывается на клиентской стороне при использовании штатных карточек атрибутируемых объектов.
/// Исключения, вышедшие их этого метода, отправляются в серверный отчет об ошибке без показа сообщения пользователю.</remarks>
/// <remarks>Метод вызывается в порядке от шаблонов-родителей к детям-модификаторам </remarks>
public override void OnBeforeDisplayInUI( InfoObject obj, IPropertySheetCallback propertySheet )
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment