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