Как программно добавить колонку с производителем в табличную часть «Товары» документа «Счет на оплату»?

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача кастомизации типовых форм без изменения основной конфигурации. Одним из наиболее востребованных сценариев является вывод дополнительных данных в табличные части документов. Например, в документе Счет на оплату пользователям часто необходимо видеть Завод-изготовитель или Производителя непосредственно в списке товаров, чтобы не заходить в каждую карточку номенклатуры отдельно.

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

Анализ исходной задачи и типичных ошибок

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


&НаСервере
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    ЭлементРодитель = ЭтаФорма.Элементы.ТоварыГруппаНоменклатура;
    НовыйЭлемент = Элементы.Вставить("Завод изготовитель", Тип("ПолеФормы"), Элементы.Товары, ЭлементРодитель); 
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "Объект.Товары.Номенклатура.Производитель";
КонецПроцедуры

В этом фрагменте кода скрыто несколько критических моментов, которые мы должны исправить:

  1. Имя элемента: В 1С имена элементов формы не могут содержать пробелы. Использование строки "Завод изготовитель" приведет к ошибке выполнения. Мы должны использовать формат "ТоварыЗаводИзготовитель" или аналогичный.
  2. Путь к данным: Платформа позволяет обращаться к реквизитам через точку (например, Номенклатура.Производитель), но только если этот реквизит доступен для отображения в контексте серверной формы.
  3. Режим редактирования: Если мы просто добавим поле, система может позволить пользователю пытаться его редактировать, что в случае со ссылочными данными через точку может вызвать путаницу или ошибки доступа. Нам нужно установить режим ТолькоПросмотр.

Пошаговая реализация решения в расширении

Рассмотрим правильный алгоритм действий для добавления колонки в форму документа Счет на оплату покупателю (например, в БП 3.0).

Шаг 1. Создание расширения и захват формы. Сначала создадим новое расширение или используем существующее. Нам необходимо добавить в него форму документа СчетНаОплатуПокупателю. Важно убедиться, что в расширение также проброшен справочник Номенклатура и его реквизит Производитель (если он используется в ПутьКДанным).

Шаг 2. Написание программного кода. Используем обработчик &После("ПриСозданииНаСервере"). Выясним причину, по которой стоит использовать именно Вставить, а не Добавить. Метод Вставить позволяет нам четко позиционировать колонку относительно существующих элементов, например, сразу после номенклатуры.

Посмотрим на пример корректного кода:


&НаСервере
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)

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

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

Разбор ключевых свойств и методов

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

Однако стоит учитывать следующие моменты:

Альтернативный вариант: Использование «ИзменитьРеквизиты»

Иногда возникают ситуации, когда прямой путь через точку не срабатывает (например, если реквизит является дополнительным сведениям или требует сложной логики получения). В этом случае мы можем применить метод ЭтаФорма.ИзменитьРеквизиты().

Рассмотрим этот метод по шагам:

  1. Создаем массив новых реквизитов РеквизитФормы.
  2. Добавляем реквизит в коллекцию Объект.Товары.
  3. Вызываем ИзменитьРеквизиты().
  4. Создаем элемент формы (колонку) и привязываем её к новому реквизиту.
  5. Заполняем данные в обработчике ПриЧтенииНаСервере или ПриИзменении номенклатуры.

Однако для простой задачи отображения стандартного поля номенклатуры, первый способ (через ПутьКДанным с точкой) является наиболее оптимальным и быстрым в реализации.

Заключение

Мы выяснили, что программное добавление колонки в расширении — это надежный способ унифицировать интерфейс для всех пользователей. Мы исключили человеческий фактор (необходимость ручной настройки) и обеспечили корректное отображение данных из связанных справочников. Помните, что использование ТолькоПросмотр = Истина является обязательным для полей, которые носят справочный характер, чтобы избежать попыток изменения данных объекта через его расширение.

← На главную