Тема: Навигация по спецификации средствами VBA (Excel)

Здравствуйте, уважаемые участники форума!
Возникла у меня задача получения позиций из TCS для своего приложения. Самостоятельно (дорабатывая примеры руководства smile) удалось подключиться к TCS и перейти в главную сборку изделия:

Sub Test()
    Dim I, J As Integer
    Dim Number As Integer
    Dim NMks As CSDN.Nomenclatures
    Dim Spec As CSDN.NmkSpecification
    Dim Props1 As CSDN.PropArray
    Dim Props2 As CSDN.PropArray
    
    Call Login
    If App.NmkClasses.RunModuleForSelect("Выберите класс", False) Then
        Set NMks = App.Nomenclatures(App.NmkClasses.Properties("ID").AsInteger)
        If NMks.RunModuleForSelect("Выберите номенклатуру", True) Then
            ActiveWorkbook.Sheets(1).Cells(1, 1).Value = "ID"
            ActiveWorkbook.Sheets(1).Cells(1, 2).Value = "Децимальный номер"
            ActiveWorkbook.Sheets(1).Cells(1, 3).Value = "Наименование"
            ActiveWorkbook.Sheets(1).Cells(1, 4).Value = "Тип"
            ActiveWorkbook.Sheets(1).Cells(1, 5).Value = "Кол-во"
            Number = 2
            If NMks.GotoSelectedRow(0) Then
                Set Spec = NMks.Properties("NmkSpecification").AsIDispatch
                Set Props2 = Spec.CreatePropArray(1)
                J = Props2.Add(0, "NMK_ID", 0)
                J = Props2.Add(0, "NMK_NOTE", 0)
                J = Props2.Add(0, "NMK_NAME", 0)
                J = Props2.Add(0, "NMK_CLASSIF_TYPE_NOTE", 0)
                J = Props2.Add(0, "QUANTITY", 0)
                Number = PrintDataToSheet(Number, Spec, Props2)
                Set Props2 = Nothing
                Set Spec = Nothing
            End If
        End If
        Set NMks = Nothing
    End If
End Sub

Добился распечатки позиций главной сборки на лист Excel (с фильтрацией по "NMK_CLASSIF_TYPE_NOTE"). Теперь встала задача, к которой не очень представляю, как подступиться: у сборок и комплектов (свойство "NMK_CLASSIF_TYPE_NOTE" имеет значение "СБ" или "КОМПЛЕКТ") есть возможность перейти на более низкий уровень. Вручную в TCS это выполнимо двойным щелчком, но как это сделать программно? Подскажите пожалуйста. Основная идея - переписать на лист Excel все сборки, комплекты, детали и т.д. выбранного изделия с указанием входимости (от детали до главной сборки) для последующей обработки.
Заранее благодарен за помощь
С уважением
Шаронов Андрей

Re: Навигация по спецификации средствами VBA (Excel)

Здравствуйте! ну честно говоря можно сильно по разному сделать. Так то и отчет проще у нас спроектировать, а скорее всего и готовый уже есть.

На всякий случай ознакомьтесь с советам по АПИ https://forum.technologics.ru/topic1441.html, ролик есть полезный https://forum.technologics.ru/user21.html, руководство пользователя.

Основной инструмент в работе API Explorer https://help.technologics.ru/7.9/TCSHelp/_800.htm. В нем можно все увидеть, пройти и даже заготовку кода получить. Там не все последнее есть правда, но основные режимы все присутствуют и далее понятно самому как делать.

Так же у нас идет много расширений с открытым кодом.

Конкретно по вашему случаю: У вас есть идентиифкатор номенклатуры, читаете его получаете через https://help.technologics.ru/7.9/TCSAPI … mId_13.htm (не забываем удалить https://forum.technologics.ru/post15111.html#p15111) Там получаете спецификацию и так далее.

Возможно будет гораздо проще написать свой набор данных https://help.technologics.ru/7.9/TCSHelp/_155.htm.

Ну а скорее всего более правильно воспользоваться итоговой спецификацией https://help.technologics.ru/7.9/TCSHelp/_295.htm, там все что вы делаете уже собрано. Там и же и отчеты нужные вам найдете скорее всего.

Спасибо сказали: Andrei881

Re: Навигация по спецификации средствами VBA (Excel)

Добрый день!
Огромное спасибо за ответ!

Олег Зырянов пишет:

Ну а скорее всего более правильно воспользоваться итоговой спецификацией https://help.technologics.ru/7.9/TCSHelp/_295.htm, там все что вы делаете уже собрано. Там и же и отчеты нужные вам найдете скорее всего.

Впринципе, сначала исходил тоже из этого варианта, причем, использовал экспортированную спецификацию в dbf-формате. Было очень удобно, но тут сказали, что в итоговой спецификации данные устарели. Сам к обновлению никакого доступа и касательства, к сожалению, не имею - фактически простой пользователь с установленной клиентской программой smile Как раз из-за этого пришлось разбираться уже с взаимодействием с TCS через API.

Олег Зырянов пишет:

Конкретно по вашему случаю: У вас есть идентиифкатор номенклатуры, читаете его получаете через https://help.technologics.ru/7.9/TCSAPI … mId_13.htm (не забываем удалить https://forum.technologics.ru/post15111.html#p15111) Там получаете спецификацию и так далее.

Воспользовался таким вариантом. Получился в итоге такой текст:

Private Function PrintSpec(Number As Long, Module As CSDN.DModule, ParentSborka As String)
    Dim J As Integer
    Dim Spec As CSDN.NmkSpecification
    Dim Props2 As CSDN.PropArray
    
    Set Spec = Module.Properties("NmkSpecification").AsIDispatch        'Переходим в спецификацию
    If Spec Is Nothing Then
        J = 0
    End If
    'Создаем массив свойств и заполняем его
    Set Props2 = Spec.CreatePropArray(1)                                
    J = Props2.Add(0, "NMK_ID", 0)                                      
    J = Props2.Add(0, "NMK_NOTE", 0)                                    
    J = Props2.Add(0, "NMK_NAME", 0)                                    
    J = Props2.Add(0, "NMK_CLASSIF_TYPE_NOTE", 0)                       
    J = Props2.Add(0, "QUANTITY", 0)                                    
    'Выводим спецификацию на лист
    Number = PrintDataToSheet(Number, Spec, Props2, ParentSborka)
    Set Props2 = Nothing
    Set Spec = Nothing
    PrintSpec = Number
End Function

Sub Test()
    Dim Golova As Long
    Dim Hvost As Long
    Dim CurrentSborka As String
    Dim NMks As CSDN.Nomenclatures
    Dim Nmk As CSDN.SingleNomenclature
        
    Call Login
    Set NMks = App.Nomenclatures(SB_ID)                                 
    If NMks.RunModuleForSelect("Выберите номенклатуру", True) Then
        'Заполняем шапку таблицы
        ActiveWorkbook.Sheets(1).Cells(1, 1).Value = "ID"
        ActiveWorkbook.Sheets(1).Cells(1, 2).Value = "Децимальный номер"
        ActiveWorkbook.Sheets(1).Cells(1, 3).Value = "Наименование"
        ActiveWorkbook.Sheets(1).Cells(1, 4).Value = "Тип"
        ActiveWorkbook.Sheets(1).Cells(1, 5).Value = "Кол-во"
        ActiveWorkbook.Sheets(1).Cells(1, 6).Value = "Куда входит"
        'Запоминаем децимальный номер главной сборки
        CurrentSborka = NMks.Properties("NOTE").AsString
        'Заносим данные главной сборки
        ActiveWorkbook.Sheets(1).Cells(2, 1).Value = NMks.Properties("ID").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 2).Value = NMks.Properties("NOTE").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 3).Value = NMks.Properties("NAME").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 4).Value = "СБ"
        ActiveWorkbook.Sheets(1).Cells(2, 5).Value = "1"
        Golova = 3                                                      'Установка индекса головы списка
        Hvost = 3                                                       'Установка индекса хвоста списка
        If NMks.GotoSelectedRow(0) Then
            Hvost = PrintSpec(Hvost, NMks, CurrentSborka)               'Выводим главную спецификацию
            Do
                If ((ActiveWorkbook.Sheets(1).Cells(Golova, 4).Value = "СБ") Or (ActiveWorkbook.Sheets(1).Cells(Golova, 4).Value = "КОМПЛЕКТ")) Then
                'Если текущая позиция сборка или комплект
                    Set Nmk = App.SingleNmkFromId(CLng(ActiveWorkbook.Sheets(1).Cells(Golova, 1).Value))
                    Hvost = PrintSpec(Hvost, Nmk, CStr(ActiveWorkbook.Sheets(1).Cells(Golova, 2).Value))
                    Set Nmk = Nothing
                End If
                Golova = Golova + 1                                     'Инкремент головы
            'Выполняем цикл до того момента пока "голова" не настигнет "хвост" - т.е. все записи, 
            'полученные от TCS будут обработаны на признак сборки
            Loop Until Golova = Hvost                                   
        End If
        Set NMks = Nothing
        Set Nmk = Nothing
    End If
End Sub

Впринципе, на листе получается то, что нужно, но, такое ощущение, что происходит переполнение памяти - в какой-то момент строчка

Set Spec = Module.Properties("NmkSpecification").AsIDispatch

Дает Spec=Nothing. Получается, что я неправильно очищаю переменные? Если честно, не очень понял, как определять, какого типа является переменная (имеется в виду, пост о типах памяти). Вроде бы, все объявлены, как локальные, но, возможно, я что-то не так понял?
Насчет ролика - нашел, гляну smile Тем более, у нас еще TCS 5.5 стоит smile
Еще раз огромное спасибо!
С уважением
Шаронов Андрей

Re: Навигация по спецификации средствами VBA (Excel)

Не припомню у нас версии 5.5. Скорее всего у вас все таки не TechnologiCS. В этом случае лучше конечно обратиться к менеджерам https://www.technologics.ru/contacts.html, там  наверное лучше объяснят ситуацию.

По поводу памяти я ссылку кидал.

Впринципе, сначала исходил тоже из этого варианта, причем, использовал экспортированную спецификацию в dbf-формате. Было очень удобно, но тут сказали, что в итоговой спецификации данные устарели.

Честно говоря не сильно понятно. Итоговую спецификацию надо разузловать, чтобы были последние данные. Ну и права запросить.

А так все выше написанное все таки относится именно к TechnologiCS. Хотя 5-ка очень старая, и там много нет.

(изменено: Andrei88, 18 сентября 2023 14:22:29)

Re: Навигация по спецификации средствами VBA (Excel)

Олег Зырянов пишет:

По поводу памяти я ссылку кидал.

Вот как раз я и не понял из поста по ссылке, в какой у меня памяти находятся объявляемые модули.

Олег Зырянов пишет:

Не припомню у нас версии 5.5

Сейчас глянул - версия 5.5.5.0

Re: Навигация по спецификации средствами VBA (Excel)

Сейчас глянул - версия 5.5.5.0

Я понял. Это не TechnologiCS. Подробнее менеджеры могут объяснить.

(изменено: Andrei88, 2 октября 2023 06:01:19)

Re: Навигация по спецификации средствами VBA (Excel)

Удалось-таки сделать рабочий вариант. Надеюсь, более-менее правильный:

Private Function PrintSpec(Number As Long, Module As CSDN.DModule, ParentSborka As String)
    Const retries As Integer = 5
        
    Dim J As Integer
    Dim t As Integer
    Dim Spec As CSDN.NmkSpecification
    Dim Props2 As CSDN.PropArray
    
    For t = 0 To retries
        Set Spec = Module.Properties("NmkSpecification").AsIDispatch    'Ïåðåõîäèì â ñïåöèôèêàöèþ
        Spec.UserModuleName = "Spec"
        If Not (Spec Is Nothing) Then
            Exit For
        Else
            'Set Spec = Nothing
            App.DeleteModuleByUserModuleName ("Spec")
        End If
    Next t
    'If Spec Is Nothing Then
    '    J = 0
    'End If
    Set Props2 = Spec.CreatePropArray(1)                                'Ñîçäàåì ìàññèâ ñâîéñòâ è çàïîëíÿåì åãî
    J = Props2.Add(0, "NMK_ID", 0)                                      'Èäåíòèôèêàòîð ïîçèöèè â ñïåöèôèêàöèè
    J = Props2.Add(0, "NMK_NOTE", 0)                                    'Äåöèìàëüíûé íîìåð
    J = Props2.Add(0, "NMK_NAME", 0)                                    'Íàèìåíîâàíèå
    J = Props2.Add(0, "NMK_CLASSIF_TYPE_NOTE", 0)                       'Òèï
    J = Props2.Add(0, "QUANTITY", 0)                                    'Êîëè÷åñòâî
    'Âûâîäèì ñïåöèôèêàöèþ íà ëèñò
    Number = PrintDataToSheet(Number, Spec, Props2, ParentSborka)
    'Call App.DeleteModuleByUserModuleName("Spec")
    'Call App.DeleteModuleByUserModuleName("Props2")
    Set Props2 = Nothing
    'Set Spec = Nothing
    App.DeleteModuleByUserModuleName ("Spec")
    PrintSpec = Number
End Function

Sub Test()
    Const retries As Integer = 5
    
    Dim t As Integer
    Dim Golova As Long
    Dim Hvost As Long
    Dim CurrentSborka As String
    Dim NMks As CSDN.Nomenclatures
    Dim Nmk As CSDN.SingleNomenclature
        
    Call Login
    Set NMks = App.Nomenclatures(SB_ID)                                 'Переходим в раздел "СБ" в номенклатуре
    If NMks.RunModuleForSelect("Выберите номенклатуру", True) Then      'Открываем диалог выбора изделия из классификатора
        'Заполняем шапку таблицы
        ActiveWorkbook.Sheets(1).Cells(1, 1).Value = "ID"
        ActiveWorkbook.Sheets(1).Cells(1, 2).Value = "Децимальный номер"
        ActiveWorkbook.Sheets(1).Cells(1, 3).Value = "Наименование"
        ActiveWorkbook.Sheets(1).Cells(1, 4).Value = "Тип"
        ActiveWorkbook.Sheets(1).Cells(1, 5).Value = "Кол-во"
        ActiveWorkbook.Sheets(1).Cells(1, 6).Value = "Куда входит"
        'Запоминаем децимальный номер главной сборки
        CurrentSborka = NMks.Properties("NOTE").AsString
        'Заносим данные главной сборки
        ActiveWorkbook.Sheets(1).Cells(2, 1).Value = NMks.Properties("ID").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 2).Value = NMks.Properties("NOTE").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 3).Value = NMks.Properties("NAME").AsString
        ActiveWorkbook.Sheets(1).Cells(2, 4).Value = "СБ"
        ActiveWorkbook.Sheets(1).Cells(2, 5).Value = "1"
        Golova = 3                                                      'Установка счетчика головы (номер текущей обрабатываемой позиции)
        Hvost = 3                                                       'Установка счетчика хвоста (номер последней добавленной позиции)
        If NMks.GotoSelectedRow(0) Then
            Hvost = PrintSpec(Hvost, NMks, CurrentSborka)               'Выводим главную сборку
            Do
                If ((ActiveWorkbook.Sheets(1).Cells(Golova, 4).Value = "СБ") Or (ActiveWorkbook.Sheets(1).Cells(Golova, 4).Value = "КОМПЛЕКТ")) Then
                'Если текущая позиция сборка или комплект
                    For t = 0 To retries
                        Set Nmk = App.SingleNmkFromId(CLng(ActiveWorkbook.Sheets(1).Cells(Golova, 1).Value))
                        Nmk.UserModuleName = "Nomeklature"
                        If Not (Nmk Is Nothing) Then
                            Exit For
                        Else
                            App.DeleteModuleByUserModuleName ("Nomeklature")
                        End If
                    Next t
                    Hvost = PrintSpec(Hvost, Nmk, CStr(ActiveWorkbook.Sheets(1).Cells(Golova, 2).Value))
                    'Set Nmk = Nothing
                    App.DeleteModuleByUserModuleName ("Nomeklature")
                End If
                Golova = Golova + 1                                     'Инкремент головы
            Loop Until Golova = Hvost                                   'Выполняем цикл до того момента пока "голова" не настигнет "хвост" - т.е. все записи, полученные от TCS будут обработаны на признак сборки
        End If
        Set NMks = Nothing
        Set Nmk = Nothing
    End If
End Sub

Теперь столкнулся с другой проблемой - необходимостью запроса материала и массы детали. Сказали, что масса и материал присутствуют в "Карточке номенклатуры". Идентификаторы их "TCS_ST_KG" и "M_DET". Как-то до них можно добраться программно?
Писал вот такую конструкцию:

Set NMks = App.Nomenclatures2(SB_ID, "TCS_ST_KG")

Но можно ли теперь как-то считывать данные "TCS_ST_KG" для конкретной детали в спецификации?
С уважением
Шаронов Андрей

Re: Навигация по спецификации средствами VBA (Excel)

Я вам в личку ответил.