Как изменить запись регистра сведений из динамического списка в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с управляемыми формами часто возникает задача изменить значение реквизита или ресурса (например, установить флаг Прочитан) для выбранной строки в динамическом списке. В отличие от ссылочных объектов (документов или справочников), регистр сведений не имеет ссылок. Каждая его запись уникально идентифицируется совокупностью измерений и периодом (для периодических регистров).

В этой статье разберем, как правильно получить ключевые данные текущей строки из динамического списка на клиенте, передать их на сервер и применить изменения в базе данных.

Основные способы изменения записей регистра сведений

Рассмотрим два основных механизма платформы 1С для программного изменения записей регистра сведений:

  1. Использование Менеджера записи (СоздатьМенеджерЗаписи) — наилучший вариант для изменения одной конкретной записи, когда известны все ключевые измерения и период.
  2. Использование Набора записей (СоздатьНаборЗаписей) — подходит при редактировании записи через отбор или при необходимости работы с группой записей.

Шаг 1. Получение данных выбранной строки на клиенте

Проанализируем работу с динамическим списком. Для считывания значений текущей выделенной строки на клиенте используется свойство таблицы ТекущиеДанные. Важно учитывать, что динамический список запрашивает из базы только те поля, которые добавлены в колонки таблицы на форме. Если какое-то из измерений регистра не выведено в таблицу, его значение в ТекущиеДанные получить не удастся (при необходимости колонку можно сделать невидимой, установив свойство Видимость = Ложь).

Посмотрим на пример клиентского обработчика команды:


&НаКлиенте
Процедура ОтметитьКакПрочитанное(Команда)

    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Формируем структуру с ключевыми полями записи
    КлючЗаписи = Новый Структура;
    КлючЗаписи.Вставить("Период", ТекущиеДанные.Период);
    КлючЗаписи.Вставить("ПользовательОтКого", ТекущиеДанные.ПользовательОтКого);
    КлючЗаписи.Вставить("Сообщение", ТекущиеДанные.Сообщение);

    // Вызываем серверную процедуру
    ИзменитьЗаписьНаСервере(КлючЗаписи);

    // Обновляем динамический список для отображения изменений
    Элементы.Список.Обновить();

КонецПроцедуры

Шаг 2. Изменение записи на сервере через Менеджер записи

Рассмотрим реализацию серверной процедуры с использованием объекта МенеджерЗаписи. Заполняем ключевые измерения, считываем запись методом Прочитать(), модифицируем нужный ресурс и сохраняем вызовом Записать():


&НаСервере
Процедура ИзменитьЗаписьНаСервере(КлючЗаписи)

    МенеджерЗаписи = РегистрыСведений.СообщенияПользователям.СоздатьМенеджерЗаписи();
    
    // Заполняем ключевые поля (измерения и период)
    ЗаполнитьЗначенияСвойств(МенеджерЗаписи, КлючЗаписи);
    МенеджерЗаписи.ПользовательКому = ПараметрыСеанса.ТекущийПользователь;
    
    // Считываем запись из базы данных
    МенеджерЗаписи.Прочитать();
    
    // Изменяем нужный ресурс или реквизит
    МенеджерЗаписи.Прочитан = Истина;
    
    // Сохраняем изменения
    МенеджерЗаписи.Записать();

КонецПроцедуры

Альтернативный вариант: использование Набора записей

Разберем подход с использованием объекта НаборЗаписей. Этот способ часто применяется, когда требуется явно установить отбор по ключевым полям:


&НаСервере
Процедура ИзменитьЧерезНаборЗаписей(КлючЗаписи)

    Набор = РегистрыСведений.СообщенияПользователям.СоздатьНаборЗаписей();
    
    // Устанавливаем отбор по измерениям
    Набор.Отбор.Период.Установить(КлючЗаписи.Период);
    Набор.Отбор.ПользовательОтКого.Установить(КлючЗаписи.ПользовательОтКого);
    Набор.Отбор.Сообщение.Установить(КлючЗаписи.Сообщение);
    
    // Считываем данные
    Набор.Прочитать();
    
    // Изменяем запись в наборе
    Если Набор.Количество() > 0 Тогда
        Запись = Набор[0];
        Запись.Прочитан = Истина;
        Набор.Записать();
    КонецЕсли;

КонецПроцедуры

Групповая обработка нескольких выделенных строк

Выясним, как обработать сразу несколько строк, если пользователь выделил их в динамическом списке с использованием клавиш Shift или Ctrl.

Для считывания выделенных элементов на клиенте применяется свойство Элементы.Список.ВыделенныеСтроки и метод ДанныеСтроки():


&НаКлиенте
Процедура ОтметитьВыделенные(Команда)

    МассивКлючей = Новый Массив;
    
    Для Каждого ИдентификаторСтроки Из Элементы.Список.ВыделенныеСтроки Цикл
        СтрокаДанных = Элементы.Список.ДанныеСтроки(ИдентификаторСтроки);
        Если СтрокаДанных <> Неопределено Тогда
            КлючЗаписи = Новый Структура;
            КлючЗаписи.Вставить("Период", СтрокаДанных.Период);
            КлючЗаписи.Вставить("ПользовательОтКого", СтрокаДанных.ПользовательОтКого);
            КлючЗаписи.Вставить("Сообщение", СтрокаДанных.Сообщение);
            МассивКлючей.Добавить(КлючЗаписи);
        КонецЕсли;
    КонецЦикла;

    Если МассивКлючей.Количество() > 0 Тогда
        ИзменитьМассивЗаписейНаСервере(МассивКлючей);
        Элементы.Список.Обновить();
    КонецЕсли;

КонецПроцедуры

На сервере обходим массив ключей и обновляем соответствующую запись для каждого элемента:


&НаСервере
Процедура ИзменитьМассивЗаписейНаСервере(МассивКлючей)

    Для Каждого КлючЗаписи Из МассивКлючей Цикл
        МенеджерЗаписи = РегистрыСведений.СообщенияПользователям.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МенеджерЗаписи, КлючЗаписи);
        МенеджерЗаписи.ПользовательКому = ПараметрыСеанса.ТекущийПользователь;
        МенеджерЗаписи.Прочитать();
        
        Если МенеджерЗаписи.Выбран() Тогда
            МенеджерЗаписи.Прочитан = Истина;
            МенеджерЗаписи.Записать();
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

Важные особенности и правила

  1. Обновление списка: Изменение записей в базе данных не приводит к автоматическому обновлению данных на форме. После вызова серверной процедуры обязательно вызывайте Элементы.Список.Обновить().
  2. Колонки на форме: Все ключевые поля (измерения и период) должны обязательно находиться в составе элементов формы динамического списка, иначе метод ТекущиеДанные не вернет их значения.
  3. Встроенный способ редактирования: Если на форме не требуется дополнительная бизнес-логика, в конфигураторе для регистра сведений можно установить свойство «Способ редактирования» в значение «В списке». Это позволит редактировать значения полей прямо в ячейках динамического списка.
← На главную