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

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

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

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

В чем причина «прыгающего» курсора?

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

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

  1. Вы пытаетесь переместить курсор в таблице значений.
  2. Это действие инициирует перерисовку формы.
  3. Срабатывает формула в текстовом поле, которая вызывает функцию обновления (например, СформИнфорСтроку()).
  4. Внутри этой функции обычно стоит метод УдалитьСтроки(), а затем цикл заполнения новыми данными.
  5. Как только старые строки удаляются и создаются новые, визуальное состояние объекта сбрасывается. Для платформы это «новая» таблица, и она по умолчанию ставит фокус на самую первую строку.

Таким образом, возникает бесконечный цикл: любое движение вызывает обновление, а обновление сбрасывает фокус на начало.

Решение проблемы: введение проверки на изменение контекста

Чтобы разорвать этот цикл, нам необходимо добавить логическую проверку. Программа должна обновлять таблицу значений только в том случае, если в основном списке действительно был выбран другой элемент (изменился контекст). Если же пользователь просто кликает по таблице значений или перемещает в ней курсор, обновление срабатывать не должно.

Рассмотрим, как это реализовать программно. В модуле формы нам понадобится переменная для хранения «предыдущего» состояния.

Разберем по шагам реализацию в коде:

  1. Объявите переменную в начале модуля формы (вне процедур), чтобы она сохраняла свое значение между вызовами функций.
  2. В функции обновления сравните текущий элемент справочника с тем, который был сохранен в этой переменной.
  3. Если элементы совпадают — выходите из функции. Если не совпадают — обновляйте таблицу и запоминайте новый элемент.

Пример исправленного кода функции обновления:


Перем СтарыйЭлемент; // Переменная в разделе объявлений модуля

Функция СформИнфорСтроку()
    // Проверяем, изменился ли текущий элемент в основном списке справочника
    Если ТекущийЭлемент() = СтарыйЭлемент Тогда
        // Если элемент тот же самый, ничего не делаем и выходим
        Возврат "";
    КонецЕсли;

    // Если элемент изменился, запоминаем его и выполняем обновление
    СтарыйЭлемент = ТекущийЭлемент();
    
    // Очищаем таблицу значений
    СписокАналогов.УдалитьСтроки();
    
    // Вызываем процедуру заполнения (код заполнения может быть в отдельной функции)
    ЗаполнитьАналоги();
    
    Возврат "";
КонецФункции

Почему это работает?

Когда вы добавляете условие Если ТекущийЭлемент() = СтарыйЭлемент Тогда, функция обновления перестает выполняться при каждом «чихе» системы. Теперь, когда вы щелкаете мышкой по самой таблице значений или нажимаете клавиши «Вверх»/«Вниз», находясь внутри неё, ТекущийЭлемент() (владелец или текущая запись в справочнике) остается прежним. Проверка не проходит, метод УдалитьСтроки() не вызывается, и курсор остается там, куда его поставил пользователь.

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

Разберем еще несколько нюансов, которые помогут сделать работу с таблицами значений в 1С 7.7 более стабильной:

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

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

← На главную