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

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

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

Анализ проблемы: почему возникает ошибка «Поле объекта не обнаружено»

Рассмотрим ситуацию, когда разработчик пытается обратиться к реквизиту табличной части напрямую через объект документа. Часто в коде можно встретить следующую конструкцию:


Объект.Товары.ОтвественныйЗакупкиВКП = Объект.Товары.Производитель.ОтветственныйЗакупки;

При выполнении такого кода система выдаст ошибку «Поле объекта не обнаружено». Давайте выясним причину. Объект.Товары — это не одна строка, а вся коллекция строк табличной части. У коллекции (таблицы) нет реквизита ОтвественныйЗакупкиВКП, он есть только у конкретной строки этой таблицы. Чтобы программно изменить данные, нам необходимо сначала получить доступ к конкретному индексу или текущей строке, с которой работает пользователь.

Решение 1: Обработка события «ПриИзменении» на клиенте

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

Во-первых, нам нужно убедиться, что реквизит ОтвественныйЗакупкиВКП создан именно в метаданных документа (в конфигураторе), в составе табличной части Товары. Если добавить колонку только на форму, данные не будут сохраняться в базе.

Во-вторых, создадим обработчик события для поля Производитель. Проанализируем пример кода, который решает задачу:


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

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

В данном примере мы используем свойство Элементы.Товары.ТекущиеДанные. Это наиболее простой способ получить доступ к данным строки, на которой сфокусирован курсор пользователя в момент изменения значения. Обратите внимание на проверку Неопределено — это важный момент для предотвращения критических ошибок, если строка по какой-то причине не была определена.

Решение 2: Оптимизация производительности (Серверный вызов)

Хотя обращение «через точку» (как в примере выше) работает, оно не всегда оптимально. В 1С обращение к реквизиту ссылки на клиенте приводит к тому, что система скрыто обращается к серверу и считывает весь объект справочника со всеми его реквизитами, табличными частями и правами доступа. Если справочник «Производители» очень тяжелый, это может замедлить работу интерфейса.

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


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

&НаСервереБезКонтекста
Функция ПолучитьОтветственногоЗакупки(СсылкаПроизводитель)
    
    // Используем метод «ЗначениеРеквизитаОбъекта» из БСП (если подключена) 
    // или простой запрос для быстродействия
    Возврат СсылкаПроизводитель.ОтветственныйЗакупки;
    
КонецФункции

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

Различие между данными и элементами формы

Проанализируем еще одну частую ошибку: путаницу между программным объектом Объект и коллекцией Элементы. Объект — это данные, которые будут записаны в базу. Элементы — это визуальное отображение этих данных на экране.

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

Особенности реализации бизнес-логики

В обсуждении на форуме упоминалось, что иногда в табличной части нужно проставить «временного» сотрудника, даже если в справочнике «Производитель» поле пустое. Наш код в событии ПриИзменении идеально подходит под это требование:

  1. При выборе производителя подтягивается ответственный «по умолчанию».
  2. После этого пользователь может вручную изменить ответственного прямо в строке табличной части.
  3. Программа не будет перезаписывать вручную введенного сотрудника до тех пор, пока пользователь снова не изменит значение в поле «Производитель».

Такой подход обеспечивает гибкость: мы автоматизируем рутинный ввод, но оставляем за пользователем право последнего слова.

Проверка прав доступа

При реализации программного заполнения важно помнить о правах доступа (RLS). Если у пользователя нет прав на просмотр реквизита ОтветственныйЗакупки в справочнике, то при попытке его прочитать код может вернуть Неопределено. Проанализируйте настройки прав доступа в вашей конфигурации, если данные вдруг перестали заполняться у рядовых сотрудников, в то время как у администратора все работает корректно.

Подводя итог, можно сказать, что правильное обращение к данным табличной части в 1С 8.3 требует понимания контекста выполнения кода (Клиент/Сервер) и правильной работы с текущей строкой данных. Используя методы, описанные выше, вы создадите надежный и быстрый интерфейс для работы ваших пользователей.

← На главную