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