Почему падает 1С 7.7 при динамическом изменении колонок в таблице значений и как это исправить?

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

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

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

Причины аварийного завершения (Access Violation)

Штатный элемент управления ТаблицаЗначений на форме 1С 7.7 представляет собой стандартный системный грид Win32/MFC. Внешние компоненты перехватывают его оконную процедуру (выполняют subclassing), чтобы реализовать расширенные визуальные возможности: вывод нескольких колонок в одной ячейке, многострочные шапки и произвольную раскраску.

Аварийное завершение программы чаще всего происходит по следующим причинам:

  1. Разрушение внутренних дескрипторов заголовков: при динамическом удалении и создании колонок методами Очистить(), УдалитьКолонку() и НоваяКолонка() структуры сетки перестраиваются быстрее, чем внешняя компонента успевает обновить свой внутренний кэш и пересчитать координаты ячеек.
  2. Активный фокус ввода: если пользователь кликает по переключателю в момент, когда фокус или каретка выбора строки находились внутри таблицы значений, перерисовка несуществующих координат приводит к чтению по недействительному адресу памяти.
  3. Наложение правил позиционирования: повторный вызов методов объединения и смещения колонок поверх уже модифицированной сетки без предварительного сброса координат нарушает внутреннюю логику отрисовки.
  4. Конфликт в обработчиках событий: попытка модификации визуального элемента непосредственно в теле события нажатия на управляющий элемент формы часто пересекается со стандартным циклом перерисовки интерфейса 1С.

Способ 1. Использование нескольких таблиц значений с управлением видимостью

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

Посмотрим на алгоритм реализации этого метода:

  1. Размещаем на форме две таблицы: ТЗ_Простая и ТЗ_Сложная, наложив их друг на друга или управляя координатами.
  2. Инициализируем структуру колонок для каждой таблицы один раз при открытии формы.
  3. В обработчике переключателя переключаем свойство видимости через методы формы.

Рассмотрим пример кода обработчика переключения режимов:


Процедура ПриПереключенииРежима()
    Если ВыбРежим = 1 Тогда
        Форма.ТЗ_Простая.Видимость(1);
        Форма.ТЗ_Сложная.Видимость(0);
        Форма.ТЗ_Простая.Доступность(1);
        Форма.ТЗ_Сложная.Доступность(0);
    Иначе
        Форма.ТЗ_Простая.Видимость(0);
        Форма.ТЗ_Сложная.Видимость(1);
        Форма.ТЗ_Простая.Доступность(0);
        Форма.ТЗ_Сложная.Доступность(1);
    КонецЕсли;
КонецПроцедуры

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

Способ 2. Статическая структура колонок и управление шириной

Если требуется использовать именно один элемент управления на форме, создадим единый набор колонок, объединяющий оба режима, а ненужные колонки будем скрывать, устанавливая им нулевую ширину с помощью метода УстановитьПараметрыКолонки().

Разберем по шагам, как настроить данный механизм:

  1. При инициализации формы программно или визуально создаем сразу все необходимые колонки.
  2. Перед изменением конфигурации колонок обязательно снимаем фокус с таблицы значений, активизируя другой элемент формы (например, сам переключатель через команду Активизировать("ВыбРежим")).
  3. Вместо удаления колонок перебираем их и задаем ширину: для скрытых — 0, для отображаемых — требуемое положительное значение.

Процедура ОбновитьОтображениеКолонок()
    // Снимаем фокус с таблицы во избежание сбоя перерисовки
    Активизировать("ВыбРежим");
    
    Если ВыбРежим = 1 Тогда
        // Режим простой таблицы
        ТЗ.УстановитьПараметрыКолонки("КолонкаСложная1",,,, 0);
        ТЗ.УстановитьПараметрыКолонки("КолонкаСложная2",,,, 0);
        ТЗ.УстановитьПараметрыКолонки("КолонкаПростая",,,, 25);
    Иначе
        // Режим расширенной таблицы
        ТЗ.УстановитьПараметрыКолонки("КолонкаПростая",,,, 0);
        ТЗ.УстановитьПараметрыКолонки("КолонкаСложная1",,,, 15);
        ТЗ.УстановитьПараметрыКолонки("КолонкаСложная2",,,, 15);
    КонецЕсли;
КонецПроцедуры

Способ 3. Вынос обработки событий в отдельный поток

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

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

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

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

Преимущества перехода на Табличное поле:

  1. Нативная поддержка сложных макетов: компонент изначально спроектирован для объединения ячеек, построения иерархических шапок и динамической смены колонок.
  2. Разделение данных и представления: источником данных (провайдером) выступает объект ТаблицаЗначений или класс поставщика данных, а само визуальное поле только отображает их без постоянного риска разрушения дескрипторов при манипуляциях со структурой.
  3. Стабильность: исключаются конфликты субклассинга стандартных элементов 1С, что предотвращает вылеты программы.
← На главную