Официальный форум российского программного комплекса T-FLEX PLM


Поиск  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
Получить путь связанного объекта(файла) из Структуры изделия
 

Добрый день!

Я работаю с режимом "Структура изделия", все позиции которые есть в структуре изделия выгружаю в pdm систему, но чтобы это сделать нужно открыть каждую деталь и сохранить ее, для этого нужен путь файла. Путь файла искала в режиме 3D модель, обозначение файла брала из структуры изделия и искала соответствие в дереве построения. Но столкнулась с вариантом когда, в дереве построения и в структуре изделия обозначения отличаются, но при этом если в структуре становлюсь на какую-то позицию, то в дереве она подсвечивается. Столкнулась с тем, что могу вытащить путь связанного объекта и отдельно Обозначение и Наименование, но связать их между собой не получается.

На входе имею см. рисунок1.

Далее использую код, который бегает по структуре изделия и считывает Обозначение, Наименование, Путь(расположение связанных объектов) и записывает в таблицу.

Если я использую код:

Код
   //создаем столбцы в Data Table
           System.Data.DataTable dt = new System.Data.DataTable();
           dt.Columns.Add("NOTE_SPEC", typeof(string));
           dt.Columns.Add("NAME_SPEC", typeof(string));
           dt.Columns.Add("CHECK_POS", typeof(Boolean));
           dt.Columns.Add("Path", typeof(string));
           document = TFlex.Application.ActiveDocument;
           //получаем объекты дерева построения            
           //1-параметр - ссылка на текущую сборку
           //2-параметр - указывает нужно ли, кроме ссылок на grb, возвращать ссылки на картинки, БД.
           //3-параметр - указывает нужно ли возвращать ссылки на библиотечные фрагменты
           //последний параметр - позволяет задать уровень вложенности, 
           //для которого нужно получить ссылки(false - 1 уровень вложенности, true - поиск на всю глубину сборки)
           string[] filePaths = TFlex.Application.GetDocumentExternalFileLinks(document.FileName, false, false, false);

           //бегаем по спецификации T-flex 
           foreach (var ps in document.GetProductStructures())
           {
               //перебор всех элементов/записей
               foreach (var elem in ps.GetAllRowElements())
               {
                   var includeInReport = (bool)elem.IncludeInDoc.Value; //true/false если стоит галочка включать в спецификацию
                   d = elem.SourceFragmentPath; //расположение (путь) связанного объекта

                   if (d != null)
                   {
                       //перебор групп(разделов) "главного" представления:
                       foreach (var group in ps.GetRowElementGroups())
                       {
                           string groupName = group.Name;

                           if ((groupName == "Документация") || (groupName == "Сборочные единицы") || (groupName == "Детали") || (groupName == "Прочие изделия"))
                           {
                               foreach (var item in group.Items)
                               {
                                   //Значения элемента
                                   dynamic mainElem = item.MergedElements.First();
                                   string paramValue = mainElem[new Guid("ee9a8bc0-c016-4915-9baa-69b2d8c28786")].ValueAsString; //обозначение
                                   string paramValue1 = mainElem[new Guid("44bb724a-de07-4fd3-9882-ced1c8425057")].ValueAsString; //наименование

                                   if ((groupName == "Документация") || (groupName == "Детали") || (groupName == "Сборочные единицы") || (groupName == "Прочие изделия"))
                                   {
                                       //добавляем строку в Data Table и запоняем ее
                                       DataRow newRow = dt.Rows.Add();
                                       newRow.SetField("NOTE_SPEC", paramValue);
                                       newRow.SetField("NAME_SPEC", paramValue1);
                                       newRow.SetField("CHECK_POS", true);
                                       count_row = Convert.ToInt16(dt.Rows.Count.ToString());

                                       if (paramValue.Contains(" СБ") == true)
                                       {
                                           string paths = document.FileName.ToString();
                                           newRow.SetField("path", paths); //заполняем строку
                                       }
                                       else
                                       {
                                           newRow.SetField("path", d); //заполняем строку
                                       }
                                   }
                               }
                           }
                       }
                   }
               }   
           }
           gridContrl.DataSource = null; 
           gridContrl.DataSource = dt;


то на выходе получаю (см.рисунок2). Обратите внимание, что колонки Обозначение и Расположение файла не соответствуют.

Если использую код, который вытаскивает правильно Обозначение, то не могу получить Расположение файла, так как SourceFragmentPath есть только в GetAllRowElements. (см. рисунок3)
Код
//создаем столбцы в Data Table
            System.Data.DataTable dt = new System.Data.DataTable();
            dt.Columns.Add("NOTE_SPEC", typeof(string));
            dt.Columns.Add("NAME_SPEC", typeof(string));
            dt.Columns.Add("CHECK_POS", typeof(Boolean));
            dt.Columns.Add("Path", typeof(string));
            document = TFlex.Application.ActiveDocument;
            //получаем объекты дерева построения            
            //1-параметр - ссылка на текущую сборку
            //2-параметр - указывает нужно ли, кроме ссылок на grb, возвращать ссылки на картинки, БД.
            //3-параметр - указывает нужно ли возвращать ссылки на библиотечные фрагменты
            //последний параметр - позволяет задать уровень вложенности, 
            //для которого нужно получить ссылки(false - 1 уровень вложенности, true - поиск на всю глубину сборки)
            string[] filePaths = TFlex.Application.GetDocumentExternalFileLinks(document.FileName, false, false, false);

            //бегаем по спецификации T-flex 
            foreach (var ps in document.GetProductStructures())
            {
                //перебор всех элементов/записей
                foreach (var elem in ps.GetAllRowElements())
                {
                    var includeInReport = (bool)elem.IncludeInDoc.Value; //true/false если стоит галочка включать в спецификацию
                    d = elem.SourceFragmentPath; //расположение (путь) связанного объекта
                }
                    if (d != null)
                    {
                        //перебор групп(разделов) "главного" представления:
                        foreach (var group in ps.GetRowElementGroups())
                        {
                            string groupName = group.Name;

                            if ((groupName == "Документация") || (groupName == "Сборочные единицы") || (groupName == "Детали") || (groupName == "Прочие изделия"))
                            {
                                foreach (var item in group.Items)
                                {
                                    //Значения элемента
                                    dynamic mainElem = item.MergedElements.First();
                                    string paramValue = mainElem[new Guid("ee9a8bc0-c016-4915-9baa-69b2d8c28786")].ValueAsString; //обозначение
                                    string paramValue1 = mainElem[new Guid("44bb724a-de07-4fd3-9882-ced1c8425057")].ValueAsString; //наименование

                                    if ((groupName == "Документация") || (groupName == "Детали") || (groupName == "Сборочные единицы") || (groupName == "Прочие изделия"))
                                    {
                                        //добавляем строку в Data Table и запоняем ее
                                        DataRow newRow = dt.Rows.Add();
                                        newRow.SetField("NOTE_SPEC", paramValue);
                                        newRow.SetField("NAME_SPEC", paramValue1);
                                        newRow.SetField("CHECK_POS", true);
                                        count_row = Convert.ToInt16(dt.Rows.Count.ToString());

                                        if (paramValue.Contains(" СБ") == true)
                                        {
                                            string paths = document.FileName.ToString();
                                            newRow.SetField("path", paths); //заполняем строку
                                        }
                                        else
                                        {
                                            newRow.SetField("path", d); //заполняем строку
                                        }
                                    }
                                }
                            }
                        }
                    }
                //}   
            }
            gridContrl.DataSource = null; 
            gridContrl.DataSource = dt;

Получается я могу получить либо только расположение файлов, либо реальные обозначение и наименование деталей.

Подскажите пожалуйста, как получить и Расположение связанных объектов, и Обозначение, и Наименование, при этом сохранив все условия из кода?

рисунок1.jpg (509.68 КБ)
рисунок2.jpg (309.04 КБ)
Рисунок3.jpg (69.92 КБ)
 
Анна, пример выгрузки данных структуры изделия в XML:
Код
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using TFlex.Model;
using TFlex.Model.Data.ProductStructure;

namespace Test
{
    public class ProductStructureInfo
    {
        private static readonly Document document = TFlex.Application.ActiveDocument;

        public static void Run()
        {
            if (document == null)
                return;

            string path = Path.Combine(document.FilePath, "product_structure_data.xml");
            //
            // GUID схемы структуры изделия (см. C:\Program Files\T-FLEX CAD 16\Program\ProductStructs\Default product structure.xml)
            //
            Guid guid = new Guid("{0971322f-b6bb-46ae-891e-1abb26e0a252}");
            //
            // Получаем ссылку на объект структуры изделия из активного документа
            //
            ProductStructure ps = document.GetProductStructures().Where(p => p.SchemeId == guid).FirstOrDefault();
            if (ps != null)
            {
                XDocument xml = ProductStructureToXml(ps);
                xml.Save(path);
            }
        }

        private static XDocument ProductStructureToXml(ProductStructure ps)
        {
            //
            // Получаем ссылку на объект схемы
            //
            Scheme scheme = ps.GetScheme();
            //
            // Создаем объект XML документа
            //
            XDocument document = new XDocument(new XDeclaration("1.0", "utf-8", null));
            XElement psElement = new XElement("ProductStructure",
                new XAttribute("uid", scheme.UID),
                new XAttribute("name", scheme.Name), 
                new XAttribute("path", scheme.OriginalPath));

            XElement groups = new XElement("Groups");

            SetGroup(groups, ps);

            psElement.Add(groups);
            document.Add(psElement);
            return document;
        }

        private static void SetGroup(XElement groups, ProductStructure psParent)
        {
            Document child;
            Scheme scheme = psParent.GetScheme();
            XElement fragment;

            foreach (var row in psParent.GetRowElementGroups())
            {
                XElement group = new XElement("Group", new XAttribute("name", row.Name));

                switch (row.Name)
                {
                    case "Детали":
                        foreach (var i in row.RowElements)
                        {
                            //
                            // Добавление фрагмента детали в XML-документ
                            //
                            fragment = new XElement("Fragment", new XAttribute("id", i.ObjectId));
                            SetElement(scheme, fragment, i);
                            group.Add(fragment);
                        }
                        break;
                    case "Сборочные единицы":
                        foreach (var j in row.RowElements)
                        {
                            //
                            // Добавление фрагмента подсборки в XML-документ
                            //
                            fragment = new XElement("Fragment", new XAttribute("id", j.ObjectId));
                            SetElement(scheme, fragment, j);
                            //
                            // Открываем документ, относительно пути элемента структуры изделия
                            //
                            if ((child = TFlex.Application.OpenDocument(j.SourceFragmentPath, false)) != null)
                            {
                                //
                                // Получаем ссылку на объект ProductStructure из дочернего документа
                                //
                                ProductStructure childPs = child.GetProductStructures().Where(p => p.SchemeId == scheme.UID).FirstOrDefault();

                                if (childPs != null)
                                {
                                    //
                                    // Добавляем элемент Groups к фрагменту подсборки
                                    //
                                    XElement childGroups = new XElement("Groups");
                                    //
                                    // Рекурсивный вызов метода SetGroup с параметрами подсборки
                                    //
                                    SetGroup(childGroups, childPs);
                                    fragment.Add(childGroups);
                                }

                                child.Close();
                            }

                            group.Add(fragment);
                        }
                        break;
                }

                groups.Add(group);
            }
        }

        private static void SetElement(Scheme scheme, XElement fragment, RowElement element)
        {
            foreach (var p in scheme.Parameters)
            {
                switch (p.Name)
                {
                    case "Наименование":
                        fragment.Add(new XElement("parameter", 
                            new XAttribute("name", p.Name), 
                            new XAttribute("value", element[p.UID].Text)));
                        break;
                    case "Обозначение":
                        fragment.Add(new XElement("parameter",
                            new XAttribute("name", p.Name),
                            new XAttribute("value", element[p.UID].Text)));
                        break;
                    case "Позиция из фрагмента":
                        fragment.Add(new XElement("parameter",
                            new XAttribute("name", p.Name),
                            new XAttribute("value", element[p.UID].Text)));
                        break;
                }
            }

            fragment.Add(new XElement("parameter", 
                new XAttribute("name", "Путь к фрагменту"), 
                new XAttribute("value", element.SourceFragmentPath)));
        }
    }
}
T-FLEX CAD 17.1.6.0
 
vite, подскажите пожалуйста какую ссылку вы используете для определения "SchemeId"?
Ошибка такая: " 'TFlex.Model.ProductStructure' does not contain a definition for 'SchemeId' and no extension method 'SchemeId' accepting a first argument of type 'TFlex.Model.ProductStructure' could be found (are you missing a using directive or an assembly reference?) "
 
Цитата
Анна написал:
подскажите пожалуйста какую ссылку вы используете для определения "SchemeId"?
это свойство было добавлено в T-FLEX CAD API 16, но вы можете определить схему по наименованию, например:
Код
ProductStructure ps = document.GetProductStructures().Where(p => p.Name == "Данные для спецификации").FirstOrDefault();
T-FLEX CAD 17.1.6.0
 
vite, спасибо Вам большое, как всегда выручили!!!
Страницы: 1