Зачем нужно вызывать метод Прочитать() перед записью в регистр сведений через МенеджерЗаписи?

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

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

Разберем механику работы МенеджераЗаписи

Объект МенеджерЗаписи (МЗ) — это специальная обертка, предназначенная для работы с одной конкретной записью регистра сведений. Технически он хранит внутреннее состояние, соответствующее значениям измерений и ресурсов регистра.

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

  1. Потеря контекста записи: Платформа может некорректно сопоставить текущий объект МЗ с уже существующей строкой в базе данных.
  2. Риск перезаписи: Без предварительного позиционирования метод Записать() может сработать непредсказуемо, особенно если в регистре уже есть данные с такими же ключевыми полями.
  3. Очистка ресурсов: Если запись содержит дополнительные ресурсы, которые вы не устанавливаете явно в текущем фрагменте кода, отсутствие чтения может привести к тому, что эти ресурсы будут очищены (установлены в значения по умолчанию/пустые значения), так как объект МЗ не «знал» о том, что именно было в базе до начала операции.

Проанализируем пример с курсами валют

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


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

// Установка свойств для первой валюты
ЗаписьКурсовВалют.Валюта = Валюта1;
ЗаписьКурсовВалют.Период = Дата;
ЗаписьКурсовВалют.Курс = 100;
ЗаписьКурсовВалют.Записать(); // Записывает курс 1

// При установке свойств для второй валюты без Прочитать()
ЗаписьКурсовВалют.Валюта = Валюта2;
ЗаписьКурсовВалют.Период = Дата;
ЗаписьКурсовВалют.Курс = 74;
ЗаписьКурсовВалют.Записать(); // Может привести к конфликту или потере предыдущей записи

Чтобы избежать подобных ситуаций, мы должны явно спозиционировать менеджер на ту запись, которую планируем изменять. Метод Прочитать() выполняет именно эту роль — он делает «запрос» к базе данных по текущим значениям измерений, загружает состояние записи в объект МЗ, и только после этого мы безопасно меняем значения ресурсов.

Правильный алгоритм работы

Разберем по шагам, как выглядит корректная последовательность действий:

  1. Создаем экземпляр менеджера записи: Менеджер = РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи();
  2. Устанавливаем значения ключевых полей (измерений): Менеджер.Валюта = ТекВалюта;
  3. Выполняем чтение для позиционирования: Менеджер.Прочитать();
  4. Устанавливаем или изменяем значения ресурсов: Менеджер.Курс = ТекКурс;
  5. Сохраняем изменения: Менеджер.Записать();

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

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

// Обновляем ресурсы
Менеджер.Курс = НовыйКурс;
Менеджер.Записать();

Почему это важно для стабильности системы?

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

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

3. Понимание платформы: Важно помнить, что МенеджерЗаписи — это обертка над набором записей. Когда вы работаете с ним, платформа в конечном итоге выполняет операции набора записей. Вызов Прочитать() — это ваш способ сказать системе: «я хочу работать с уже имеющимся объектом», что является стандартом разработки в типовых конфигурациях, таких как УПП или ERP.

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

← На главную