При разработке сложных интерфейсов на платформе 1С:Предприятие 7.7 с использованием внешних компонент (например, FormEx) разработчики часто сталкиваются с нестабильным поведением программы. Типичная ситуация: на форме внешней обработки расположена ТаблицаЗначений и переключатель режимов отображения. При переключении структуры колонок (например, с простого плоского списка на сложную многоуровневую сетку с объединением колонок) первое переключение проходит успешно, однако при повторных нажатиях 1С 7.7 аварийно завершает работу с системной ошибкой памяти.
Разберем подробнее, почему возникает этот сбой, и рассмотрим проверенные архитектурные решения, которые позволяют обойти ограничение платформы и обеспечить стабильную работу формы.
Штатный элемент управления ТаблицаЗначений на форме 1С 7.7 представляет собой стандартный системный грид Win32/MFC. Внешние компоненты перехватывают его оконную процедуру (выполняют subclassing), чтобы реализовать расширенные визуальные возможности: вывод нескольких колонок в одной ячейке, многострочные шапки и произвольную раскраску.
Аварийное завершение программы чаще всего происходит по следующим причинам:
Очистить(), УдалитьКолонку() и НоваяКолонка() структуры сетки перестраиваются быстрее, чем внешняя компонента успевает обновить свой внутренний кэш и пересчитать координаты ячеек.Самый надежный и простой подход в рамках штатных механизмов 1С 7.7 — отказаться от постоянной динамической перестройки колонок одного и того же элемента управления. Разместим на форме две отдельные таблицы значений и будем управлять их доступностью и видимостью в зависимости от положения переключателя.
Посмотрим на алгоритм реализации этого метода:
ТЗ_Простая и ТЗ_Сложная, наложив их друг на друга или управляя координатами.Рассмотрим пример кода обработчика переключения режимов:
Процедура ПриПереключенииРежима()
Если ВыбРежим = 1 Тогда
Форма.ТЗ_Простая.Видимость(1);
Форма.ТЗ_Сложная.Видимость(0);
Форма.ТЗ_Простая.Доступность(1);
Форма.ТЗ_Сложная.Доступность(0);
Иначе
Форма.ТЗ_Простая.Видимость(0);
Форма.ТЗ_Сложная.Видимость(1);
Форма.ТЗ_Простая.Доступность(0);
Форма.ТЗ_Сложная.Доступность(1);
КонецЕсли;
КонецПроцедуры
Такой подход полностью исключает постоянное разрушение и пересоздание Win32-хэндлов контрола во время работы пользователя.
Если требуется использовать именно один элемент управления на форме, создадим единый набор колонок, объединяющий оба режима, а ненужные колонки будем скрывать, устанавливая им нулевую ширину с помощью метода УстановитьПараметрыКолонки().
Разберем по шагам, как настроить данный механизм:
Активизировать("ВыбРежим")).0, для отображаемых — требуемое положительное значение.
Процедура ОбновитьОтображениеКолонок()
// Снимаем фокус с таблицы во избежание сбоя перерисовки
Активизировать("ВыбРежим");
Если ВыбРежим = 1 Тогда
// Режим простой таблицы
ТЗ.УстановитьПараметрыКолонки("КолонкаСложная1",,,, 0);
ТЗ.УстановитьПараметрыКолонки("КолонкаСложная2",,,, 0);
ТЗ.УстановитьПараметрыКолонки("КолонкаПростая",,,, 25);
Иначе
// Режим расширенной таблицы
ТЗ.УстановитьПараметрыКолонки("КолонкаПростая",,,, 0);
ТЗ.УстановитьПараметрыКолонки("КолонкаСложная1",,,, 15);
ТЗ.УстановитьПараметрыКолонки("КолонкаСложная2",,,, 15);
КонецЕсли;
КонецПроцедуры
Если перерисовка интерфейса и вызовы методов внешней компоненты продолжают вызывать сбой, необходимо развязать выполнение пользовательского клика и процедуру обновления таблицы. Для этого выносят тяжелую логику перерисовки из основного обработчика нажатия кнопки/переключателя в отложенный вызов через ОбработкаВнешнегоСобытия или механизм таймера.
Это гарантирует, что 1С 7.7 полностью завершит обработку оконного сообщения для клика мыши, перерисует элемент управления и только после этого приступит к изменению структуры данных и визуальных свойств сетки.
Штатная ТаблицаЗначений в платформе 7.7 изначально не предназначалась для сложного позиционирования ячеек друг под другом и многоуровневых шапок. Если интерфейс требует богатого визуального отображения, оптимальным решением является использование компоненты 1С++ и элемента ТабличноеПоле.
Преимущества перехода на Табличное поле:
ТаблицаЗначений или класс поставщика данных, а само визуальное поле только отображает их без постоянного риска разрушения дескрипторов при манипуляциях со структурой.