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