Как в запросе через COM-соединение получить вид документа (регистратора)

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При работе с внешними базами данных 1С через COM-соединение программисты часто сталкиваются с проблемой идентификации типа объекта. Когда мы выбираем поле Регистратор в запросе к регистру накопления, на сторону вызывающей программы возвращается COM-объект (ссылка). Напрямую понять, какой это вид документа (например, "Приходная накладная" или "Реализация"), бывает затруднительно, так как привычные методы типизации ведут себя иначе в контексте внешнего соединения.

В этой статье мы разберем несколько эффективных способов получения вида документа, проанализируем их преимущества и выясним, какой метод лучше использовать в зависимости от ваших задач.

Способ 1. Использование функций ПРЕДСТАВЛЕНИЕ и ТИПЗНАЧЕНИЯ в тексте запроса

Самый простой и быстрый способ получить строковое название типа документа прямо в результате запроса — это комбинация функций ПРЕДСТАВЛЕНИЕ и ТИПЗНАЧЕНИЯ. Рассмотрим этот метод подробнее, так как он позволяет минимизировать количество обращений к серверу базы данных через медленный COM-интерфейс.

Проанализируем пример кода запроса:


ЗапросКом = COMСоединение.NewObject("Запрос");
ЗапросКом.Текст = 
"ВЫБРАТЬ
|   ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(Регистратор)) КАК ВидДокумента,
|   СуммаВзаиморасчетов КАК Сумма,
|   Регистратор КАК СсылкаНаДокумент
|ИЗ
|   РегистрНакопления.ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты";

Выборка = ЗапросКом.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    // В поле ВидДокумента будет содержаться строка, например, "Приходная накладная"
    Сообщить(Выборка.ВидДокумента);
КонецЦикла;

Преимущество: Мы получаем готовую строку с названием типа документа сразу в выборке. Это избавляет нас от необходимости вызывать дополнительные методы для каждой строки результата.

Важный нюанс: Функция ПРЕДСТАВЛЕНИЕ возвращает локализованное имя типа (синоним), которое зависит от языка платформы. Если вам нужно программное имя (как в конфигураторе), этот метод может не подойти.

Способ 2. Использование оператора ССЫЛКА для жесткой типизации

Если нам заранее известен список документов, которые могут выступать регистраторами, мы можем использовать конструкцию ВЫБОР с оператором ССЫЛКА. Это позволит нам вернуть строго заданные строковые идентификаторы.

Разберем, как это реализовать на практике:


ТекстЗапроса = 
"ВЫБРАТЬ
|   ВЫБОР
|       КОГДА Регистратор ССЫЛКА Документ.ПриходнаяНакладная ТОГДА ""ПриходнаяНакладная""
|       КОГДА Регистратор ССЫЛКА Документ.РасходнаяНакладная ТОГДА ""РасходнаяНакладная""
|       ИНАЧЕ ""НеизвестныйДокумент""
|   КОНЕЦ КАК ИмяТипа,
|   Регистратор
|ИЗ
|   РегистрНакопления.ПартииТоваровНаСкладах";

Этот метод считается наиболее надежным, если вы пишете сложную логику обработки на стороне вызывающей системы, так как вы сами контролируете возвращаемые значения ИмяТипа.

Способ 3. Обращение к метаданным при обходе выборки

Иногда бывает удобнее получить вид документа уже после выполнения запроса, непосредственно при обработке строк. Поскольку Регистратор через COM возвращается как полноценный объект ссылки, мы можем обратиться к его свойствам и методам, предоставляемым платформой 1С.

Выясним, как получить программное имя документа через объектную модель:


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    // Обращаемся к COM-объекту ссылки
    ДокументСсылка = Выборка.Регистратор;
    
    // Получаем имя метаданных через прокси-объект
    Попытка
        ИмяВида = ДокументСсылка.Метаданные().Имя;
        Сообщить("Тип документа: " + ИмяВида);
    Исключение
        // Обработка случая, если регистратор не определен (NULL)
    КонецПопытки;
КонецЦикла;

Важно: Обращение к Метаданные() через COM является довольно "дорогой" операцией с точки зрения производительности, так как требует дополнительного сетевого вызова для каждого объекта. Если в вашей выборке тысячи строк, этот метод значительно замедлит работу обработки.

Способ 4. Получение XML-типа (наиболее универсальный вариант)

Для тех случаев, когда нужно получить уникальный строковый идентификатор типа, не зависящий от языка интерфейса (например, DocumentRef.Invoice), рекомендуется использовать глобальный метод XMLТипЗнч через COM-соединение. Этот метод возвращает объект ТипXML, который содержит имя типа в формате XML.

Посмотрим на пример реализации:


// Предположим, у нас есть ссылка, полученная через запрос
СсылкаCOM = Выборка.Регистратор;

// Вызываем метод XMLТипЗнч у основного объекта COM-соединения
ТипXML = COMСоединение.XMLТипЗнч(СсылкаCOM);

// Получаем строковый идентификатор
СтрокаТипа = ТипXML.ИмяТипа; // Вернет что-то вроде "DocumentRef.ПриходнаяНакладная"

Этот подход позволяет однозначно идентифицировать вид объекта, даже если в разных базах у документов разные синонимы.

Рекомендации по оптимизации и обработке ошибок

При работе с регистрами через COM-соединение следует помнить о нескольких критических моментах:

  1. Проверка на NULL: В регистрах накопления поле Регистратор может содержать NULL (например, при определенных типах итогов или битых записях). Всегда делайте проверку Регистратор ЕСТЬ НЕ NULL в запросе или используйте Попытка...Исключение в коде.
  2. Минимизация обращений: Старайтесь получать все необходимые данные (включая вид документа) внутри текста запроса (Способ 1 или 2). Каждый вызов метода через точку от COM-объекта (Объект.Метаданные().Имя) — это отдельный сетевой пакет между вашим приложением и сервером 1С.
  3. Использование метода String(): В некоторых случаях, чтобы получить строковое представление объекта, находящегося на стороне COM-сервера, можно использовать метод COMСоединение.String(Объект). Это аналог функции Строка(), выполняемый на стороне сервера.

Подводя итог, можно сказать: если вам нужно просто вывести название документа пользователю — используйте ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(Регистратор)) в запросе. Если же вам нужно реализовать сложную логику в зависимости от вида документа — используйте оператор ССЫЛКА или метод XMLТипЗнч.

← На главную