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