При программной работе с регистрами сведений начинающие разработчики часто сталкиваются с ситуацией, когда добавление новой записи перезаписывает или полностью удаляет уже существующие данные в базе. Рассмотрим подробнее, почему возникают такие ошибки при использовании набора записей и менеджера записи, и разберем правильные варианты решения задачи.
Разберем ситуацию на примере работы с объектом СоздатьНаборЗаписей(). По умолчанию механизм записи набора записей работает в режиме замещения. Это означает, что при вызове метода Записать() платформа сначала **удаляет из базы данных все записи**, подпадающие под установленный отбор, а затем записывает новые строки, находящиеся в наборе.
Если перед вызовом метода Записать() или Прочитать() отбор по измерениям не был установлен вовсе, платформа считает отбор пустым и стирает абсолютно все записи из регистра сведений. Например, следующий код полностью очистит регистр:
// Опасно! Данный код удалит все записи из регистра сведений
Набор = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
Набор.Записать();
Выясним, как правильно работать с набором записей. Главное правило — **всегда устанавливать отбор по ключевым измерениям (и периоду, если регистр периодический) до считывания или записи набора**.
Проанализируем пошаговый алгоритм добавления записи через набор записей:
СоздатьНаборЗаписей().Прочитать() (если необходимо сохранить уже имеющиеся записи по данному отбору).Записать().Посмотрим на практический пример кода для записи контактной информации физического лица:
НовыйКИ = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
// Обязательно устанавливаем отбор по измерениям
НовыйКИ.Отбор.Объект.Установить(СсылкаНаФизЛицо);
НовыйКИ.Отбор.Тип.Установить(Перечисления.ТипыКонтактнойИнформации.Адрес);
НовыйКИ.Отбор.Вид.Установить(Справочники.ВидыКонтактнойИнформации.ЮрАдресФизЛица);
// Считываем существующие записи по этому отбору
НовыйКИ.Прочитать();
// Если запись отсутствует, добавляем новую
НоваяСтрока = НовыйКИ.Добавить();
НоваяСтрока.Объект = СсылкаНаФизЛицо;
НоваяСтрока.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
НоваяСтрока.Вид = Справочники.ВидыКонтактнойИнформации.ЮрАдресФизЛица;
НоваяСтрока.Представление = "г. Москва, ул. Ленина, д. 1";
// Записываем набор (заместятся только записи, подпадающие под отбор)
НовыйКИ.Записать();
Если вам требуется создать или обновить только одну конкретную запись в независимом или периодическом регистре сведений, удобнее использовать объект СоздатьМенеджерЗаписей(). Этот объект работает с единичной записью таблицы аналогично объекту справочника или документа.
Важно соблюдать строгий порядок выполнения методов при работе с МенеджерЗаписи:
Период для периодических регистров).Прочитать(), чтобы проверить наличие записи в базе данных.Записать().Разберем пример программного сохранения паспортных данных физического лица:
МенеджерЗаписи = РегистрыСведений.ПаспортныеДанныеФизЛиц.СоздатьМенеджерЗаписи();
// Step 1: Сначала задаем ключевые поля (Период и Измерения)
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.ФизЛицо = СсылкаНаФизЛицо;
// Step 2: Читаем запись из БД по указанному ключу
МенеджерЗаписи.Прочитать();
// Step 3: Заполняем ресурсы и реквизиты
МенеджерЗаписи.ДокументВид = ВидДокумента;
МенеджерЗаписи.ДокументСерия = СерияПаспорта;
МенеджерЗаписи.ДокументНомер = НомерПаспорта;
МенеджерЗаписи.ДокументДатаВыдачи = ДатаВыдачи;
МенеджерЗаписи.ДокументКемВыдан = КемВыдан;
// Step 4: Сохраняем запись
Попытка
МенеджерЗаписи.Записать();
Исключение
ЗаписьЖурналаРегистрации("Ошибка записи паспорта",
УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
При проектировании механизмов программной записи в регистры рекомендуем придерживаться следующих правил профессиональной разработки:
Передача параметров через Структуру: Избегайте передачи наборов данных между функциями с помощью объекта СписокЗначений и обращения по числовому индексу (Получить(0), Получить(1)). Это приводит к трудноотлавливаемым ошибкам при изменении состава или порядка элементов. Используйте объект Структура с явными именами ключей.
Обработка исключительных ситуаций: Не оставляйте блок Исключение пустым. Если запись не выполнится из-за блокировки или несоответствия типов, программа продолжит работу, замалчивая ошибку. Всегда заносите сведения с помощью ЗаписьЖурналаРегистрации или информируйте пользователя.
Проверка ссылки объекта: Перед записью сведений в регистр убедитесь, что связанный объект (например, физическое лицо) физически сохранен в базе и ссылка на него сформирована (НЕ СсылкаНаФизЛицо.Пустая()).