Библиотека APL_PSS_API

Модераторы: deschere, ayatsk

TuMKa
Сообщения: 5
Зарегистрирован: 19 май 2022, 15:58

Библиотека APL_PSS_API

Сообщение TuMKa »

Здравствуйте!
У меня несколько вопросов о работе методов библиотеки APL_PSS_API. Разработка ведется на C# (VS 2022)

1. Метод IAplAPI_Document::GetFileName не возвращает имя файла, хотя файл у документа есть точно, его можно выгрузить методом IAplAPI_Document::LoadRevision. Это ошибка или я что-то не так делаю? Пример:

Код: Выделить всё

....
  int pdf = aplPssAPI.SelectInstance(inWorkOptions, new object[0]); // inWorkOptions = 4
            if (pdf > 0)
            {
                dynamic outRel = null;
                dynamic outExt = null;
            	aPI_Document.FindAssociatedDocuments(pdf, ref outExt, ref outRel);
            	int[] arrDoc = (int[])outExt;
                        for (int i = 0; i < arrDoc.Length; i++)
                        {

                            aPI_Document.LoadDocumentDictionary();
                            aPI_Document.LoadDocInfo(arrDoc[i]);
                            var file = "";
                            aPI_Document.GetFullFileName(arrDoc[i], file);
                            // ------------------------------------^^^^^ - переменная после выполнения метода остается пустой.
            }
2. Не отфильтровываются элементы состава по дате при использовании метода IAplAPI_Product::FilterlByDate
Пример:

Код: Выделить всё

....
  int pdf = aplPssAPI.SelectInstance(inWorkOptions, new object[0]); // inWorkOptions = 4
            if (pdf > 0)
            {
                  aPI_Product.LoadAllSubProduct(0, 0, pdf, out object extRel, out object extPdf_1, 1);
                  bool result = aPI_Product.FilterlByDate(extPdf_1, dtFilter.Value, out object extPdf); // где текущая дата в формате DateTime
  
                  // по итогу result = true, а количество элементов в массиве extPdf_1 равно количеству элементов extPdf
                  // хотя в настройках применяемости один элемент заменен другим на дату прошлого месяца.
                  // заменный элемент отображается в дереве блеклым и перечеркнутым шрифтом
            
            }
3. Не могу найти метод и понять каким образом можно получить набор данных допустимых замен, если в сборке есть деталь, которая может быть заменена в контексте сборки другой?

Заранее благодарен за ответы.
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

Метод IAplAPI_Document::GetFileName не возвращает имя файла
Похоже, в API ошибка. Исправим в ближайшем будущем. Пока можно прочитать имя файла просто читая атрибуты. Вот пример:

Код: Выделить всё

Type PssApiType = Type.GetTypeFromProgID("APL_PSS_API.AplPssAPI");
if (null == PssApiType) return;
dynamic PssApiInst = Activator.CreateInstance(PssApiType);
if (null == PssApiInst) return;

APL_PSS_API_Lib.IAplAPI pss = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Data pssData = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Document pssDoc = PssApiInst;


object b=pss.Connect("Administrator", "", "DEMO");
if (false==(bool)b) return;

try
{
    pssDoc.LoadDocumentDictionary();

    object obj = null;
    int doc = (int)pss.SelectInstance(16, obj);
    if (0 == doc) throw new Exception("Ничего не выбрано");

    pssDoc.LoadDocInfo(doc);
    //string file = "";
    //b=pssDoc.GetFullFileName(doc, file);

    int revision = 0;
    if ((bool)pssData.IsKindOfBN(doc, "apl_document")) revision = (int)pssData.GetAttrBN(doc, "active");
    else if ((bool)pssData.IsKindOfBN(doc, "apl_document_revision")) revision = doc;
    else throw new Exception("Вместо документа непонятный объект");

    int stor = (int)pssData.GetAttrBN(revision, "access_form");

    if (0 == stor) throw new Exception("Нес файла у документа");
                
    object o_fname = null;
    if ((bool)pssData.IsKindOfBN(stor, "apl_stored_document")) o_fname = pssData.GetAttrBN(stor, "file_name");
    else if ((bool)pssData.IsKindOfBN(stor, "apl_assigned_document")) o_fname = pssData.GetAttrBN(stor, "location_path");

    string sFileName = o_fname.ToString();

    MessageBox.Show(sFileName, "Имя файла", MessageBoxButtons.OK);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK);
}
pss.Disconnect();

Вызывать aPI_Document.LoadDocumentDictionary(); достаточно 1 раз после Connect.

2. Не отфильтровываются элементы состава по дате при использовании метода IAplAPI_Product::FilterlByDate
Фильтровать надо не extPdf_1, а extRel.
Не могу найти метод и понять каким образом можно получить набор данных допустимых замен,
Специальных функций в API нет. Нужно искать объекты "product_definition_substitute" и обрабатывать результаты.

Если у файла aplDBE.bin (в папке с PSS) изменить расширение на .exe, то с помощью него можно содержимо БД и разобраться как устроены замены.
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

Ошибка с IAplAPI_Document::GetFileName исправлена в версии 5_634.
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

Еще один рабочий пример на C# на всякий случай

Код: Выделить всё

Type PssApiType = Type.GetTypeFromProgID("APL_PSS_API.AplPssAPI");
if (null == PssApiType) return;
dynamic PssApiInst = Activator.CreateInstance(PssApiType);
if (null == PssApiInst) return;

APL_PSS_API_Lib.IAplAPI pss = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Data pssData = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Folder pssFolder = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Document pssDoc = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Product pssPrd = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Autorization pssAuth = PssApiInst;
APL_PSS_API_Lib.IAplAPI_BProcess pssBP = PssApiInst;
APL_PSS_API_Lib.IAplAPI_Characteristic pssCharact = PssApiInst;

object b = pss.Connect("Administrator", "", "DEMO");
if (false == (bool)b) return;

pssCharact.LoadCharacteristicDictionary();

try
{
    object obj = null;
    int pdf = (int)pss.SelectInstance(8, obj);
    if (0 == pdf) throw new Exception("Ничего не выбрано");

    object o_extRel0 = null, o_extRel1 = null, o_extPdf = null;
    pssPrd.LoadAllSubProduct(0, 0, pdf, out o_extRel0, out o_extPdf, 1); // Получаем состав сборки

    DateTime dt = DateTime.Now;
    bool result = (bool)pssPrd.FilterlByDate(o_extRel0, dt,  out o_extRel1); // Фильтруем на текущую дату

    int[] extRel=(int[]) o_extRel1;

    object oStrTmp;
    string sPos, sUnitName, sPdfName, sContent="";

    foreach (int rel in extRel)
    {
        sPdfName = ""; sPos = ""; sUnitName = "";
                    
        int pdf1 = (int) pssData.GetAttrBN(rel, "related_product_definition");
        oStrTmp = pss.GetInstanceName(pdf1);
        sPdfName = oStrTmp.ToString();

        oStrTmp = pssData.GetAttrBN(rel, "id");
        sPos = oStrTmp.ToString();

        double dCount = (double) pssData.GetAttrBN(rel, "value_component");

        int unit = (int)pssData.GetAttrBN(rel, "unit_component");
        if (0 == unit) sUnitName = "шт.";
        else pssCharact.GetUnitName(unit, out sUnitName);

        string sItem = string.Format("\n {0}: {1}  Кол-во: {2} {3}", sPos, sPdfName, dCount.ToString(), sUnitName);
        sContent += sItem;
    }
    MessageBox.Show(sContent, "Состав", MessageBoxButtons.OK);

}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK);
}
pss.Disconnect();
TuMKa
Сообщения: 5
Зарегистрирован: 19 май 2022, 15:58

Re: Библиотека APL_PSS_API

Сообщение TuMKa »

Спасибо за комментарии. До "product_definition_substitute" еще руки не добрались пока вопросов к этому нет.
Воспользовался aplDBE.exe и вот тут мне непонятно следующее:
Идентификатор объекта в PSM.exe и aplDBE.exe 4-x значные, например: 5234, а API предоставляет этот идентификатор как 131570904.
Как мне получить 4х значный идентификатор?
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

Есть идентификатор объекта в БД. У Вас он четырехзначный т.к. БД очень маленькая. При загрузке объекта в кэш на клиенте у него появляется адрес в памяти, который актуален только во время текущей сессии. Он длинный т.к. адреса ниже 0x400000 зарезервированы за ядром windows. Практически во всех функциях API используется адрес в памяти. При использовании ActiveX этот адрес в памяти представляется как int, т.к. при использовании ActiveX напрямую с памятью работать нельзя.

Получить идентификатор в БД по адресу в памяти: IAplAPI_Data::GetInstanceId
Получить адрес в памяти по идентификатору в БД: IAplAPI_Data::GetInstanceById (при вызове, если в кэше не было информации об объекте, то она будет загружена автоматически, но значения атрибутов загружены не будут. Как правило, их можно загрузить с помощью IAplAPI::LoadExtentInfo.
TuMKa
Сообщения: 5
Зарегистрирован: 19 май 2022, 15:58

Re: Библиотека APL_PSS_API

Сообщение TuMKa »

Здравствуйте, такой вопрос:
Делаю проверку ЭП документов, и мне нужно определить статус электронной подписи. Выполняю следующие шаги:

Код: Выделить всё

                           aPI_Autorization.LoadItemApproval(doc, out approvalitem);
                           foreach(int approv in approvalitem)
                           {
                                   aPI_Product.LoadProductInfo(approv);
                                   int id_appr = aPI_Data.GetAttrBN(approv, "status");
                                   aPI_Product.LoadProductInfo(id_appr);
                                   string status_name = aPI_Data.GetAttrBN(id_appr, "name");
                                   ^^^^^^^^^^^^^^^^^^^^^^^
                                   здесь вместо ожидаемого "Копия верна" получаю null
                            }                            
хотя при просмотре объектов через aplDBE.exe свойство name у элемента есть (см. скриншот)
2022-08-26_12-43-00.png
Прошу пояснить, где я делаю неправильно.
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

1. aPI_Product.LoadProductInfo зачитывает в память информацию об изделии. Если ей передать подпись - она ничего делать не будет. В данном случае вызывать дополнительное чтение не нужно, т.к. aPI_Autorization.LoadItemApproval() зачитывает всё что нужно.

2. Атрибуты статуса относятся к «статической» информации, которая, зачитывается один раз после коннекта функциями LoadDictionary()). Но, чтение атрибутов статуса из ActiveX как-то выпало. Сейчас можно вместо aPI_Product.LoadProductInfo(id_appr); Вставить вызов IAplAPI::LoadExtentInfo().

Но лучше взять с сайта версию 5_650. В ней зачитывание ролей и статусов добавлено в IAplAPI_Autorization::LoadOrgStruct(), которую надо вызвать один раз после коннекта.
TuMKa
Сообщения: 5
Зарегистрирован: 19 май 2022, 15:58

Re: Библиотека APL_PSS_API

Сообщение TuMKa »

Здравствуйте, каким методом можно получить список папок первого уровня от головной объекта "Папки" как например:
папки.png
Попробовал загрузить сначала все ентити типа api_folder:
LoadEntityExtentFromDB("apl_folder")
затем отобрать те их них, у которых нет родительской папки (свойство "parent" равно null), но этот вариант не подошел - в список попадают много других лишних папок. Полагаю в этот список могли попасть и папки из раздела "Мой рабочий стол" и просто папки никуда не входящие.
Аватара пользователя
ayatsk
Сообщения: 402
Зарегистрирован: 03 июл 2008, 22:41
Откуда: НИЦ CALS
Контактная информация:

Re: Библиотека APL_PSS_API

Сообщение ayatsk »

IAplAPI_Folder::GetAllSubFolder() и родителем указать 0

или IAplAPI::QueryExecute() с таким запросом: "SELECT Ext_ FROM Ext_ {apl_folder(.parent = #0 )} END_SELECT"
Ответить

Вернуться в «Вопросы по API»