В практике разработки на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с загадочным поведением интерфейса: функции, размещенные в элементах типа «Текст» на форме документа или справочника, вызываются гораздо чаще, чем того ожидает логика программы. Особенно ярко это проявляется в табличных частях, где простое перемещение курсора или открытие формы вызывает лавинообразное появление диагностических сообщений или замедление работы системы. Рассмотрим подробнее, почему это происходит и как локализовать проблему.
Разберем классический пример. На форму документа в табличную часть добавлен элемент «Текст», в поле «Формула» которого прописан вызов функции:
Функция Проверка()
Сообщить("Вызов функции...");
Возврат "";
КонецФункции
При открытии такого документа в окне сообщений мы можем увидеть три одинаковых записи, а при клике на строку — еще две. Если же мы принудительно вызовем обновление формы через Форма.Обновить(), количество вызовов может увеличиться в геометрической прогрессии. Проанализируем, почему стандартные средства отладки (стек вызовов) в этом случае оказываются малоинформативными: система просто показывает вызов функции без указания на инициировавшее его событие кода, так как инициатором выступает сам графический движок 1С 7.7.
Выясним основную техническую причину. В 1С 7.7 вычисление формул в текстовых элементах на форме происходит каждый раз, когда системе требуется перерисовать (перекрасить) соответствующий участок окна. Этот процесс тесно связан с механизмом обработки сообщений Windows, таких как WM_PAINT.
Ситуация осложняется при использовании внешних компонент, в частности FormEx. Эта компонента широко применяется для расширения возможностей интерфейса (раскраска строк, работа с фокусом, программное управление элементами). Проанализируем механизм ее работы:
Сервис.ВключитьРаскраскуТаблиц(), компонента вмешивается в процесс отрисовки каждой ячейки, чтобы применить заданные пользователем цвета.Важный вывод: Если вы используете FormEx и сталкиваетесь с «двоением» вызовов, попробуйте временно отключить раскраску таблиц или выгрузить компоненту для проверки. Если проблема исчезла — причина в избыточных событиях перерисовки.
Посмотрим на ситуацию со стороны системного окружения. Часто бывает, что на локальном компьютере программиста все работает корректно, а в терминальной сессии (RDP) проявляются лишние срабатывания. Это связано с оптимизацией передачи графики в протоколе удаленного рабочего стола:
Разберем по шагам, как минимизировать негативные последствия многократных вызовов.
Это золотое правило разработки в 1С 7.7. Функции, указанные в элементах «Текст» на форме, не должны:
Сообщить().Любое из этих действий само по себе может вызвать изменение фокуса или обновление интерфейса, что приведет к рекурсивному вызову этой же функции.
Для реквизитов формы типа «Текст» (если они связаны с данными) существует метод, позволяющий ограничить частоту вычислений. Рассмотрим пример использования этого метода в процедуре ПриОткрытии():
Процедура ПриОткрытии()
// Устанавливаем идентификатор для текстового поля на форме, например "ТекстСтатус"
Форма.ТекстСтатус.ВыполнятьФормулуТолькоПриИзменении(1);
КонецПроцедуры
Хотя этот метод официально предназначен для редактируемых реквизитов, в ряде случаев он помогает снизить нагрузку и на чисто информационные поля.
Если функция должна выполнять какие-то вычисления, проанализируем, как можно предотвратить их повторение. Мы можем использовать проверку на изменение текущей строки или времени последнего вызова. Рассмотрим пример кода с защитой от лишних вычислений:
Переменная ПоследнийНомерСтроки;
Функция РасчетВТЧ()
// Если мы все еще на той же строке, не выполняем тяжелые расчеты
Если НомерСтроки = ПоследнийНомерСтроки Тогда
Возврат ""; // Или возвращаем ранее рассчитанное значение
КонецЕсли;
// Выполняем логику
ПоследнийНомерСтроки = НомерСтроки;
// Ваш код здесь...
Возврат Результат;
КонецФункции
Если вы используете FormEx для визуального оформления, правильнее будет перенести логику из формул текстовых полей в специализированные процедуры компоненты, такие как ПослеОтрисовкиЯчейки(). Эти события работают более предсказуемо и позволяют управлять оформлением таблицы без лишних вызовов встроенного движка 1С.
Таким образом, мы выяснили, что повторное срабатывание функций — это не баг кода, а особенность архитектуры 1С 7.7, усиленная внешними факторами. Использование «чистых» функций без побочных эффектов и контроль за состоянием внешних компонент отрисовки позволяют полностью устранить данную проблему.