Как отредактировать табличную часть документа в произвольной форме в 1С:Предприятии 8.3

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

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

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

Постановка задачи и анализ базового решения

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

Базовый вызов произвольной формы из команды основной формы выглядит следующим образом:


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

Однако здесь мы сталкиваемся с несколькими техническими сложностями:

  1. Как передать текущие (еще не записанные в базу) данные табличной части в открываемую форму?
  2. Как вернуть измененные данные обратно в основную форму?
  3. Что делать, если табличная часть на основной форме скрыта (установлена Видимость = Ложь), из-за чего платформа оптимизирует трафик и очищает данные на клиенте?

Давайте пошагово решим эти проблемы с использованием современных стандартов разработки 1С.

Решение проблемы скрытой табличной части: Свойство «Использовать всегда»

Рассмотрим важную платформенную особенность управляемых форм. Если вы скрываете табличную часть на основной форме (снимаете флажок видимости или вообще не выносите её на интерфейс формы), платформа 1С в целях экономии трафика перестает передавать данные этой табличной части с сервера на клиент. В результате в коде на клиенте реквизит Объект.ИмяТабличнойЧасти окажется пустым.

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

  1. В конфигураторе откройте основную форму вашего документа.
  2. В правом верхнем окне перейдите на вкладку «Реквизиты».
  3. Раскройте дерево основного реквизита Объект и найдите вашу табличную часть.
  4. Нажмите правой кнопкой мыши по табличной части, выберите «Свойства».
  5. В палитре свойств найдите флажок «Использовать всегда» (Always Use) и установите его в положение Истина.
  6. Повторите эту операцию для всех колонок (подчиненных реквизитов) вашей табличной части, данные которых вам необходимы на клиенте.

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

Оптимальный способ обмена данными через Временное хранилище

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

Рассмотрим по шагам реализацию этого механизма.

Шаг 1. Подготовка и открытие формы в основном документе

В модуле основной формы документа напишем код, который выгружает табличную часть во временное хранилище, формирует описание оповещения (для асинхронного возврата данных) и открывает форму редактирования:


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

&НаКлиенте
Процедура ОткрытьРедакторТаблицы(Команда)
    // 1. Сохраняем данные во временное хранилище на сервере
    АдресХранилища = ПоместитьТЧВоВременноеХранилище();
    
    // 2. Настраиваем обратный вызов (оповещение) при закрытии формы-редактора
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияРедактора", ЭтотОбъект);
    
    // 3. Передаем адрес хранилища в параметрах открываемой формы
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("АдресДанных", АдресХранилища);
    
    // 4. Открываем произвольную форму
    ОткрытьФорму(
        "Документ.ИмяВашегоДокумента.Форма.ИмяПроизвольнойФормы", 
        ПараметрыФормы, 
        ЭтотОбъект, 
        Истина, // Уникальность окна
        , 
        , 
        Оповещение
    );
КонецПроцедуры

Шаг 2. Разработка произвольной формы редактирования

Создайте новую произвольную форму в вашем документе. Добавьте на нее реквизит с типом ТаблицаЗначений (назовем его ЛокальнаяТаблица) и воссоздайте колонки, аналогичные вашей табличной части. Вынесите эту таблицу на форму.

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


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

&НаСервере
Функция СохранитьДанныеВХранилище()
    // Преобразуем реквизит формы обратно в Таблицу Значений
    ТаблицаДляСохранения = РеквизитФормыВЗначение("ЛокальнаяТаблица", Тип("ТаблицаЗначений"));
    // Перезаписываем данные во временном хранилище
    ПоместитьВоВременноеХранилище(ТаблицаДляСохранения, АдресДанныхФормы);
    Возврат АдресДанныхФормы;
КонецФункции

&НаКлиенте
Процедура ЗаписатьИЗакрыть(Команда)
    // Сохраняем изменения на сервере
    АдресРезультата = СохранитьДанныеВХранилище();
    // Закрываем форму и возвращаем адрес измененных данных в основную форму
    Закрыть(АдресРезультата);
КонецПроцедуры

Шаг 3. Прием измененных данных в основной форме

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


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

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

Архитектурные стандарты БСП (на примере «Реквизитов печати»)

Давайте проанализируем, как аналогичные задачи решаются в типовых конфигурациях ERP, УТ или КА с использованием стандартов Библиотеки стандартных подсистем (БСП). Ярким примером служит заполнение реквизитов печати для накладной ТОРГ-12.

Вместо того чтобы напрямую связывать формы, БСП использует слабосвязанную архитектуру:

  1. Вспомогательные данные (например, ФИО подписантов, доверенности) хранятся в специальном реквизите документа типа ХранилищеЗначения или в скрытой табличной части в виде пар «Ключ-Значение».
  2. Для редактирования вызывается общая или специализированная форма-помощник, которая ничего не знает о контексте конкретного документа. Ей передается простая структура параметров.
  3. Помощник обрабатывает данные локально и при закрытии возвращает структуру измененных полей.
  4. Основная форма принимает эту структуру, раскладывает ее по реквизитам объекта и помечает форму как модифицированную.

Такой подход обеспечивает высокую повторную используемость кода и минимизирует риски блокировок или ошибок сериализации при обновлении конфигурации.

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

← На главную