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