Как программно пересчитать строки табличной части документа в 1С 7.7 при вводе на основании?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

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

Выясняем причину: почему формулы колонок «зависают»?

Для начала проанализируем внутреннее устройство платформы 1С 7.7. Когда мы открываем форму документа, визуальные элементы табличной части связываются с реквизитами табличной части объекта. Каждая колонка в свойствах диалога имеет специальное поле — «Формула». В этом поле разработчики обычно указывают имя процедуры или функции (например, РассчитатьСтроку() или глПересчетТабличнойЧасти(Контекст)), которая должна выполняться при изменении значения в данной колонке.

Однако эта формула отрабатывает исключительно при интерактивном событии (когда пользователь физически изменяет значение в ячейке на форме или нажимает Enter). Если же документ заполняется программно в модуле документа или при вводе на основании, то данные записываются напрямую в реквизиты объекта, минуя интерактивный слой формы. В результате при открытии формы мы видим заполненные базовые реквизиты, но расчетные поля, зависящие от формул колонок, остаются пустыми до первого «клика» пользователя.

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

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

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

Шаг 1. Определяем имя процедуры пересчета.
Откроем конфигурацию в Конфигураторе, найдем нужный нам документ (например, «Корректировочный счет-фактура») и откроем его форму. Дважды кликнем на колонку табличной части, которая должна вызывать пересчет (например, «Цена до изменения» или «Сумма»). Перейдем на вкладку «Дополнительно» и посмотрим, какая функция или процедура указана в поле «Формула». Предположим, там написано: ПересчитатьСуммуСтроки().

Шаг 2. Добавляем программный обход в процедуру ПриОткрытии().
Перейдем в модуль формы документа. В предопределенной процедуре ПриОткрытии() мы напишем код, который будет выполняться только для новых, еще не записанных документов (чтобы не перезаписывать данные в уже проведенных документах). Мы обойдем все строки табличной части и принудительно вызовем нужную нам процедуру для каждой строки.

Рассмотрим пример кода:


Процедура ПриОткрытии()
    // Проверяем, что документ новый и открыт для редактирования
    Если Выбран() = 0 Тогда 
        // Активизируем выборку строк табличной части
        ВыбратьСтроки();
        Пока ПолучитьСтроку() = 1 Цикл
            // Вызываем процедуру, которая привязана к формуле ячейки
            ПересчитатьСуммуСтроки(); 
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

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

Решение 2. Использование динамических формул через функцию Шаблон()

Что делать, если имя процедуры пересчета может меняться или если формулы колонок прописаны непосредственно в свойствах метаданных и их неудобно вызывать напрямую? В 1С 7.7 существует мощный инструмент динамического выполнения выражений — функция Шаблон(). Мы можем прочитать формулу колонки программно и выполнить ее в контексте каждой строки.

Рассмотрим, как реализовать такой универсальный обход:


Процедура ПриОткрытии()
    Если Выбран() = 0 Тогда
        ВыбратьСтроки();
        Пока ПолучитьСтроку() = 1 Цикл
            // Выполняем выражение, зашитое в формулу ячейки
            // Например, если формула в конфигураторе называется "Рассчитать()":
            Шаблон("[Рассчитать()]");
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Использование метода Шаблон() позволяет динамически вычислять любые строковые выражения и вызывать процедуры модуля формы, сохраняя гибкость разработки.

Решение 3. Имитация интерактивного фокуса (Native-метод платформы)

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

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

  1. АктивизироватьСтроку(<НомерСтроки>) — переводит курсор на строку с указанным индексом.
  2. Активизировать(<ИмяРеквизита>, <Режим>) — активирует конкретный элемент управления или колонку. Передача значения 1 во втором параметре принудительно переводит ячейку в режим интерактивного редактирования (эмулируя двойной клик мыши).

Проанализируем пример кода, который выполняет эту задачу:


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

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

Решение 4. Использование внешней компоненты FormEx

Если ваша конфигурация использует популярную внешнюю компоненту FormEx (которая расширяет возможности работы с интерфейсом в 1С 7.7), вы можете решить задачу без лишнего визуального мерцания и напрямую обратиться к недокументированным возможностям контекста формы.

С помощью FormEx можно перехватывать события нажатия клавиш, использовать объект РасширениеФормы и программно эмулировать ввод данных:

Однако для большинства типовых задач автоматизации в «1С:Бухгалтерии 7.7» вполне достаточно первого решения. Оно является наиболее стабильным, не требует регистрации сторонних DLL-библиотек в операционной системе и работает «из коробки» на любых конфигурациях.

Мы рекомендуем всегда отдавать предпочтение первому методу как наиболее чистому с точки зрения архитектуры разработки в среде 1С:Предприятие 7.7. Это избавит пользователей от необходимости выполнять рутинные действия вручную и обеспечит 100% точность математических расчетов в ваших документах.

← На главную