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

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

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

В этой статье мы подробно разберем, как правильно обращаться к данным таблицы формы, как обойти их в цикле и каким образом передать эту информацию в модуль объекта для дальнейшей обработки.

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

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

Если вы создали таблицу в списке реквизитов формы (правая верхняя панель редактора формы), она имеет тип ДанныеФормыКоллекция. Если же вы перетащили этот реквизит на рабочую область формы, создался элемент управления типа ТаблицаФормы.

Рассмотрим типичную ошибку: попытку обращения к визуальному элементу вместо данных. У ТаблицыФормы (элемента) действительно нет методов для выгрузки всех строк, она «видит» только то, что отображается в данный момент, например, ТекущиеДанные. Чтобы получить доступ ко всей коллекции строк, мы должны обращаться именно к реквизиту формы по его имени.

Доступ к таблице в модуле формы

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

Разберем пример обхода таблицы в цикле в процедуре ПередЗаписьюНаСервере. Это наиболее подходящее место для подготовки данных перед их сохранением в базу данных.


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

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

Важно помнить, что тип ДанныеФормыКоллекция позволяет использовать цикл Для каждого, вопреки заблуждениям о невозможности итерации. Если система «ругается» на отсутствие возможности обхода, значит, вы пытаетесь обратиться к элементу управления на клиенте, а не к данным на сервере.

Преобразование в реальную таблицу значений

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

Посмотрим, как это реализовать с помощью встроенных функций платформы:


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

Использование ДанныеФормыВЗначение — это «золотой стандарт» работы на сервере, когда стандартных методов коллекции формы становится недостаточно.

Передача данных в модуль объекта через ДополнительныеСвойства

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

Для этих целей идеально подходит свойство ДополнительныеСвойства, которое есть у любого прикладного объекта. Проанализируем шаги реализации:

  1. В модуле формы в обработчике ПередЗаписьюНаСервере мы помещаем нашу таблицу в структуру дополнительных свойств объекта.
  2. В модуле объекта в обработчике ПередЗаписью мы извлекаем эти данные и используем их.

Рассмотрим программный код для модуля формы:


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

Теперь посмотрим, как принять эти данные в модуле объекта (например, справочника):


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

Подведем итоги

Для успешной работы с таблицами на форме необходимо придерживаться следующих правил:

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

← На главную