Работа с регистрами сведений — одна из базовых и наиболее часто встречающихся задач при разработке на платформе 1С. Часто возникают ситуации, когда необходимо найти конкретную запись по определенным критериям и обновить в ней данные (ресурсы или реквизиты) или вовсе изменить ключевые поля (измерения). В этой статье мы подробно разберем, как правильно манипулировать записями, какие объекты использовать и как избежать типичных ошибок, с которыми сталкиваются разработчики.
Если нам необходимо изменить одну конкретную запись и мы знаем значения всех её измерений, наиболее простым и логичным способом будет использование объекта РегистрСведенийМенеджерЗаписи. Рассмотрим этот метод подробнее.
Для того чтобы система могла однозначно идентифицировать строку в регистре, мы должны заполнить все измерения, входящие в уникальный ключ. Проанализируем типичный алгоритм работы:
МЗ = РегистрыСведений.НазваниеВашегоРегистра.СоздатьМенеджерЗаписи();
// Устанавливаем значения ВСЕХ измерений для поиска
МЗ.Измерение1 = Значение1;
МЗ.Измерение2 = Значение2;
// Пытаемся прочитать запись из базы данных
МЗ.Прочитать();
Если МЗ.Выбран() Тогда
// Если запись найдена, меняем нужные ресурсы или реквизиты
МЗ.Ресурс1 = НовоеЗначение;
МЗ.Записать();
Иначе
// Сообщаем, если запись не найдена, или создаем новую
Сообщить("Запись не найдена!");
КонецЕсли;
Важный нюанс: метод МенеджерЗаписи работает эффективно только тогда, когда вы точно знаете ключ записи. Если вы укажете не все измерения, метод Прочитать() не сможет найти существующую запись, и при вызове Записать() система попытается создать новую строку, что может привести к ошибке неуникальности данных.
Когда нам нужно изменить группу записей или выполнить поиск по частичному набору измерений, мы используем объект РегистрСведенийНаборЗаписей. Этот метод считается более универсальным и безопасным при массовых операциях.
Разберем по шагам, как работать с набором:
НаборЗаписей.Отбор.Рассмотрим пример кода:
Набор = РегистрыСведений.НазваниеВашегоРегистра.СоздатьНаборЗаписей();
// Устанавливаем отбор по конкретному измерению
Набор.Отбор.Измерение1.Установить(Значение1);
Набор.Прочитать();
Для Каждого Запись Из Набор Цикл
// Меняем ресурс
Запись.Ресурс1 = НовоеЗначение;
КонецЦикла;
// Записываем набор, замещая старые данные новыми
Набор.Записать(Истина);
Здесь параметр Истина в методе Записать() означает, что записи, соответствующие установленному отбору, будут полностью заменены данными из нашего набора в оперативной памяти.
Одна из самых частых проблем — попытка изменить само измерение у существующей записи. В 1С измерения формируют уникальный ключ, поэтому просто «переименовать» измерение в существующей записи нельзя. Выясним причину: технически изменение ключа — это удаление старой записи и создание новой.
Рассмотрим правильный алгоритм решения этой задачи:
Посмотрим на пример удаления старой записи через пустой набор:
// Удаление записи
НаборДляУдаления = РегистрыСведений.НазваниеВашегоРегистра.СоздатьНаборЗаписей();
НаборДляУдаления.Отбор.Измерение1.Установить(СтароеЗначение);
// Оставляем набор пустым и записываем — это удалит все записи с этим Измерением1
НаборДляУдаления.Записать(Истина);
// Добавление новой записи с измененным измерением
НоваяЗапись = РегистрыСведений.МенеджерЗаписи.СоздатьМенеджерЗаписи();
НоваяЗапись.Измерение1 = НовоеЗначение;
НоваяЗапись.Ресурс1 = ЗначениеРесурса;
НоваяЗапись.Записать();
Проанализируем ситуацию, когда процедура изменения записи вызывается с клиента на сервер. Часто в процедуру передаются параметры, такие как ТекущиеДанные строки формы. Для оптимизации и стабильности кода рекомендуется использовать ключевое слово Знач.
Почему это важно? Когда мы передаем параметры по ссылке (без Знач), 1С вынуждена отслеживать состояние объекта и возвращать его измененным на клиент. Если нам нужно просто прочитать данные для поиска в регистре, передача "по значению" (Знач) работает быстрее и исключает лишние ошибки передачи контекста. Выясним, как это выглядит в коде:
&НаСервереБезКонтекста
Процедура ИзменитьЗаписьНаСервере(Знач СтруктураКлюча, Знач НовоеЗначение)
МЗ = РегистрыСведений.ВашРегистр.СоздатьМенеджерЗаписи();
// Заполняем ключ из переданной структуры
ЗаполнитьЗначенияСвойств(МЗ, СтруктураКлюча);
МЗ.Прочитать();
Если МЗ.Выбран() Тогда
МЗ.НужныйРесурс = НовоеЗначение;
МЗ.Записать();
КонецЕсли;
КонецПроцедуры
В процессе работы вы можете столкнуться с тем, что код написан верно, но изменения «не видны» другим пользователям или система выдает ошибку об отсутствии полей. Часто это связано с динамическим обновлением конфигурации. Если вы добавили новое измерение или ресурс в регистр и применили изменения, пока пользователи работают в системе, их локальный кэш может конфликтовать с новой структурой базы данных.
Рекомендации по решению:
/ClearCache).&НаСервереБезКонтекста, так как они менее зависимы от состояния контекста формы.При работе в многопользовательском режиме важно помнить о блокировках. Если ваш код читает запись, а затем долго её обрабатывает перед записью, другой пользователь может успеть её изменить. Чтобы обеспечить целостность данных, рекомендуется использовать объект БлокировкаДанных внутри транзакции:
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИмяРегистра");
ЭлементБлокировки.УстановитьЗначение("Измерение1", Значение1);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
// Здесь код поиска и изменения записи
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Таким образом, мы рассмотрели основные механизмы поиска и модификации данных в регистрах сведений 1С. Помните: для точечных правок используйте МенеджерЗаписи, для массовых или сложных отборов — НаборЗаписей, а при изменении самих измерений всегда применяйте схему «удаление старого — создание нового».