Как обратиться к табличной части документа из модуля менеджера в 1С?

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

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

В чем принципиальное отличие модуля менеджера от модуля объекта?

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

  1. Модуль объекта: описывает поведение конкретного экземпляра документа, загруженного в оперативную память. В нем доступны предопределенные свойства и методы этого экземпляра, включая реквизиты, движения и табличные части (например, коллекция Товары). Контекст модуля знает, с какими именно данными он работает в текущий момент.
  2. Модуль менеджера: относится ко всему классу (типу метаданных) документов в целом, то есть к объекту ДокументМенеджер.<ИмяДокумента>. В нем нет контекста конкретного документа. Ключевое слово ЭтотОбъект здесь указывает на сам менеджер, а не на документ с его полями. Модуль менеджера выступает аналогом специализированного общего модуля, куда выносят алгоритмы печати, специализированные выборки, создание связанных сущностей и универсальные сервисные функции.

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

Способ 1. Передача ссылки или объекта через параметр функции

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


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

Теперь посмотрим, как вызвать этот метод из контекста формы документа. На клиенте мы не можем напрямую вызывать модуль менеджера, поэтому вызов выполняется через серверную процедуру или функцию формы:


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

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

Способ 2. Чтение сохраненных данных через запрос по ссылке

Если документ уже записан в базу данных, то передавать в модуль менеджера весь объект не требуется. Стандарты разработки фирмы «1С» рекомендуют передавать ссылку на документ (ДокументСсылка.<ИмяДокумента>) и считывать данные табличной части с помощью запроса. Разберем этот вариант подробнее:


Процедура ОбработатьТабличнуюЧастьПоСсылке(СсылкаНаДокумент) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ТЧ.Номенклатура КАК Номенклатура,
        |	ТЧ.Количество КАК Количество,
        |	ТЧ.Сумма КАК Сумма
        |ИЗ
        |	Документ.РеализацияТоваровУслуг.Товары КАК ТЧ
        |ГДЕ
        |	ТЧ.Ссылка = &Ссылка";
        
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Обрабатываем полученные строки
    КонецЦикла;
    
КонецПроцедуры

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

Способ 3. Программное изменение табличной части в модуле менеджера

Если перед нами стоит задача не просто прочитать строки, но и добавить новую запись или скорректировать данные существующего документа из метода менеджера, нам потребуется получить объект документа из ссылки через метод ПолучитьОбъект():


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

Важно помнить: обращение к табличной части через саму ссылку (например, СсылкаНаДокумент.Товары) возвращает коллекцию, открытую только для чтения. Изменить, добавить или удалить строки напрямую через ссылку платформа не позволяет.

Способ 4. Работа с несохраненными данными формы

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

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


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

В самом модуле менеджера процедура примет ТаблицаЗначений обычным параметром и выполнит все необходимые алгоритмы обхода строк.

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

← На главную