При работе с внешними базами данных 1С через COM-соединение программисты часто сталкиваются с проблемой идентификации типа объекта. Когда мы выбираем поле Регистратор в запросе к регистру накопления, на сторону вызывающей программы возвращается COM-объект (ссылка). Напрямую понять, какой это вид документа (например, "Приходная накладная" или "Реализация"), бывает затруднительно, так как привычные методы типизации ведут себя иначе в контексте внешнего соединения.
В этой статье мы разберем несколько эффективных способов получения вида документа, проанализируем их преимущества и выясним, какой метод лучше использовать в зависимости от ваших задач.
Самый простой и быстрый способ получить строковое название типа документа прямо в результате запроса — это комбинация функций ПРЕДСТАВЛЕНИЕ и ТИПЗНАЧЕНИЯ. Рассмотрим этот метод подробнее, так как он позволяет минимизировать количество обращений к серверу базы данных через медленный COM-интерфейс.
Проанализируем пример кода запроса:
ЗапросКом = COMСоединение.NewObject("Запрос");
ЗапросКом.Текст =
"ВЫБРАТЬ
| ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(Регистратор)) КАК ВидДокумента,
| СуммаВзаиморасчетов КАК Сумма,
| Регистратор КАК СсылкаНаДокумент
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты";
Выборка = ЗапросКом.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// В поле ВидДокумента будет содержаться строка, например, "Приходная накладная"
Сообщить(Выборка.ВидДокумента);
КонецЦикла;
Преимущество: Мы получаем готовую строку с названием типа документа сразу в выборке. Это избавляет нас от необходимости вызывать дополнительные методы для каждой строки результата.
Важный нюанс: Функция ПРЕДСТАВЛЕНИЕ возвращает локализованное имя типа (синоним), которое зависит от языка платформы. Если вам нужно программное имя (как в конфигураторе), этот метод может не подойти.
Если нам заранее известен список документов, которые могут выступать регистраторами, мы можем использовать конструкцию ВЫБОР с оператором ССЫЛКА. Это позволит нам вернуть строго заданные строковые идентификаторы.
Разберем, как это реализовать на практике:
ТекстЗапроса =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА Регистратор ССЫЛКА Документ.ПриходнаяНакладная ТОГДА ""ПриходнаяНакладная""
| КОГДА Регистратор ССЫЛКА Документ.РасходнаяНакладная ТОГДА ""РасходнаяНакладная""
| ИНАЧЕ ""НеизвестныйДокумент""
| КОНЕЦ КАК ИмяТипа,
| Регистратор
|ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах";
Этот метод считается наиболее надежным, если вы пишете сложную логику обработки на стороне вызывающей системы, так как вы сами контролируете возвращаемые значения ИмяТипа.
Иногда бывает удобнее получить вид документа уже после выполнения запроса, непосредственно при обработке строк. Поскольку Регистратор через COM возвращается как полноценный объект ссылки, мы можем обратиться к его свойствам и методам, предоставляемым платформой 1С.
Выясним, как получить программное имя документа через объектную модель:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Обращаемся к COM-объекту ссылки
ДокументСсылка = Выборка.Регистратор;
// Получаем имя метаданных через прокси-объект
Попытка
ИмяВида = ДокументСсылка.Метаданные().Имя;
Сообщить("Тип документа: " + ИмяВида);
Исключение
// Обработка случая, если регистратор не определен (NULL)
КонецПопытки;
КонецЦикла;
Важно: Обращение к Метаданные() через COM является довольно "дорогой" операцией с точки зрения производительности, так как требует дополнительного сетевого вызова для каждого объекта. Если в вашей выборке тысячи строк, этот метод значительно замедлит работу обработки.
Для тех случаев, когда нужно получить уникальный строковый идентификатор типа, не зависящий от языка интерфейса (например, DocumentRef.Invoice), рекомендуется использовать глобальный метод XMLТипЗнч через COM-соединение. Этот метод возвращает объект ТипXML, который содержит имя типа в формате XML.
Посмотрим на пример реализации:
// Предположим, у нас есть ссылка, полученная через запрос
СсылкаCOM = Выборка.Регистратор;
// Вызываем метод XMLТипЗнч у основного объекта COM-соединения
ТипXML = COMСоединение.XMLТипЗнч(СсылкаCOM);
// Получаем строковый идентификатор
СтрокаТипа = ТипXML.ИмяТипа; // Вернет что-то вроде "DocumentRef.ПриходнаяНакладная"
Этот подход позволяет однозначно идентифицировать вид объекта, даже если в разных базах у документов разные синонимы.
При работе с регистрами через COM-соединение следует помнить о нескольких критических моментах:
Регистратор может содержать NULL (например, при определенных типах итогов или битых записях). Всегда делайте проверку Регистратор ЕСТЬ НЕ NULL в запросе или используйте Попытка...Исключение в коде.Объект.Метаданные().Имя) — это отдельный сетевой пакет между вашим приложением и сервером 1С.COMСоединение.String(Объект). Это аналог функции Строка(), выполняемый на стороне сервера.Подводя итог, можно сказать: если вам нужно просто вывести название документа пользователю — используйте ПРЕДСТАВЛЕНИЕ(ТИПЗНАЧЕНИЯ(Регистратор)) в запросе. Если же вам нужно реализовать сложную логику в зависимости от вида документа — используйте оператор ССЫЛКА или метод XMLТипЗнч.