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