При разработке внешних печатных форм (ВПФ) или отчетов в конфигурации 1С:Бухгалтерия предприятия 3.0 разработчики часто сталкиваются с задачей вывода на печать вида контрагента. Казалось бы, задача тривиальная: достаточно обратиться к реквизиту через точку, например, написать СсылкаНаОбъект.Контрагент.Вид. Однако при попытке выполнить такой код система выдает ошибку: «Поле "Вид" не найдено». В этой статье мы подробно разберем, почему возникает эта ошибка, как на самом деле устроено хранение данных о типе контрагента в базе данных и как правильно написать алгоритм для его определения.
Для начала проанализируем структуру справочника Контрагенты в типовой конфигурации «1С:Бухгалтерия 3.0». На форме карточки контрагента пользователи видят красивое поле выбора, где можно указать:
Однако в самой базе данных (в таблице справочника) реквизита с именем Вид просто не существует. То поле, которое отображается на форме — это так называемый реквизит формы. Он создается динамически в модуле формы при открытии карточки контрагента и заполняется на лету по сложной логике. Соответственно, при попытке получить это значение напрямую из ссылки на объект базы данных платформа 1С выдает закономерный отказ.
Выясним причину, почему простые попытки использовать реквизит ЮридическоеФизическоеЛицо приводят к некорректным результатам. Например, государственные органы и обособленные подразделения при таком подходе начинают определяться как обычные юридические лица.
В базе данных БП 3.0 разделение контрагентов строится на комбинации трех ключевых реквизитов справочника Контрагенты:
ЮридическоеФизическоеЛицо (тип: перечисление ПеречислениеСсылка.ЮридическоеФизическоеЛицо). Имеет всего два значения: ЮридическоеЛицо и ФизическоеЛицо. С точки зрения закона государственные органы и головные организации обособленных подразделений являются юридическими лицами, поэтому этот реквизит у них всегда принимает значение ЮридическоеЛицо.ГосударственныйОрган (тип: Булево). Данный флаг взводится в истину, если контрагент является налоговым органом, пенсионным фондом или другой государственной структурой.ГоловнойКонтрагент (тип: СправочникСсылка.Контрагенты). Если это поле заполнено, это означает, что перед нами не самостоятельное юридическое лицо, а обособленное подразделение филиальной сети.Для того чтобы выделить Индивидуальных предпринимателей (ИП), система чаще всего анализирует длину ИНН (у физических лиц и ИП он состоит из 12 цифр, в то время как у юридических лиц — из 10) или обращается к специализированным реквизитам карточки, таким как ОГРНИП.
Рассмотрим подробнее, как написать эффективный и быстродействующий код для внешней печатной формы. Чтобы избежать множественных обращений к базе данных через точку («open-select» запросы), которые сильно замедляют работу системы, мы получим все необходимые реквизиты одним оптимальным запросом.
Создадим вспомогательную функцию, которую можно разместить в модуле внешней печатной формы. Функция будет принимать ссылку на контрагента и возвращать строковое представление его точного вида.
// Функция определяет точный вид контрагента на основе реквизитов базы данных
Функция ПолучитьТочныйВидКонтрагента(СсылкаНаКонтрагента) Экспорт
Если Не ЗначениеЗаполнено(СсылкаНаКонтрагента) Тогда
Возврат "Не определен";
КонецЕсли;
// Создаем запрос для получения всех ключевых полей за один сеанс обращения к БД
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.ЮридическоеФизическоеЛицо КАК ЮрФизЛицо,
| Контрагенты.ГосударственныйОрган КАК ГосударственныйОрган,
| Контрагенты.ГоловнойКонтрагент КАК ГоловнойКонтрагент,
| Контрагенты.ИНН КАК ИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаКонтрагента);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Порядок проверки условий критически важен!
// 1. Проверяем, является ли контрагент государственным органом
Если Выборка.ГосударственныйОрган = Истина Тогда
Возврат "Государственный орган";
// 2. Проверяем наличие головного контрагента (признак обособленного подразделения)
ИначеЕсли ЗначениеЗаполнено(Выборка.ГоловнойКонтрагент) Тогда
Возврат "Обособленное подразделение";
// 3. Анализируем базовое разделение на Юр. и Физ. лиц
ИначеЕсли Выборка.ЮрФизЛицо = Перечисления.ЮридическоеФизическоеЛицо.ЮридическоеЛицо Тогда
Возврат "Юридическое лицо";
ИначеЕсли Выборка.ЮрФизЛицо = Перечисления.ЮридическоеФизическоеЛицо.ФизическоеЛицо Тогда
// Отделяем Индивидуальных предпринимателей от обычных физических лиц по длине ИНН
СтрокаИНН = СокрЛП(Выборка.ИНН);
Если СтрДлина(СтрокаИНН) = 12 Тогда
Возврат "Индивидуальный предприниматель";
Иначе
Возврат "Физическое лицо";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат "Не определен";
КонецФункции
Разберем по шагам, как применить созданную функцию при формировании печатного макета. Представим сценарий, когда в зависимости от вида контрагента нам необходимо выводить различные текстовые блоки (например, для физлиц — паспортные данные, для юрлиц — КПП и юридический адрес, а для госорганов — только официальное наименование без лишних реквизитов).
В процедуре печати вашего модуля добавьте следующий программный код:
// Пример интеграции в процедуру печати ВПФ
Процедура ЗаполнитьДанныеКонтрагентаВМакете(ОбластьМакета, ДанныеДокумента)
СсылкаНаКонтрагента = ДанныеДокумента.Контрагент;
// Получаем точный вид для условий и вывода на форму
ТочныйВид = ПолучитьТочныйВидКонтрагента(СсылкаНаКонтрагента);
// Пример использования в условных конструкциях
Если ТочныйВид = "Физическое лицо" Или ТочныйВид = "Индивидуальный предприниматель" Тогда
// Заполняем параметры для физических лиц
ОбластьМакета.Параметры.ДокументУдостоверяющийЛичность = ПолучитьПаспортныеДанные(СсылкаНаКонтрагента);
ОбластьМакета.Параметры.НаименованиеДляПечати = СсылкаНаКонтрагента.НаименованиеПолное;
ИначеЕсли ТочныйВид = "Государственный орган" Тогда
// Для госорганов выводим сокращенный набор информации
ОбластьМакета.Параметры.НаименованиеДляПечати = "ГОС. ОРГАН: " + СсылкаНаКонтрагента.Наименование;
Иначе
// Стандартный вывод для юридических лиц и обособленных подразделений
ОбластьМакета.Параметры.КПП = СсылкаНаКонтрагента.КПП;
ОбластьМакета.Параметры.НаименованиеДляПечати = СсылкаНаКонтрагента.НаименованиеПолное;
КонецЕсли;
// Передаем текстовое представление вида контрагента напрямую в параметр макета
ОбластьМакета.Параметры.ВидКонтрагентаПредставление = ТочныйВид;
КонецПроцедуры
Проанализировав вышеописанный код, мы видим, что жесткий порядок проверок в условном операторе Если...ИначеЕсли гарантирует безошибочное определение категории. Если поменять местами проверку на ЮридическоеФизическоеЛицо и проверку на ГосударственныйОрган, то все государственные учреждения ошибочно попадут в категорию «Юридическое лицо», что нарушит бизнес-логику формирования печатного документа.
Использование этого подхода позволит вашей внешней печатной форме работать стабильно, быстро и независимо от будущих обновлений интерфейса конфигурации 1С:Бухгалтерия 3.0, так как логика структуры хранения данных в СУБД остается неизменной.