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