Почему тормозит раскраска списков FormEx в 1С 7.7 на MS SQL Server 2008 и как это исправить?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При миграции баз данных 1С:Предприятие 7.7 с файлового режима (DBF) или устаревшего MS SQL Server 2000 на более современные версии (MS SQL Server 2008 / 2008 R2) многие разработчики сталкиваются с существенным падением производительности интерфейса. В частности, при навигации и скроллинге динамических списков (журналов документов, справочников), где применяется внешняя компонента FormEx для раскраски ячеек и строк, возникают сильнейшие задержки.

Причины возникновения задержек при перерисовке списков

Разберем детально, почему одна и та же конфигурация на базе 1С 7.7 (например, «Торговля и Склад 9.2») с одной и той же версией FormEx работает быстро в файловом режиме (DBF), но начинает зависать на MS SQL Server 2008.

Проанализируем основные факторы, влияющие на скорость отрисовки:

  1. Особенности работы SQL-курсоров платформы 1С 7.7: Платформа 1С 7.7 использует стандартные API-курсоры для навигации по записям журналов и справочников. В файловой базе считывание данных происходит из локального дискового кэша с минимальной задержкой. В случае с MS SQL Server любое считывание значений реквизитов из ячеек строки при отрисовке вызывает обращения через курсоры. На MS SQL Server 2008 поведение оптимизатора запросов и обработка курсоров отличаются, из-за чего накладные расходы на каждый запрос возрастают.
  2. Старый механизм раскраски FormEx (версия 2.0.5.0): По умолчанию старые версии компоненты при скроллинге или перерисовке таблицы заставляют платформу многократно вычислять выражения из формул текстовых колонок для каждой видимой ячейки. В сочетании с обращением к SQL-серверу это приводит к сотням лишних вызовов функций 1С на один кадр прокрутки.
  3. Избыточные вызовы обновления (двойная отрисовка): В ранних версиях FormEx при смене фокусировки или навигации по строкам происходило повторное обновление всей видимой области таблицы, из-за чего формулы раскраски вызывались дважды на одну ячейку.
  4. Включенное отслеживание мыши: В некоторых случаях в настройках компоненты активировано отслеживание движения курсора мыши над таблицей, что провоцирует непрерывный вызов процедур перерисовки.

Способ 1. Переход на «План раскраски» в FormEx

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

Рассмотрим пошагово, как перевести форму списка на план раскраски:

  1. Обновим внешнюю компоненту FormEx до более свежей сборки (не ниже 2.0.5.85, рекомендуется 2.0.5.117 или новее).
  2. В модуле формы заменим устаревший метод включения раскраски:
    
    // Старый вариант вызова:
    // Сервис.ВключитьРаскраскуТаблиц();
    
    // Новый вариант вызова (включение плана раскраски):
    Сервис.ИспользоватьПланРаскраски(1);
    
  3. В табличную часть формы списка (в редакторе диалога) добавим новую текстовую колонку со служебным заголовком FormEx_ПланРаскраски.
  4. В формуле этой колонки укажем функцию, возвращающую готовый шаблон макросов раскраски для всей строки.

Способ 2. Отключение принудительного обновления и отслеживания мыши

Выясним, какие методы компоненты FormEx позволяют снизить избыточную нагрузку при перемещении курсора по таблице.

Во-первых, вызовем метод отключения повторного фонового обновления таблицы при смещении курсора:

Сервис.ОтключитьОбновлениеПриРаскраске(1);

Во-вторых, проверим настройки компоненты на предмет отслеживания мыши. Если отслеживание положения мыши над ячейками не требуется, его следует отключить, чтобы предотвратить лишние фоновые события перерисовки.

Способ 3. Оптимизация кода функций раскраски и кэширование

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

Недопустимо внутри функции раскраски:

  1. Получать периодические реквизиты или обращаться через несколько точек к справочникам и документам (например, ТекущийДокумент.Контрагент.ОсновнойДоговор.Цены).
  2. Создавать объекты базы данных (например, СоздатьОбъект("Справочник.Контрагенты")) и выполнять выборки.
  3. Вызывать сложные функции с запросами к базе данных.

Посмотрим на пример организации кэширования цветов:


// Предварительно при открытии формы или при смене фильтра
// формируем СписокЗначений или ТаблицуЗначений с готовыми цветам строк.

Функция ПолучитьЦветСтроки()
    // Минимальная логика: только считывание из заранее подготовленного кэша
    ИдентификаторСтроки = ТекущийДокумент;
    ЦветСтроки = мКэшЦветов.Получить(ИдентификаторСтроки);
    Если ЦветСтроки = ПолучитьПустоеЗначение() Тогда
        Возврат "";
    КонецЕсли;
    Возврат ЦветСтроки;
КонецФункции

Способ 4. Переход на «Табличное поле» из внешней компоненты 1С++

Если штатными журналами и справочниками 1С 7.7 в SQL-режиме добиться высокой скорости не удается, альтернативным решением является переход на элемент управления Табличное поле из библиотеки 1С++.

При таком подходе выборка данных выполняется через прямые SQL-запросы к базе данных, а раскраска строк и ячеек осуществляется встроенными средствами самого «Табличного поля» без накладных расходов на вызов функций 1С платформы при отрисовке.

Способ 5. Обслуживание MS SQL Server 2008

При переходе на MS SQL Server 2008 необходимо также провести регламентные процедуры на стороне СУБД:

  1. Выполнить обновление статистики базы данных командой sp_updatestats.
  2. Выполнить полную реиндексацию таблиц базы данных.
  3. Проверить сетевые задержки (ping/latency) между клиентскими (терминальными) сессиями и MS SQL Server.
← На главную