Как автоматически заполнить данные в табличной части документа при выборе элемента справочника?

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

В процессе разработки в среде 1С:Предприятие 8 часто возникает задача: при выборе пользователем определенного товара (или любого другого объекта) в табличной части документа, необходимо автоматически подставить связанные с ним данные — например, цену, количество, единицу измерения или артикул. Рассмотрим, как правильно реализовать этот механизм, разберем типичные ошибки новичков и изучим наиболее эффективные методы программирования для решения этой задачи.

Анализ исходной задачи и выявление ошибок

Представим ситуацию: у нас есть справочник Товары с реквизитом Количество. В документе создана табличная часть ИнформацияОТоваре, где есть колонка Модель (ссылка на справочник) и колонка Количество (число). Нам нужно, чтобы при выборе модели в строке таблицы числовое значение из справочника автоматически «перекочевало» в документ.

Разберем типичные ошибки в логике, которые часто допускают начинающие разработчики:

  1. Обращение к реквизитам формы как к реквизитам объекта: Использование конструкции Объект.Наименование внутри процедуры обработки события строки таблицы некорректно, так как программа не понимает, из какой именно строки нужно взять данные.
  2. Ошибки в синтаксисе запроса: Назначение зарезервированных слов (например, Число) в качестве псевдонимов таблиц (КАК Число) приводит к аварийному завершению работы кода.
  3. Отсутствие параметров в запросе: Выборка данных без условия ГДЕ вернет первый попавшийся элемент из базы, а не тот, который выбрал пользователь.

Вариант 1. Простое получение данных через точку (Серверный вызов)

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

Рассмотрим реализацию на стороне клиента и сервера:


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

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

Важный нюанс: Обращение через точку (ТекущиеДанные.Модель.Количество) на сервере заставляет систему прочитать весь объект справочника из базы данных. Если в справочнике 50 реквизитов, 1С прочитает их все, хотя нам нужно только одно число. Для одной строки это незаметно, но при массовой работе это может замедлить систему.

Вариант 2. Оптимизированный запрос (Без контекста)

Для повышения производительности, особенно в высоконагруженных системах, рекомендуется использовать механизм &НаСервереБезКонтекста. Это позволяет не передавать на сервер всю форму документа целиком, а отправить только ссылку на модель и получить в ответ конкретное значение.

Разберем этот метод по шагам:


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

&НаСервереБезКонтекста
Функция ПолучитьКоличествоТовара(СсылкаНаМодель)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Товары.Количество КАК Количество
        |ИЗ
        |   Справочник.Товары КАК Товары
        |ГДЕ
        |   Товары.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаМодель);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Количество;
    КонецЕсли;
    
    Возврат 0;
КонецФункции

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

Вариант 3. Массовое заполнение реквизитов через Структуру

Часто на практике требуется заполнить сразу 5-10 полей (Цена, Артикул, Вес, Ставка НДС). Чтобы не бегать на сервер за каждым полем отдельно, выясним, как вернуть несколько значений сразу, используя объект Структура.

Посмотрим на пример реализации:


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

&НаСервереБезКонтекста
Функция ПолучитьДанныеМодели(Ссылка)
    Результат = Новый Структура("Количество, Цена, Артикул", 0, 0, "");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Товары.Количество,
        |   Товары.Цена,
        |   Товары.Артикул
        |ИЗ
        |   Справочник.Товары КАК Товары
        |ГДЕ
        |   Товары.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        ЗаполнитьЗначенияСвойств(Результат, Выборка);
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

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

Рекомендации и лучшие практики

Подведем итог и проанализируем основные правила работы с заполнением табличных частей:

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

← На главную