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

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

Работа с регистрами сведений — одна из базовых и наиболее часто встречающихся задач при разработке на платформе 1С. Часто возникают ситуации, когда необходимо найти конкретную запись по определенным критериям и обновить в ней данные (ресурсы или реквизиты) или вовсе изменить ключевые поля (измерения). В этой статье мы подробно разберем, как правильно манипулировать записями, какие объекты использовать и как избежать типичных ошибок, с которыми сталкиваются разработчики.

Способ 1. Использование Менеджера Записи

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

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


МЗ = РегистрыСведений.НазваниеВашегоРегистра.СоздатьМенеджерЗаписи();
// Устанавливаем значения ВСЕХ измерений для поиска
МЗ.Измерение1 = Значение1;
МЗ.Измерение2 = Значение2;
// Пытаемся прочитать запись из базы данных
МЗ.Прочитать();

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

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

Способ 2. Использование Набора Записей

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

Разберем по шагам, как работать с набором:

  1. Создаем объект НаборЗаписей.
  2. Устанавливаем фильтр через свойство Отбор.
  3. Читаем данные из базы.
  4. Модифицируем записи в цикле.
  5. Записываем изменения.

Рассмотрим пример кода:


Набор = РегистрыСведений.НазваниеВашегоРегистра.СоздатьНаборЗаписей();
// Устанавливаем отбор по конкретному измерению
Набор.Отбор.Измерение1.Установить(Значение1);
Набор.Прочитать();

Для Каждого Запись Из Набор Цикл
    // Меняем ресурс
    Запись.Ресурс1 = НовоеЗначение;
КонецЦикла;

// Записываем набор, замещая старые данные новыми
Набор.Записать(Истина);

Здесь параметр Истина в методе Записать() означает, что записи, соответствующие установленному отбору, будут полностью заменены данными из нашего набора в оперативной памяти.

Как изменить ключевые поля (измерения)

Одна из самых частых проблем — попытка изменить само измерение у существующей записи. В 1С измерения формируют уникальный ключ, поэтому просто «переименовать» измерение в существующей записи нельзя. Выясним причину: технически изменение ключа — это удаление старой записи и создание новой.

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

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

Посмотрим на пример удаления старой записи через пустой набор:


// Удаление записи
НаборДляУдаления = РегистрыСведений.НазваниеВашегоРегистра.СоздатьНаборЗаписей();
НаборДляУдаления.Отбор.Измерение1.Установить(СтароеЗначение);
// Оставляем набор пустым и записываем — это удалит все записи с этим Измерением1
НаборДляУдаления.Записать(Истина);

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

Особенности работы на сервере и использование Знач

Проанализируем ситуацию, когда процедура изменения записи вызывается с клиента на сервер. Часто в процедуру передаются параметры, такие как ТекущиеДанные строки формы. Для оптимизации и стабильности кода рекомендуется использовать ключевое слово Знач.

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


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

Работа с кэшированием и динамическим обновлением

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

Рекомендации по решению:

Блокировки данных при записи

При работе в многопользовательском режиме важно помнить о блокировках. Если ваш код читает запись, а затем долго её обрабатывает перед записью, другой пользователь может успеть её изменить. Чтобы обеспечить целостность данных, рекомендуется использовать объект БлокировкаДанных внутри транзакции:


Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИмяРегистра");
ЭлементБлокировки.УстановитьЗначение("Измерение1", Значение1);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

НачатьТранзакцию();
Попытка
    Блокировка.Заблокировать();
    // Здесь код поиска и изменения записи
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

Таким образом, мы рассмотрели основные механизмы поиска и модификации данных в регистрах сведений 1С. Помните: для точечных правок используйте МенеджерЗаписи, для массовых или сложных отборов — НаборЗаписей, а при изменении самих измерений всегда применяйте схему «удаление старого — создание нового».

← На главную