При разработке на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью вызова внешних обработок (например, для печати документов) с передачей им данных текущей формы. Стандартным подходом является передача переменной Контекст в качестве параметра. Однако в определенных ситуациях вызов метода Контекст.ВыбратьСтроки() внутри обработки не дает результата — строки просто не выбираются, хотя в открытом документе они визуально присутствуют. Рассмотрим подробнее, почему это происходит и как правильно организовать работу с данными формы.
Проанализируем ситуацию, описанную автором: при вызове внешней обработки печати из документа "Путевой лист" данные табличной части не считываются, если пользователь не переключился на закладку, где эта табличная часть расположена. Как только закладка активируется — данные становятся доступны. Это наводит на мысли о «ленивой инициализации» визуальных компонентов в 1С 7.7, но корень проблемы часто лежит глубже — в программной логике самой конфигурации.
В 1С 7.7 существует принципиальное различие между двумя способами получения данных:
ТекущийДокумент() вернет старые данные из файла БД (DBF или SQL), а не те, что видны на экране.Контекст напрямую зависит от того, как спроектирована форма и какие манипуляции с ней проводились в модуле.Выясним причину странного поведения на примере конфигураций «Мисофт» или аналогичных сложных решений. В этих системах часто используется механизм виртуальных табличных частей. Рассмотрим, как это работает программно:
Для удобства пользователя или из-за ограничений платформы (невозможность гибко скрывать колонки ТЧ в 7.7) разработчики создают основную табличную часть документа, но на форме ее скрывают. Вместо нее на разных закладках размещают объекты типа ТаблицаЗначений (ТЗ). В процедуре ПриОткрытии() выполняется следующий алгоритм:
УдалитьСтроки()), чтобы не дублировать данные или не вызывать конфликтов.В такой ситуации вызов Контекст.ВыбратьСтроки() закономерно возвращает пустоту, так как физически в основной табличной части документа в этот момент строк нет — они «живут» в таблицах значений на форме.
Самый простой способ получить данные — обратиться напрямую к объекту в базе данных. Это исключает зависимость от состояния экранных закладок и программных манипуляций в форме.
Рассмотрим пример кода вызова обработки:
// В модуле формы документа
ОткрытьФорму("Отчет", ТекущийДокумент(), КаталогИБ() + "ExtForms\PrintWaybill.ert");
Важный нюанс: Этот метод подходит только для документов, которые уже записаны. Если ваша задача — разрешить печать нового, еще не сохраненного документа, этот способ не сработает, так как ТекущийДокумент().Выбран() вернет 0.
Если нам необходимо получить данные именно из формы (включая несохраненные изменения), проанализируем использование метода ВыгрузитьТабличнуюЧасть(). Этот метод работает с контекстом более надежно, чем прямой перебор строк через ВыбратьСтроки(), так как он обращается к внутреннему буферу данных объекта, связанного с формой.
Посмотрим на пример реализации внутри внешней обработки:
Процедура ПриОткрытии()
Конт = Форма.Параметр;
// Создаем временную таблицу значений
ТЗ = СоздатьОбъект("ТаблицаЗначений");
// Пробуем выгрузить данные из переданного контекста
Попытка
Конт.ВыгрузитьТабличнуюЧасть(ТЗ);
Если ТЗ.КоличествоСтрок() = 0 Тогда
Предупреждение("Табличная часть пуста или данные еще не инициализированы!");
КонецЕсли;
Исключение
Сообщить("Не удалось получить данные напрямую из контекста: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если мы имеем дело с конфигурацией, где данные перенесены в ТаблицуЗначений на форме (как в случае с «Мисофт»), мы можем обратиться к этой таблице через контекст напрямую. Для этого нужно знать идентификатор этой таблицы на форме (например, ТЗ_Маршрут или ТЗ_Топливо).
Рассмотрим, как это реализовать:
// Внутри внешней обработки
Конт = Форма.Параметр;
// Обращаемся к конкретной ТЗ, которая определена в форме документа
Попытка
Конт.ТЗ_Данные.ВыбратьСтроки();
Пока Конт.ТЗ_Данные.ПолучитьСтроку() = 1 Цикл
// Обработка данных
КонецЦикла;
Исключение
// Если ТЗ с таким именем нет в контексте
Сообщить("Объект ТЗ_Данные не найден в форме документа.");
КонецПопытки;
Проанализируем поведение платформы, упомянутое автором. В 1С 7.7 существует механизм визуального обновления. При активации закладки, на которой расположены элементы управления, связанные с данными, система принудительно синхронизирует состояние экранных объектов и внутренних буферов. Если в коде формы прописано заполнение ТЗ при переходе на слой (закладку), то до момента этого перехода ТЗ будет пустой.
Чтобы избежать подобных проблем, рекомендуем придерживаться следующих правил:
ТекущийДокумент() и требуйте от пользователя сохранения перед печатью. Это гарантирует соответствие печатной формы и данных в БД.ВыгрузитьТабличнуюЧасть() в контексте формы.ПриОткрытии() и ПриВыбореЗакладки(). Если данные перемещаются в ТЗ, используйте доступ к этим ТЗ через Контекст.ИмяВашейТЗ.Таким образом, проблема «неработающего контекста» чаще всего оказывается следствием архитектурных решений конкретной конфигурации, направленных на обход визуальных ограничений старой платформы 1С 7.7. Понимание того, где именно хранятся данные в текущий момент времени (в ТЧ объекта или в ТЗ формы), позволяет быстро устранить подобные ошибки.