При разработке внешних печатных форм (ВПФ) часто возникает задача дополнить стандартный макет данными, которых нет в основных реквизитах документа. Одной из самых распространенных задач является вывод контактной информации (телефона, адреса или email) конкретного сотрудника — исполнителя или ответственного. Рассмотрим подробно, почему не получается обратиться к телефону «через точку» и как правильно реализовать эту задачу в конфигурациях на базе БСП (Библиотеки стандартных подсистем), таких как «1С:Бухгалтерия».
Проанализируем типичную ошибку начинающего разработчика. При попытке вызвать ДанныеИсполнителя.НомерТелефона система выдает ошибку: «Поле объекта не обнаружено». Выясним причину: в системе 1С данные о контактной информации (КИ) не хранятся в обычных реквизитах справочника ФизическиеЛица. Они располагаются в подчиненной табличной части КонтактнаяИнформация (в некоторых версиях — во внешнем регистре сведений). Следовательно, обычное обращение к реквизиту объекта здесь не сработает, так как строк в таблице может быть много (рабочий телефон, личный, адрес проживания, адрес прописки и т.д.).
В современных конфигурациях 1С (начиная с редакций 2.0 и 3.0 для большинства типовых решений) предусмотрен специальный общий модуль УправлениеКонтактнойИнформацией. Разберем по шагам, как получить телефон исполнителя с его помощью. Этот метод наиболее надежен, так как он учитывает архитектуру хранения данных в конкретной версии программы.
Для получения строкового представления телефона нам понадобится ссылка на объект (в нашем случае Шапка.Исполнитель) и вид контактной информации. Рассмотрим пример кода, который можно вставить в процедуру печати:
// Определим вид контактной информации, который нам нужен
ВидТелефона = Справочники.ВидыКонтактнойИнформации.ТелефонРабочийФизическиеЛица;
// Получаем представление телефона через стандартную функцию
ТелефонИсполнителя = УправлениеКонтактнойИнформацией.ПредставлениеКонтактнойИнформацииОбъекта(Шапка.Исполнитель, ВидТелефона);
// Выводим в параметр области макета
Если ЗначениеЗаполнено(ТелефонИсполнителя) Тогда
ОбластьПодвал.Параметры.ТелефонИсполнителя = "тел.: " + ТелефонИсполнителя;
Иначе
ОбластьПодвал.Параметры.ТелефонИсполнителя = "";
КонецЕсли;
Обратим внимание на важный нюанс: функция ПредставлениеКонтактнойИнформацииОбъекта возвращает уже готовую отформатированную строку. Если телефон в базе записан как «+7 (999) 000-00-00», вы получите именно это значение.
Если нам необходимо получить данные сразу для большого списка документов (например, при массовой печати), вызов функции в цикле может замедлить работу. В этом случае проанализируем ситуацию и перепишем основной запрос печатной формы, добавив в него соединение с табличной частью контактной информации.
Рассмотрим пример того, как дополнить текст запроса:
"ВЫБРАТЬ
| Акт.Ссылка КАК Ссылка,
| Акт.Исполнитель КАК Исполнитель,
| КИ.Представление КАК ТелефонИсполнителя
|ИЗ
| Документ.АктСверкиВзаиморасчетов КАК Акт
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КИ
| ПО Акт.Исполнитель = КИ.Ссылка
| И КИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонРабочийФизическиеЛица)
|ГДЕ
| Акт.Ссылка В(&МассивДокументов)"
В данном случае мы используем ЛЕВОЕ СОЕДИНЕНИЕ, чтобы даже если у исполнителя не указан телефон, документ все равно попал в выборку. Параметр КИ.Вид критически важен — без него запрос вернет все строки контактной информации (адреса, почту и т.д.), что приведет к дублированию строк в печатной форме.
В конфигурации «Бухгалтерия для Беларуси 2.1» часто используется специализированный вызов ОбщегоНазначенияБПВызовСервера.ДанныеФизЛица. Эта функция возвращает структуру или строку таблицы. Если мы хотим интегрировать получение телефона в этот механизм, нам нужно убедиться, что функция умеет извлекать КИ. Если стандартная функция этого не делает, мы можем дополнить структуру данных вручную.
Посмотрим на пример реализации, когда мы уже имеем структуру ДанныеИсполнителя:
// Получаем основные данные физлица (ФИО, должность)
ДанныеИсполнителя = ОбщегоНазначенияБПВызовСервера.ДанныеФизЛица(Шапка.Организация, Шапка.Исполнитель, Шапка.ДатаАктаСверки);
// Добавляем телефон, используя отдельный запрос или функцию
ВидКИ = Справочники.ВидыКонтактнойИнформации.ТелефонПользователя; // или ТелефонРабочийФизическиеЛица
Телефон = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(Шапка.Исполнитель, ВидКИ);
// Заполняем параметры макета
ОбластьПодвал.Параметры.ФИОИсполнителя = ДанныеИсполнителя.Представление;
ОбластьПодвал.Параметры.ДолжностьИ = ДанныеИсполнителя.Должность;
ОбластьПодвал.Параметры.ТелефонИсполнителя = Телефон;
Одной из главных проблем, озвученных в теме, является невозможность отладки. Выясним, как «поймать» ошибку в ВПФ. Внешние обработки запускаются в отдельном безопасном контексте, и обычные точки останова могут не срабатывать.
Попробуем применить следующий алгоритм для отладки:
Печать вставим строку Остановка = 1/0; или воспользуемся методом ВызватьИсключение "Стоп"; в месте, где нужно проверить значения.Сообщить(ТипЗнч(ДанныеИсполнителя));. Если это Структура, мы можем перебрать ее ключи и увидеть, есть ли там нужный нам номер.Чтобы печатная форма выглядела профессионально, проанализируем несколько советов по работе с макетом MXL:
Параметр. Если вы напишете просто текст, программное присвоение Область.Параметры... не сработает."тел.: " + Телефон используйте условие, чтобы при отсутствии номера в базе в акте сверки не красовалось одинокое «тел.: » без цифр.Лев(), Прав() и Сред().Рассмотрим, как красиво объединить должность и телефон в одну строку:
ДолжностьИТелефон = ?(ЗначениеЗаполнено(ДанныеИсполнителя.Должность), ДанныеИсполнителя.Должность, "");
Если ЗначениеЗаполнено(ТелефонИсполнителя) Тогда
ДолжностьИТелефон = ДолжностьИТелефон + ", тел.: " + ТелефонИсполнителя;
КонецЕсли;
ОбластьПодвал.Параметры.ИсполнительИнфо = ДолжностьИТелефон;
Таким образом, мы разобрали основные методы получения контактной информации. Выбор метода зависит от ваших навыков: использование встроенных функций БСП (модуль УправлениеКонтактнойИнформацией) является самым быстрым и правильным путем, в то время как модификация запроса дает большую производительность при работе с большими объемами данных.