При разработке конфигураций на платформе 1С:Предприятие 8.3 часто возникает задача автоматизации ввода данных. Рассмотрим классическую ситуацию: в документе «Билет» при выборе категории билета нам необходимо автоматически подставлять конкретное значение в поле «Экскурсовод» (например, «Без экскурсовода»), если выбранный тип билета относится к категории «Входной». Проанализируем, как реализовать это правильно, эффективно и с соблюдением стандартов разработки.
Для начала разберем структуру объектов, с которыми мы работаем. У нас есть справочник тит_КатегорияБилета, в котором хранится реквизит ТипБилета (ссылка на перечисление тит_ТипБилета). В документе тит_Билет имеется табличная часть Состав. Наша цель — написать обработчик события ПриИзменении для колонки КатегорияБилета, который будет анализировать тип и заполнять соседнюю колонку Экскурсовод.
Важно помнить о разделении контекста выполнения кода на клиенте и сервере. Платформа 1С в управляемом приложении требует минимизации серверных вызовов для обеспечения высокой скорости работы интерфейса.
В исходном коде часто встречается попытка найти элемент справочника по коду, например: Справочники.тит_Экскурсоводы.НайтиПоКоду("000000026"). Разберем, почему это плохая практика:
Решение: Создадим в справочнике тит_Экскурсоводы предопределенный элемент с именем БезЭкскурсовода. Теперь мы сможем обращаться к нему напрямую в коде, и это будет работать надежно в любой копии базы данных.
Рассмотрим, как правильно прописать условие в модуле формы документа. Нам нужно отловить момент изменения категории билета. Проанализируем ситуацию: когда пользователь выбирает значение, нам нужно «заглянуть» внутрь этого значения и узнать его тип.
Обратите внимание: обращение через точку от ссылки на клиенте (например, ТекДанные.КатегорияБилета.ТипБилета) вызывает неявный серверный вызов. Чтобы этого избежать, мы можем использовать предопределенные значения перечислений прямо на клиенте.
Разберем пример кода для формы документа:
&НаКлиенте
Процедура СоставКатегорияБилетаПриИзменении(Элемент)
// Получаем текущую строку табличной части
ТекДанные = Элементы.Состав.ТекущиеДанные;
// 1. Обязательно проверяем, заполнена ли категория билета
Если Не ЗначениеЗаполнено(ТекДанные.КатегорияБилета) Тогда
Возврат;
КонецЕсли;
// 2. Вызываем серверную функцию для получения свойств категории
// Это правильнее, чем обращаться через точку на клиенте
СтруктураСвойств = ПолучитьСвойстваКатегории(ТекДанные.КатегорияБилета);
// 3. Проверяем условие. Используем ПредопределенноеЗначение для сравнения с перечислением
Если СтруктураСвойств.ТипБилета = ПредопределенноеЗначение("Перечисление.тит_ТипБилета.ВходнойБилет") Тогда
// Устанавливаем значение предопределенного элемента
ТекДанные.Экскурсовод = ПредопределенноеЗначение("Справочник.тит_Экскурсоводы.БезЭкскурсовода");
КонецЕсли;
// Не забываем про пересчет цены, если это требуется логикой
// ТекДанные.Цена = СтруктураСвойств.Цена;
КонецПроцедуры
Поскольку на клиенте нам доступны не все реквизиты ссылки, нам понадобится небольшая серверная функция. Выясним причину: серверная функция &НаСервереБезКонтекста работает максимально быстро, так как не передает на сервер состояние всей формы.
&НаСервереБезКонтекста
Функция ПолучитьСвойстваКатегории(СсылкаКатегория)
Результат = Новый Структура;
Результат.Вставить("ТипБилета", СсылкаКатегория.ТипБилета);
Результат.Вставить("Цена", СсылкаКатегория.Цена);
Возврат Результат;
КонецФункции
Посмотрим на ситуацию шире. Иногда недостаточно просто заполнить поле автоматически — нужно еще и запретить пользователю выбирать неправильного экскурсовода вручную. Для этого в платформе 1С предусмотрен механизм Связи параметров выбора.
Рассмотрим по шагам, как это настроить в конфигураторе без написания кода:
тит_Билет и перейдите к табличной части Состав.Экскурсовод.КатегорияБилета.ТипБилета.Это позволит сделать интерфейс более «дружелюбным» и исключит вероятность человеческой ошибки еще на этапе подбора данных.
Проанализируем важный аспект: что если билеты создаются не вручную через форму, а загружаются из внешней системы или мобильного приложения? В этом случае код в модуле формы не сработает.
Чтобы логика работала всегда, её стоит продублировать (или вынести) в Модуль объекта документа, в обработчик ПередЗаписью или ОбработкаПроверкиЗаполнения. Рассмотрим пример для модуля объекта:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Для Каждого СтрокаСостава Из Состав Цикл
// Проверяем тип билета через обращение к реквизитам ссылки
Если СтрокаСостава.КатегорияБилета.ТипБилета = Перечисления.тит_ТипБилета.ВходнойБилет Тогда
// Если тип входной, принудительно ставим Без экскурсовода
СтрокаСостава.Экскурсовод = Справочники.тит_Экскурсоводы.БезЭкскурсовода;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Мы разобрали комплексный подход к решению задачи. Основные выводы, которые помогут вам писать качественный код в 1С:
ПредопределенноеЗначение() для работы на стороне клиента.ЗначениеЗаполнено() для предотвращения ошибок при пустых ссылках.Такой подход делает систему надежной, быстрой и легкой в сопровождении. Помните, что аккуратность в прописании условий сегодня экономит часы отладки завтра!