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