Как в 1С автоматически заполнить реквизит табличной части при выборе другого значения

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С:Предприятие часто возникает задача автоматизации ввода данных. Типичный сценарий: пользователь выбирает номенклатуру (запчасть) в табличной части документа, и система должна автоматически подтянуть связанные с ней данные, такие как обозначение, артикул, единица измерения или цена. Это не только ускоряет работу, но и минимизирует количество ошибок ручного ввода.

В этой статье мы подробно разберем, как реализовать такой механизм, проанализируем различные подходы в зависимости от типа используемых форм (Обычные или Управляемые) и выясним, почему иногда код выдает ошибки.

Постановка задачи

Представим, что у нас есть справочник Запчасти с реквизитом Обозначение. В документе имеется табличная часть Запчасти, где есть две колонки: Запчасть (ссылка на справочник) и Обозначение (строка или ссылка). Наша цель — сделать так, чтобы при выборе запчасти поле Обозначение заполнялось автоматически.

Вариант 1: Только отображение данных (Управляемые формы)

Если нам не нужно хранить обозначение в базе данных (в самом документе), а достаточно лишь видеть его на форме в момент работы, мы можем воспользоваться механизмом «Путь к данным». Рассмотрим этот способ подробнее.

В Управляемом приложении (платформа 8.3) элементы формы могут обращаться к реквизитам через «точку» от основного объекта. Алгоритм действий следующий:

  1. Откроем форму документа в конфигураторе.
  2. В дереве элементов формы найдем нашу таблицу.
  3. Добавим новую колонку (поле ввода).
  4. В свойстве ПутьКДанным этого поля укажем путь через основную ссылку: Объект.Запчасти.Запчасть.Обозначение.

В этом случае платформа сама, без написания единой строки кода, будет выводить обозначение выбранной запчасти. Важный нюанс: данные в этом поле не сохраняются в табличной части документа. Если в справочнике Запчасти изменится обозначение, оно изменится и во всех старых документах, где эта запчасть была выбрана.

Вариант 2: Программное заполнение и хранение данных

Если бизнес-логика требует, чтобы обозначение «зафиксировалось» в документе на момент его создания (например, для истории, так как обозначение в будущем может измениться), данные необходимо записывать в реквизит табличной части. Для этого мы будем использовать событие ПриИзменении.

Реализация для Управляемых форм (8.3)

Проанализируем ситуацию, когда код пишется в модуле управляемой формы. Нам нужно создать обработчик события для элемента формы, отвечающего за выбор запчасти.

Разберем по шагам правильный алгоритм написания кода:


&НаКлиенте
Процедура ЗапчастиЗапчастьПриИзменении(Элемент)
    
    // Получаем текущую строку табличной части
    ТекущаяСтрока = Элементы.Запчасти.ТекущиеДанные;
    
    Если ТекущаяСтрока <> Неопределено Тогда
        // Вызываем серверную функцию для получения данных, 
        // чтобы избежать неявных серверных вызовов через "точку"
        ТекущаяСтрока.Обозначение = ПолучитьОбозначениеЗапчасти(ТекущаяСтрока.Запчасть);
    КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьОбозначениеЗапчасти(ЗапчастьСсылка)
    
    Если ЗначениеЗаполнено(ЗапчастьСсылка) Тогда
        Возврат ЗапчастьСсылка.Обозначение;
    Иначе
        Возврат "";
    КонецЕсли;
    
КонецФункции

Почему мы используем серверную функцию? В управляемом приложении обращение ТекущаяСтрока.Запчасть.Обозначение на клиенте приведет к скрытому серверному вызову для получения объекта из базы данных. Если таких строк в документе много, это может замедлить работу интерфейса. Вынос получения данных в &НаСервереБезКонтекста — это правило хорошего тона для оптимизации производительности.

Реализация для Обычных форм (8.2)

Если вы работаете в старой конфигурации или используете обычные формы, синтаксис будет отличаться. Здесь мы используем коллекцию ЭлементыФормы.


Процедура ТабличнаяЧастьЗапчастиЗапчастьПриИзменении(Элемент)
    
    // В обычных формах работа идет напрямую с текущими данными элемента формы
    ТекущиеДанные = ЭлементыФормы.Запчасти.ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено Тогда
        // Проверяем, заполнена ли запчасть
        Если ЗначениеЗаполнено(ТекущиеДанные.Запчасть) Тогда
            // Присваиваем значение обозначения
            ТекущиеДанные.Обозначение = ТекущиеДанные.Запчасть.Обозначение;
        Иначе
            ТекущиеДанные.Обозначение = "";
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Разбор типичных ошибок

Рассмотрим ситуацию, описанную в сообщениях форума, где пользователь пытался написать код, но получал ошибки. Проанализируем основные причины неудач:

  1. Перемешивание контекстов: Ошибка Переменная не определена (ЭлементыФормы) в тонком клиенте (8.3) возникает из-за попытки использовать синтаксис обычных форм. В управляемом приложении нужно использовать просто Элементы.
  2. Опечатки: Ошибка Процедура или функция с указанным именем не определена (ЗаначениеЗаполнено) — это классическая опечатка в системном слове ЗначениеЗаполнено.
  3. Неверное обращение к коллекции: Попытка написать Объект.Зап.Запчасть.Наименование.ТекущиеДанные ошибочна, так как ТекущиеДанные — это свойство визуального элемента на форме (табличного поля), а не реквизита данных Объект.
  4. Избыточность запросов: Попытка использовать Новый Запрос для получения одного значения реквизита допустима, но часто избыточна. Запрос оправдан, когда нужно получить данные сразу для множества строк или из нескольких связанных таблиц.

Использование Библиотеки стандартных подсистем (БСП)

В современных конфигурациях (таких как УТ 11, ERP 2.5 или БП 3.0) разработчики стараются не писать прямых обращений к реквизитам через точку. Профессиональным подходом считается использование функций общего модуля БСП. Посмотрим на пример:


&НаКлиенте
Процедура ЗапчастиЗапчастьПриИзменении(Элемент)
    
    ТекущаяСтрока = Элементы.Запчасти.ТекущиеДанные;
    
    Если ТекущаяСтрока <> Неопределено И ЗначениеЗаполнено(ТекущаяСтрока.Запчасть) Тогда
        // Используем БСП для быстрого получения значения реквизита
        СтруктураРеквизитов = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ТекущаяСтрока.Запчасть, "Обозначение, Код, Артикул");
        ТекущаяСтрока.Обозначение = СтруктураРеквизитов.Обозначение;
    КонецЕсли;

КонецПроцедуры

Функция ОбщегоНазначения.ЗначенияРеквизитовОбъекта крайне эффективна, так как она выполняет оптимизированный запрос к базе данных и возвращает структуру со всеми нужными полями за один вызов.

Выводы и рекомендации

Выясним, какой метод лучше выбрать в вашей ситуации:

Таким образом, автоматизация заполнения табличной части — это простая, но ответственная задача, требующая понимания того, как платформа 1С работает с данными и интерфейсом.

← На главную