При разработке на управляемых формах 1С программисты часто сталкиваются со странным, на первый взгляд, поведением таблиц. После каждого программного обновления данных в таблице с помощью метода ЗначениеВРеквизитФормы, значение свойства Элементы.ИмяТаблицы.ТекущаяСтрока не возвращается к нулю, а продолжает расти. Например, если в таблице было 3 строки (с идентификаторами 0, 1, 2), то после перезаполнения новыми тремя строками идентификаторы станут 3, 4 и 5. Разберемся, почему это происходит, является ли это ошибкой платформы и как правильно работать с позиционированием строк.
Для начала проанализируем фундаментальное различие между двумя понятиями, которые часто путают: индекс и идентификатор. Это понимание — ключ к работе с управляемыми формами.
Свойство ТекущаяСтрока элемента формы "Таблица" возвращает именно идентификатор, а не индекс. Именно поэтому значения в отладчике выглядят как 0, 5, 12, 100 и так далее. Платформа гарантирует, что пока форма открыта, идентификаторы не будут повторяться, даже если старые строки были удалены.
Выясним причину "скачков" идентификаторов при вызове ЗначениеВРеквизитФормы. Этот метод работает деструктивно. Рассмотрим пошагово, что делает платформа:
ДанныеФормыКоллекция).ТаблицыЗначений.Таким образом, постоянный рост значений в ТекущаяСтрока — это штатное поведение платформы (фича), а не глюк. Это необходимо для стабильности: если бы идентификаторы переиспользовались, клиентские события, которые еще не успели обработаться, могли бы ошибочно обратиться к новой строке, думая, что это старая.
Если для вашей логики (например, для вывода сообщения пользователю или сложных расчетов) необходим именно порядковый номер строки (индекс), его нужно вычислить. Рассмотрим, как это сделать правильно на стороне сервера.
Для получения индекса нам понадобится метод НайтиПоИдентификатору, который есть у объекта ДанныеФормыКоллекция. Разберем пример кода:
&НаСервере
Процедура ЗаказыПриАктивизацииСтрокиНаСервере()
// 1. Получаем идентификатор текущей строки из элемента формы
ИдентификаторТекущейСтроки = Элементы.Спецификация.ТекущаяСтрока;
// Проверка на пустую строку (если таблица пуста)
Если ИдентификаторТекущейСтроки = Неопределено Тогда
Возврат;
КонецЕсли;
// 2. Ищем строку в данных формы по идентификатору
// Спецификация здесь — это реквизит формы (ДанныеФормыКоллекция)
СтрокаДанных = Спецификация.НайтиПоИдентификатору(ИдентификаторТекущейСтроки);
Если СтрокаДанных <> Неопределено Тогда
// 3. Получаем индекс строки в коллекции
ИндексСтроки = Спецификация.Индекс(СтрокаДанных);
Сообщить("Идентификатор: " + ИдентификаторТекущейСтроки + ", Реальный индекс: " + ИндексСтроки);
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию с точки зрения производительности. Частое использование ЗначениеВРеквизитФормы — это "тяжелая" операция. Она заставляет платформу полностью перерисовывать таблицу на клиенте и передавать большой объем данных. Если вам нужно просто обновить данные в существующих строках или добавить пару новых, лучше работать напрямую с реквизитом формы, не преобразуя его в ТаблицуЗначений.
Посмотрим на пример прямого изменения данных, которое сохраняет идентификаторы строк:
&НаСервере
Процедура ОбновитьЦеныНаСервере()
// Вместо ЗначениеВРеквизитФормы перебираем коллекцию напрямую
Для Каждого СтрокаТЧ Из Спецификация Цикл
// Допустим, мы просто увеличиваем цену на 10%
СтрокаТЧ.Цена = СтрокаТЧ.Цена * 1.1;
КонецЦикла;
// При таком подходе идентификаторы (ТекущаяСтрока) не изменятся
КонецПроцедуры
Рассмотрим несколько важных моментов, которые помогут избежать падения программы:
ЗначениеВРеквизитФормы на сервере, а в это время на клиенте выполняется обработчик ожидания или другое событие, которое обращается к старому ТекущаяСтрока, система выдаст ошибку. Старый ID перестал существовать в момент вызова метода.ЗначениеВРеквизитФормы ID всё равно сменится.Мы выяснили, что работа с таблицами в управляемых формах требует четкого разделения понятий индекса и идентификатора. Использование ТекущаяСтрока напрямую в качестве индекса — это классическая ошибка начинающего разработчика 1С. Правильный путь — это использование связки Элементы.Таблица.ТекущаяСтрока и метода РеквизитФормы.НайтиПоИдентификатору(). Это обеспечит стабильную работу интерфейса и корректную обработку данных даже при динамическом обновлении таблиц.