При разработке обработок для заполнения или переноса данных в 1С программисты часто сталкиваются с ситуацией, когда программная запись в регистр сведений (РС) работает не так, как ожидалось. Типичные симптомы: поле измерения остается пустым, хотя визуально данные в базе есть, или после работы обработки в регистре остается всего одна запись вместо тысяч. Рассмотрим подробно, как правильно организовать процесс записи на примере регистра ЗначенияСвойствОбъектов.
Проанализируем фрагмент кода, с которого часто начинают новички. Попытка найти элемент плана видов характеристик (ПВХ) через НайтиПоНаименованию("Вид упаковки") часто возвращает пустую ссылку. Выясним причину этого поведения.
Во-первых, метод НайтиПоНаименованию требует полного совпадения строки. Если в наименовании есть лишний пробел, невидимый символ или оно дополнено уточнением в скобках (например, Вид упаковки (Упаковки характеристик)), система вернет пустую ссылку. Во-вторых, поиск по строке крайне ненадежен в распределенных базах или при обновлении конфигураций.
Рассмотрим альтернативные и более надежные способы получения ссылки на свойство:
// Пример получения ссылки по ГУИД
Идентификатор = Новый УникальныйИдентификатор("550e8400-e29b-41d4-a716-446655440000");
СсылкаНаСвойство = ПланыВидовХарактеристик.СвойстваОбъектов.ПолучитьСсылку(Идентификатор);
СсылкаНаСвойство = ПредопределенноеЗначение("ПланВидовХарактеристик.СвойстваОбъектов.ИмяПредопределенногоЭлемента");
Проанализируем ситуацию, когда после выполнения цикла в регистре остается только одна последняя запись. Это происходит из-за непонимания механизма работы объекта НаборЗаписей. Посмотрим на ошибочную структуру:
Пока Выборка.Следующий() Цикл
НаборЗаписей = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
// ... заполнение записи ...
НаборЗаписей.Записать(); // ОШИБКА: очищает весь регистр или записи без отбора!
КонецЦикла;
Вызов метода Записать() без установленного фильтра в свойстве Отбор по умолчанию пытается заместить ВСЕ записи в регистре тем набором, который вы подготовили. В данном случае — одной строкой из текущей итерации цикла. Рассмотрим, как исправить эту логику.
Если нам нужно записывать данные по одной строке и мы знаем значения всех измерений, удобнее использовать РегистрСведенийМенеджерЗаписи. Этот объект работает с конкретной строкой регистра как с отдельным объектом.
Разберем по шагам правильный алгоритм:
Объект, Свойство).Прочитать(), если нужно обновить существующую запись, или сразу заполняем ресурсы и вызываем Записать().
Пока Выборка.Следующий() Цикл
МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Выборка.Владелец;
МенеджерЗаписи.Свойство = СсылкаНаСвойство;
МенеджерЗаписи.Значение = Выборка.Упаковка;
МенеджерЗаписи.Записать();
КонецЦикла;
Если требуется высокая производительность или нужно обновить сразу группу записей по конкретному объекту, используем НаборЗаписей с обязательным установкой отбора. Проанализируем пример:
НаборЗаписей = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
// Устанавливаем отбор, чтобы не затереть лишнего
НаборЗаписей.Отбор.Объект.Установить(Выборка.Владелец);
НаборЗаписей.Отбор.Свойство.Установить(СсылкаНаСвойство);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Объект = Выборка.Владелец;
НоваяЗапись.Свойство = СсылкаНаСвойство;
НоваяЗапись.Значение = Выборка.Упаковка;
НаборЗаписей.Записать(); // Теперь запишется только по конкретному объекту
Важный нюанс: метод Записать() без параметров удаляет старые записи, подходящие под отбор, и записывает новые. Если вам нужно просто добавить запись, не очищая существующие (и вы уверены, что не будет конфликта ключей), используйте Записать(Ложь).
Работая с этим конкретным регистром в типовых конфигурациях (УТ 11, ERP, КА 2), важно помнить о подсистеме «Дополнительные реквизиты и сведения». Прямая запись в регистр может быть "невидимой" для интерфейса, если свойство не включено в соответствующий набор свойств для данного типа объекта.
Профессиональный подход подразумевает использование функций программного интерфейса БСП (Библиотеки стандартных подсистем). Вместо прямого обращения к регистру, рекомендуется вызывать методы общего модуля УправлениеСвойствами. Это гарантирует соблюдение ссылочной целостности и корректное отображение данных в карточках объектов.
Если ваша выборка содержит тысячи строк, создание объекта менеджера или набора на каждой итерации создаст колоссальную нагрузку на СУБД. Выясним, как ускорить процесс:
НачатьТранзакцию() ... ЗафиксироватьТранзакцию(). Это позволит базе данных выполнить запись одним блоком.Записать(). Если вы записываете разные свойства для одного объекта, создайте один набор записей, установите отбор по объекту, добавьте все нужные строки в этот набор и запишите его один раз.Подведем итог: для успешной программной записи в регистр необходимо обеспечить точное получение ссылок (избегая поиска по наименованию), всегда использовать отборы при работе с наборами записей и учитывать специфику бизнес-логики конфигурации (использование БСП).