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

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

При работе в среде 1С:Предприятие программисты часто сталкиваются с необходимостью программной корректировки данных в регистрах сведений. В отличие от справочников или документов, у регистров сведений нет понятия "Объект" в привычном понимании (как СправочникОбъект). Это вызывает закономерный вопрос: как же тогда изменить уже существующую строку? В этой статье мы подробно разберем механизмы изменения записей, изучим основные инструменты и предостережем вас от типичных ошибок, которые могут привести к полной потере данных в регистре.

Особенности архитектуры регистров сведений

Прежде всего, нам необходимо уяснить, что регистр сведений — это набор записей, каждая из которых уникальна в пределах своих ключевых полей (измерений). Мы не можем просто "найти" запись и вызвать у неё метод Записать(). Для изменения данных нам придется использовать специальные посредники. Рассмотрим два основных способа: Набор записей и Менеджер записи.

Способ 1. Использование Набора записей (массовое изменение)

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

Рассмотрим по шагам алгоритм действий:

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

Посмотрим на конкретный пример кода:


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

// 2. Устанавливаем отбор по ключевым полям (измерениям)
// Важно: отбор можно ставить только на те поля, которые помечены как "Использовать в отборе"
Набор.Отбор.Контрагент.Установить(ВыбКонтрагент);
Набор.Отбор.Организация.Установить(ВыбОрганизация);

// 3. Читаем данные из базы в память
Набор.Прочитать();

// 4. Модифицируем записи
Для Каждого Запись Из Набор Цикл
    // Предположим, нам нужно изменить ресурс "Статус"
    Запись.Статус = Перечисления.СтатусыКонтрагентов.Активен;
    Запись.ДатаИзменения = ТекущаяДата();
КонецЦикла;

// 5. Записываем результат обратно в БД
Набор.Записать();

Способ 2. Использование Менеджера записи (единичное изменение)

Если нам достоверно известно, что нужно изменить всего одну конкретную запись, и мы знаем значения всех её измерений, удобно использовать СоздатьМенеджерЗаписи(). Этот объект во многом похож на работу с объектами справочников.

Разберем, как это работает:


Менеджер = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();

// Заполняем ключевые поля (измерения), чтобы однозначно идентифицировать запись
Менеджер.Контрагент = ВыбКонтрагент;
Менеджер.Организация = ВыбОрганизация;

// Пытаемся прочитать существующую запись
Менеджер.Прочитать();

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

Важное примечание: Использование менеджера записи в цикле для обработки тысяч строк — плохая практика. Каждый вызов Записать() у менеджера инициирует отдельную транзакцию и отдельное обращение к СУБД, что существенно замедляет работу системы. В таких ситуациях всегда выбирайте Набор записей.

Критическая ошибка: Запись без отбора

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

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

Рассмотрим пример "опасного" кода, который уничтожит данные:


// ОПАСНО! Очистка всего регистра
мНаборЗаписей = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
мНаборЗаписей.Записать(); // Здесь нет отбора и нет строк в наборе — регистр станет пустым

Работа с периодическими регистрами

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

Регистры, подчиненные регистратору

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

Чтобы изменить такие данные, нам нужно:

  1. Установить отбор по документу-регистратору.
  2. Прочитать набор.
  3. Внести правки и записать.

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

Заключение и рекомендации

Подведем итог нашему исследованию. Для эффективного управления данными в регистрах сведений:

Соблюдение этих простых правил позволит вам безопасно и эффективно манипулировать данными в регистрах сведений 1С.

← На главную