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