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

Программист IT и автоматизация бизнеса
← На главную

При разработке в 1С часто возникает необходимость получить данные из регистра сведений по определенному условию, изменить их или заменить новыми. Рассмотрим типичную ситуацию: нам нужно получить старые данные о принадлежности сотрудников к определенной группе, очистить их и заполнить новыми. Проанализируем частые ошибки и разберем правильный алгоритм решения этой задачи.

Разберем проблему: почему метод Получить() выдает ошибку?

Часто разработчики пытаются использовать метод Получить (или ПолучитьПоследнее/ПолучитьПервое для периодических регистров), передавая в структуру отбора только одно значение, например, группу сотрудников. Посмотрим на пример кода, который приводит к ошибке:


Группа = Новый Структура("ГруппаСотрудников"); 
Группа.Вставить("ГруппаСотрудников", ГруппаСотрудников); 
Старое = РегистрыСведений.СоставГруппСотрудников.Получить(,Группа);

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

Правильное решение: использование объекта НаборЗаписей

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

  1. Создаем набор записей нужного регистра.
  2. Устанавливаем отбор по нужному измерению (в нашем случае — по группе).
  3. Читаем данные из базы данных в оперативную память (если нужно проанализировать старые данные).
  4. Очищаем набор или сразу добавляем новые записи.
  5. Записываем изменения в базу данных.

Посмотрим на пример правильного кода для выполнения этой операции:


// 1. Создаем набор записей
НаборЗаписей = РегистрыСведений.СоставГруппСотрудников.СоздатьНаборЗаписей();

// 2. Устанавливаем отбор по измерению
НаборЗаписей.Отбор.ГруппаСотрудников.Установить(НужнаяГруппа);

// 3. Читаем старые данные (если они нам нужны для анализа)
НаборЗаписей.Прочитать();

// 4. Очищаем старые данные (опционально, так как запись с замещением сделает это автоматически)
НаборЗаписей.Очистить();

// 5. Заполняем набор новыми данными в цикле
Для Каждого СтрокаСотрудника Из ТаблицаНовыхСотрудников Цикл
    НоваяЗапись = НаборЗаписей.Добавить();
    НоваяЗапись.ГруппаСотрудников = НужнаяГруппа;
    НоваяЗапись.Сотрудник = СтрокаСотрудника.Сотрудник;
КонецЦикла;

// 6. Записываем изменения в базу
НаборЗаписей.Записать();

Важные нюансы метода Записать()

Проанализируем работу метода Записать. У него есть булево свойство Замещать, которое по умолчанию всегда равно Истина. Это означает, что поведение системы при записи зависит от установленных отборов:

Замещение старых записей: Если вы установили отбор, прочитали набор, ничего не добавили и просто вызвали метод Записать(), платформа удалит все записи в базе данных, которые соответствуют этому отбору. Это самый быстрый способ очистить данные по конкретному измерению.

Добавление к существующим: Если вам нужно не удалить старые записи по группе, а просто дописать к ним новые, используйте вызов Записать(Ложь). При таком подходе новые записи из набора будут аккуратно добавлены к уже существующим в базе данных.

Оптимизация: метод Загрузить()

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


НаборЗаписей = РегистрыСведений.СоставГруппСотрудников.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ГруппаСотрудников.Установить(НужнаяГруппа);

// РезультатЗапроса - это результат выполнения вашего запроса
ТаблицаДанных = РезультатЗапроса.Выгрузить();

// Названия колонок таблицы должны совпадать с именами измерений и ресурсов регистра
НаборЗаписей.Загрузить(ТаблицаДанных);

// Записываем с автоматическим замещением старых данных по отбору
НаборЗаписей.Записать();

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

В завершение разберем одно критически важное ограничение. Все манипуляции, описанные выше, применимы только в том случае, если регистр сведений является независимым.

Если в конфигураторе в свойствах регистра установлен режим «Подчинение регистратору», то управлять записями напрямую через произвольные отборы (например, по группе сотрудников) не выйдет. В таких регистрах отбор можно устанавливать исключительно по документу-регистратору. Если попытаться записать набор с другим отбором, платформа выдаст ошибку. В этом случае, чтобы изменить состав группы, придется программно находить документы, которые сформировали эти записи, изменять их табличные части и перепроводить.

← На главную