Почему не работают методы табличной части при передаче контекста формы в 1С 7.7

Программист 1С v7.7 Бухгалтерский учет
← На главную

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

Суть проблемы: Контекст против Объекта

Проанализируем ситуацию, описанную автором: при вызове внешней обработки печати из документа "Путевой лист" данные табличной части не считываются, если пользователь не переключился на закладку, где эта табличная часть расположена. Как только закладка активируется — данные становятся доступны. Это наводит на мысли о «ленивой инициализации» визуальных компонентов в 1С 7.7, но корень проблемы часто лежит глубже — в программной логике самой конфигурации.

В 1С 7.7 существует принципиальное различие между двумя способами получения данных:

  1. ТекущийДокумент(): возвращает ссылку на объект, записанный в базе данных. Если пользователь внес изменения в форму, но не нажал кнопку "Записать" или "ОК", метод ТекущийДокумент() вернет старые данные из файла БД (DBF или SQL), а не те, что видны на экране.
  2. Контекст: передает текущее состояние экранной формы. Это позволяет печатать данные «на лету», даже если документ еще не сохранен. Однако Контекст напрямую зависит от того, как спроектирована форма и какие манипуляции с ней проводились в модуле.

Разбор причины: Особенности конфигураций на платформе 7.7

Выясним причину странного поведения на примере конфигураций «Мисофт» или аналогичных сложных решений. В этих системах часто используется механизм виртуальных табличных частей. Рассмотрим, как это работает программно:

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

  1. Данные из реальной табличной части выгружаются во временные таблицы значений.
  2. Строки основной табличной части документа удаляются (командой УдалитьСтроки()), чтобы не дублировать данные или не вызывать конфликтов.
  3. Пользователь работает с ТЗ на форме.
  4. Перед записью данные из ТЗ собираются обратно в основную табличную часть.

В такой ситуации вызов Контекст.ВыбратьСтроки() закономерно возвращает пустоту, так как физически в основной табличной части документа в этот момент строк нет — они «живут» в таблицах значений на форме.

Решение 1: Использование метода ТекущийДокумент()

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

Рассмотрим пример кода вызова обработки:


// В модуле формы документа
ОткрытьФорму("Отчет", ТекущийДокумент(), КаталогИБ() + "ExtForms\PrintWaybill.ert");

Важный нюанс: Этот метод подходит только для документов, которые уже записаны. Если ваша задача — разрешить печать нового, еще не сохраненного документа, этот способ не сработает, так как ТекущийДокумент().Выбран() вернет 0.

Решение 2: Принудительная выгрузка табличной части из контекста

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

Посмотрим на пример реализации внутри внешней обработки:


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

Решение 3: Доступ к внутренним Таблицам Значений формы

Если мы имеем дело с конфигурацией, где данные перенесены в ТаблицуЗначений на форме (как в случае с «Мисофт»), мы можем обратиться к этой таблице через контекст напрямую. Для этого нужно знать идентификатор этой таблицы на форме (например, ТЗ_Маршрут или ТЗ_Топливо).

Рассмотрим, как это реализовать:


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

Почему «прыжки» по закладкам помогали?

Проанализируем поведение платформы, упомянутое автором. В 1С 7.7 существует механизм визуального обновления. При активации закладки, на которой расположены элементы управления, связанные с данными, система принудительно синхронизирует состояние экранных объектов и внутренних буферов. Если в коде формы прописано заполнение ТЗ при переходе на слой (закладку), то до момента этого перехода ТЗ будет пустой.

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

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

← На главную