При программной разработке и интеграциях в среде 1С:Предприятие 8 часто возникает задача обновления реквизитов справочников — в частности, изменения кода причины постановки на учет (КПП) организации. Начинающие разработчики нередко сталкиваются с ситуацией, когда код выполняется без ошибок, однако новые данные в базе не сохраняются. Разберем механику работы платформы с объектами и выясним причину такого поведения.
Рассмотрим частую ошибку, возникающую при попытке изменить реквизит справочника в одну или две несвязанные строки:
// Ошибочный вариант 1: отсутствие вызова метода Записать()
СсылкаНаОрганизацию.ПолучитьОбъект().КПП = "771111111";
// Ошибочный вариант 2: повторный вызов ПолучитьОбъект()
СсылкаНаОрганизацию.ПолучитьОбъект().КПП = "771111111";
СсылкаНаОрганизацию.ПолучитьОбъект().Записать();
Выясним причину, почему приведенный выше код не приводит к изменению данных в информационной базе:
ПолучитьОбъект() считывает данные из базы и создает в оперативной памяти абсолютно новый экземпляр объектной сущности СправочникОбъект.Записать(). Сразу после выполнения строки объект удаляется сборщиком мусора, а изменения теряются.КПП. Вторая строка создает второй, совершенно новый экземпляр объекта, считывая его исходное состояние из базы данных, и записывает его обратно без каких-либо изменений. Первый объект с модифицированным КПП при этом уничтожается.Для корректного сохранения изменений необходимо сначала поместить ссылку на созданный объект в переменную, изменить требуемые реквизиты и затем вызвать метод Записать() у этой же переменной.
Разберем рабочий пример кода:
ОбъектОрганизации = СсылкаНаОрганизацию.ПолучитьОбъект();
ОбъектОрганизации.КПП = "771111111";
ОбъектОрганизации.Записать();
В этом случае платформа работает с одним и тем же экземпляром объекта в памяти и фиксирует новые значения в базе данных.
При вызове метода Записать() платформа выполняет обработчики событий модуля объекта (ПередЗаписью, ПриЗаписи) и общие подписки на события. В типовых конфигурациях встроена проверка корректности формата КПП (строка из 9 знаков, отсутствие недопустимых символов).
Если требуется изменить значение в обход встроенных алгоритмов валидации или отключить избыточные проверки при пакетной загрузке, используют режим загрузки данных:
Попытка
ОбъектОрганизации = СсылкаНаОрганизацию.ПолучитьОбъект();
Если ОбъектОрганизации <> Неопределено Тогда
ОбъектОрганизации.ОбменДанными.Загрузка = Истина;
ОбъектОрганизации.КПП = "771111111";
ОбъектОрганизации.Записать();
КонецЕсли;
Исключение
// Обработка ошибок блокировки или отсутствия прав доступа
ЗаписьЖурналаРегистрации("ОбновлениеКПП", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Если в конфигурации используется Библиотека стандартных подсистем (БСП), то для обновления одиночных реквизитов можно использовать готовую функцию общего модуля без явного получения объекта:
ЗначенияРеквизитов = Новый Структура;
ЗначенияРеквизитов.Вставить("КПП", "771111111");
ОбщегоНазначения.УстановитьРеквизитыОбъекта(СсылкаНаОрганизацию, ЗначенияРеквизитов);
Обратим внимание на архитектуру хранения данных в современных конфигурациях (1С:ERP, 1С:Комплексная автоматизация, 1С:Бухгалтерия предприятия 3.0, 1С:Управление торговлей 11):
РегистрацииВНалоговомОргане или связанных периодических регистрах сведений. Если изменить КПП только в справочнике Организации, печатные формы и регламентированные отчеты могут продолжать использовать старые данные из карточки регистрации в ИФНС.