Как предотвратить перекрытие Таблицы Значений табличной частью документа в 1С 7.7

Программист 1С v7.7
← На главную

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

Почему возникает проблема Z-порядка?

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

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

Метод 1: Разделение интерфейса и использование двух Таблиц Значений

Наиболее надежным и визуально чистым решением, которое подтвердил автор темы, является полный отказ от отображения стандартной табличной части в той области, где должна находиться ТаблицаЗначений. Рассмотрим этот алгоритм по шагам:

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

Такой подход полностью исключает конфликт Z-порядка, так как две ТаблицыЗначений на форме 1С 7.7 взаимодействуют друг с другом гораздо корректнее, чем ТЗ и системная многострочная часть.

Метод 2: Программное обновление через «Текст с формулой»

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

Для реализации динамического обновления выполним следующие действия:

  1. Разместим на форме элемент типа «Текст».
  2. В свойствах текста, в поле «Формула», пропишем вызов функции, например: глОбновитьДанныеТЗ().
  3. Сделаем это поле невидимым или размером в 1 пиксель (это не повлияет на исполнение формулы).

Проанализируем пример кода для такой функции:


Переменная ТекущийНомерСтроки;

Функция глОбновитьДанныеТЗ()
    // Проверяем, изменилась ли строка в основной таблице
    Если НомерСтроки <> ТекущийНомерСтроки Тогда
        ТекущийНомерСтроки = НомерСтроки;
        
        // Здесь код обновления нашей Таблицы Значений
        ТЗ_ПодчиненныйСпр.Очистить();
        Спр = СоздатьОбъект("Справочник.Цены");
        Спр.ИспользоватьВладельца(Товар);
        Спр.ВыбратьЭлементы();
        Пока Спр.ПолучитьЭлемент() = 1 Цикл
            ТЗ_ПодчиненныйСпр.НоваяСтрока();
            ТЗ_ПодчиненныйСпр.Наименование = Спр.Наименование;
            ТЗ_ПодчиненныйСпр.Цена = Спр.Цена;
        КонецЦикла;
    КонецЕсли;
    Возврат ""; // Возвращаем пустую строку для отображения в тексте
КонецФункции

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

Метод 3: Использование внешних компонент (FormEx и 1С++)

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

Использование FormEx: Эта компонента позволяет программно управлять координатами объектов. С помощью метода УстановитьПривязку можно жестко зафиксировать положение элементов управления относительно границ формы, что иногда предотвращает графические артефакты при изменении размеров окна.

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

Метод 4: Механизм слоев

В конфигураторе 1С 7.7 существует понятие слоев (меню «Вставить» -> «Слой»). Проанализируем, как это может помочь:

  1. Мы можем вынести вспомогательную ТаблицуЗначений на отдельный слой (например, «СлойИнфо»).
  2. Основную табличную часть оставить на слое «Основной».
  3. Программно управлять видимостью слоев с помощью команды ИспользоватьСлой("Основной,СлойИнфо", 1).

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

Дополнительные рекомендации по верстке формы

Выясним еще одну тонкость: проблема одного пикселя. В 1С 7.7 объекты не должны касаться друг друга «стык в стык». Если граница ТаблицыЗначений совпадает с границей многострочной части хотя бы по одной координате, система может считать их пересекающимися. Попробуем отодвинуть элементы друг от друга на расстояние 2-3 пикселя. Часто этого небольшого зазора достаточно, чтобы графический движок перестал перекрывать один объект другим при клике.

Также полезно рассмотреть настройку формы «Изменять размер». Если у формы убрать возможность максимизации и изменения размеров пользователем (фиксированная форма), поведение Z-порядка становится более стабильным, так как исключаются динамические пересчеты координат, при которых чаще всего и возникают ошибки наложения слоев.

Подводя итог, наиболее эффективным решением для современных конфигураций на базе 7.7 является либо использование внешних компонент для отрисовки таблиц, либо создание интерфейса-«дублера» на базе нескольких объектов ТаблицаЗначений, что обеспечивает предсказуемость поведения формы и удобство работы пользователя.

← На главную