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