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

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

Анализ проблемы и распространенных ошибок

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

Рассмотрим характерные ошибки, из-за которых строки не добавляются в табличную часть или возникает исключение «Объект недоступен для изменения»:

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

Решение 1. Передача контекста объекта (ЭтотОбъект) во вспомогательную форму

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

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


Для Каждого Стр Из СписокЗаказов Цикл
    Заказ = Стр.Значение;
    
    // СсылкаНаОбъект содержит переданный контекст ЭтотОбъект документа
    НоваяСтрока = СсылкаНаОбъект.ЗаказыПокупателей.Добавить();
    НоваяСтрока.ЗаказПокупателя = Заказ;
    НоваяСтрока.НеВычислятьКоличествоИМассу = ЗначениеЗаполнено(НоваяСтрока.ЗаказПокупателя.цсКомплексныйЗаказ);
    НоваяСтрока.СобиратьОтдельно = НоваяСтрока.ЗаказПокупателя.Контрагент.СобиратьОтдельно;
    НоваяСтрока.ДобавленБезРезерва = Истина;
КонецЦикла;

ЭтаФорма.Закрыть();

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

Решение 2. Использование штатного механизма выборки и оповещения

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

Проанализируем порядок действий для реализации этого варианта:

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

Рассмотрим пример кода в модуле формы документа:


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

Особенности работы с интерфейсом

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

Признак модифицированности: Если заполнение табличной части выполняется программно из другого контекста, платформа может не установить флаг изменения формы автоматически. В результате пользователь может закрыть документ без предложения сохранить данные. Чтобы избежать потери введенных строк, явным образом задавайте свойство ЭтаФорма.Модифицированность = Истина;.

Обновление табличного поля: В редких случаях после добавления строк через объект отображение в элементы формы может не обновиться мгновенно. Для принудительного обновления вызовите метод Обновить() у соответствующего элемента формы ЭлементыФормы.ТабличнаяЧастьЗаказы.Обновить().

← На главную