Получить объект по ссылке, провести и отменить проведение документа в 1С 8.3 программно
Чтобы программно изменить существующий элемент справочника или документ в 1С 8.3, вызовите на сервере метод ссылки Объект = Ссылка.ПолучитьОбъект(), проверьте Объект <> Неопределено, измените реквизиты и сохраните данные вызовом Объект.Записать().
Для управления проведением документа передайте в ДокументОбъект.Записать(РежимЗаписи, РежимПроведения) нужное значение системного перечисления РежимЗаписиДокумента: Запись (сохранить без изменения движений или перезаписать черновик), Проведение (провести с указанием РежимПроведенияДокумента.Оперативный или Неоперативный) либо ОтменаПроведения (снять проведение и очистить движения).
Чем ссылка отличается от объекта в 1С 8.3
В платформе 1С:Предприятие 8.3 важно разделять два типа данных: ссылочные типы (СправочникСсылка.<Имя>, ДокументСсылка.<Имя>) и объектные типы (СправочникОбъект.<Имя>, ДокументОбъект.<Имя>). Ссылка — это лёгкий указатель на запись в базе данных, который содержит уникальный идентификатор (УникальныйИдентификатор()) и тип таблицы.
Через точку от ссылки (например, СсылкаНаДокумент.Контрагент) можно только прочитать значения реквизитов, причём каждое такое обращение к первой некешированной ссылке приводит к считыванию всего объекта в кэш сеанса. Попытка присвоить новое значение свойству ссылки (СсылкаНаДокумент.Комментарий = "Исправлено") вызовет ошибку выполнения: свойства ссылки доступны исключительно для чтения. Кроме того, метод ПолучитьОбъект() существует только в серверном контексте (&НаСервере или &НаСервереБезКонтекста) — на тонком и веб-клиенте объектные типы данных недоступны.
Когда вы вызываете Ссылка.ПолучитьОбъект(), сервер 1С считывает из СУБД все реквизиты шапки и все строки табличных частей документа или справочника, размещая их в оперативной памяти рабочего процесса в виде изменяемого экземпляра ДокументОбъект или СправочникОбъект.
Как безопасно получить объект по ссылке программно
Перед вызовом ПолучитьОбъект() нужно убедиться, что ссылка заполнена и в базе данных реально существует соответствующая запись. Если переменная содержит Неопределено, Null или пустую ссылку (Документы.РеализацияТоваровУслуг.ПустаяСсылка()), а также если элемент был физически удалён из базы (битая ссылка «Объект не найден»), поведение кода зависит от проверки:
- Для пустой ссылки метод
ПустаяСсылка.ПолучитьОбъект()вызовет исключениеНельзя получить объект для пустой ссылки. - Для битой ссылки на удалённый элемент метод
БитаяСсылка.ПолучитьОбъект()не выбросит исключение, но вернёт значениеНеопределено.
&НаСервереБезКонтекста
Процедура ОбновитьКомментарийПоСсылке(СсылкаНаОбъект, НовыйКомментарий)
// 1. Проверяем, что передана непустая ссылка, а не Null или Неопределено
Если Не ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
Возврат;
КонецЕсли;
// 2. Получаем изменяемый объект в память сервера
ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
// 3. Защита от битой ссылки (если запись удалена из СУБД)
Если ОбъектБД = Неопределено Тогда
ЗаписьЖурналаРегистрации("ОбновлениеРеквизитов",
УровеньЖурналаРегистрации.Предупреждение, , СсылкаНаОбъект,
"Объект не найден в информационной базе (битая ссылка).");
Возврат;
КонецЕсли;
// 4. Блокируем объект от параллельного изменения в форме другим пользователем
ОбъектБД.Заблокировать();
ОбъектБД.Комментарий = НовыйКомментарий;
ОбъектБД.Записать();
КонецПроцедуры
Неопределено, Null и пустую ссылку перед вызовом методаНеопределено, если запись удалена из БДРежимЗаписиДокумента и проведение документа в 1С 8.3
В отличие от справочника, где метод СправочникОбъект.Записать() не принимает параметров, у объекта документа метод записи управляет как сохранением реквизитов, так и движениями по регистрам: ДокументОбъект.Записать(<РежимЗаписи>, <РежимПроведения>).
Первый параметр задаётся системным перечислением РежимЗаписиДокумента и принимает одно из трёх значений:
РежимЗаписиДокумента.Запись(значение по умолчанию, если параметр не передан) — записывает реквизиты и табличные части документа. Если документ ранее не был проведён, он остаётся непроведённым. Если документ уже был проведён, обычный вызовЗаписать(РежимЗаписиДокумента.Запись)сохранит новые реквизиты шапки и табличных частей, но оставит пометкуПроведен = Истинаи старые движения в регистрах без пересчёта.РежимЗаписиДокумента.Проведение— записывает документ, устанавливает свойствоПроведен = Истинаи вызывает обработчикОбработкаПроведенияв модуле объекта для формирования движений по регистрам.РежимЗаписиДокумента.ОтменаПроведения— снимает признак проведения (Проведен = Ложь), вызываетОбработкаУдаленияПроведенияи очищает движения документа во всех подчинённых регистрах.
&НаСервереБезКонтекста
Процедура ПровестиДокументПоСсылке(СсылкаНаДокумент, Оперативно = Ложь)
Если Не ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
Возврат;
КонецЕсли;
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Если ДокОбъект = Неопределено Или ДокОбъект.ПометкаУдаления Тогда
Возврат;
КонецЕсли;
// Выбираем режим проведения в зависимости от даты документа
Если Оперативно Тогда
РежимПроведения = РежимПроведенияДокумента.Оперативный;
Иначе
РежимПроведения = РежимПроведенияДокумента.Неоперативный;
КонецЕсли;
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведения);
Исключение
ЗаписьЖурналаРегистрации("ПроведениеДокументов",
УровеньЖурналаРегистрации.Ошибка, , СсылкаНаДокумент,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
РежимЗаписиДокумента.Запись (по умолчанию), Проведение или ОтменаПроведенияРежимПроведенияДокумента.Неоперативный (по умолчанию) или Оперативный — учитывается только при ПроведениеВторой параметр РежимПроведенияДокумента учитывается только тогда, когда первым параметром передан РежимЗаписиДокумента.Проведение. Если проводить документ прошлым периодом в режиме РежимПроведенияДокумента.Оперативный и в метаданных документа разрешено оперативное проведение, платформа либо выдаст ошибку, либо изменит дату документа на текущую серверную дату.
При написании групповых обработок проведения и корректировки реквизитов важно учитывать подписки на события и свойства конкретных документов конфигурации. В ИИ Консоли кода 1С агент видит метаданные вашей базы, сам проверяет допустимые режимы проведения документа и генерирует готовую внешнюю обработку .epf с безопасной транзакционной записью.
Как отменить проведение документа программно
Чтобы программно сделать проведённый документ непроведённым и удалить его движения из регистров накопления, бухгалтерии и расчёта, а также из подчинённых регистров сведений, вызовите метод Записать() с параметром РежимЗаписиДокумента.ОтменаПроведения. Второй параметр (РежимПроведения) при отмене проведения не указывается.
При таком вызове платформа открывает транзакцию, выполняет подписки на событие ПередЗаписью (где в параметре РежимЗаписи будет передано значение ОтменаПроведения), запускает процедуру ОбработкаУдаленияПроведения в модуле объекта, очищает наборы записей движений с признаком автоудаления и записывает саму шапку документа с Проведен = Ложь.
&НаСервереБезКонтекста
Процедура ОтменитьПроведениеДокумента(СсылкаНаДокумент, ПометитьНаУдаление = Ложь)
Если Не ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
Возврат;
КонецЕсли;
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Если ДокОбъект = Неопределено Тогда
Возврат;
КонецЕсли;
Если ПометитьНаУдаление Тогда
// Сам снимет проведение и установит ПометкаУдаления = Истина за один вызов
ДокОбъект.УстановитьПометкуУдаления(Истина);
ИначеЕсли ДокОбъект.Проведен Тогда
// Снимет проведение и очистит движения, оставив документ черновиком
ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;
КонецПроцедуры
ОбработкаУдаленияПроведения и очищает движения, сохраняя документ черновикомПометкаУдаления = ИстинаКогда использовать ОбменДанными.Загрузка = Истина
У любого экземпляра СправочникОбъект и ДокументОбъект есть системное свойство ОбменДанными типа ПараметрыОбменаДанными с булевым флагом Загрузка (по умолчанию Ложь). В типовых конфигурациях 1С (ERP, КА, УТ 11, БП 3.0, ЗУП 3.1) в начале всех обработчиков ПередЗаписью, ПриЗаписи и в подписках на события стоит стандартная проверка:
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если перед вызовом Объект.Записать() установить Объект.ОбменДанными.Загрузка = Истина, платформа запишет объект в режиме загрузки данных:
- Пропускаются все типовые проверки заполнения, контроль дат запрета изменения (БСП), бизнес-логика в
ПередЗаписью/ПриЗаписии подписки на эти события, где предусмотрен выход по флагуОбменДанными.Загрузка. - Платформа отключает автоматическое присвоение номера/кода, контроль уникальности кодов и проверку заполнения реквизитов со свойством «Проверка заполнения = Выдавать ошибку».
- Для документа не вызывается обработчик
ОбработкаПроведенияи не пересчитываются движения по регистрам — сохраняются только сам объект и те значения реквизитов (включая флагПроведен), которые уже заданы в объекте.
Поэтому режим ОбменДанными.Загрузка = Истина применяют тогда, когда нужно быстро обновить технический реквизит (например, комментарий, статус синхронизации или номер входящего документа) в тысячах проведённых документов прошлых периодов, не затрагивая их бухгалтерские и складские движения. Если же вы меняете сумму, количество, склад или цену и хотите пересчитать движения по регистрам, включать ОбменДанными.Загрузка = Истина категорически нельзя.
Сводная таблица режимов записи и методов объекта
В таблице собраны основные сценарии работы с объектом, полученным через Ссылка.ПолучитьОбъект(), и их влияние на движения документа и обработчики событий.
| Вызов в коде 1С 8.3 | Флаг Проведен |
Движения в регистрах | Когда применять |
|---|---|---|---|
Док.Записать(РежимЗаписиДокумента.Запись) |
Не меняется | Не пересчитываются | Сохранение нового или непроведённого документа (черновика) с вызовом проверок в ПередЗаписью. |
Док.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный) |
Становится Истина |
Формируются заново на дату документа | Проведение и перепроведение документов за прошлые периоды без сдвига времени документа. |
Док.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный) |
Становится Истина |
Формируются с оперативным контролем остатков | Проведение документа текущим моментом времени в реальном времени работы кассира или кладовщика. |
Док.Записать(РежимЗаписиДокумента.ОтменаПроведения) |
Становится Ложь |
Очищаются (вызывается ОбработкаУдаленияПроведения) |
Программное снятие документа с проведения без установки пометки на удаление. |
Док.ОбменДанными.Загрузка = Истина; Док.Записать(); |
Сохраняется как есть в объекте | Не трогаются (ОбработкаПроведения не вызывается) |
Служебное обновление справочных реквизитов (комментария, внешнего ID) без запуска проверок и перепроведения. |
Док.УстановитьПометкуУдаления(Истина) |
Становится Ложь |
Очищаются автоматически | Штатная пометка документа на удаление с одновременной отменой проведения. |
Частые ошибки при получении объекта и записи документов
- Вызов
Ссылка.ПолучитьОбъект()внутри цикла по выборке запроса. Каждое обращение кПолучитьОбъект()выполняет отдельные SQL-запросы к таблицам шапки и всех табличных частей объекта. Если нужно только прочитать реквизиты, выбирайте их прямо в запросе (ВЫБРАТЬ Док.Контрагент, Док.СуммаДокумента), аПолучитьОбъект()вызывайте исключительно для тех ссылок, которые действительно требуют перезаписи. - Попытка изменить реквизит напрямую через ссылку. Код вида
Выборка.Ссылка.Комментарий = "Ок"; Выборка.Ссылка.Записать();завершится ошибкой, так как уДокументСсылканет методаЗаписать(), а все её свойства доступны только для чтения. - Отсутствие проверки
Объект <> НеопределенопослеПолучитьОбъект(). Если в регистре или реквизите сохранилась битая ссылка на удалённый элемент,ПолучитьОбъект()вернётНеопределено, и следующая строкаОбъект.Записать()упадёт с исключениемЗначение не является значением объектного типа (Записать). - Запись уже проведённого документа в режиме
РежимЗаписиДокумента.Записьпосле изменения табличной части. Если в проведённом документе поменять количество или сумму и вызватьДокОбъект.Записать()без параметров, новые цифры сохранятся в документе, но в регистрах останутся старые движения — возникнет расхождение между первичным документом и отчётами. - Проведение документов задним числом в режиме
РежимПроведенияДокумента.Оперативный. Если не передать второй параметр вДокОбъект.Записать(РежимЗаписиДокумента.Проведение), по умолчанию используетсяНеоперативный, но при явной передачеОперативныйдля документа прошлой датой платформа сдвинет его дату на текущий день или откажет в проведении. - Снятие проведения через
ДокОбъект.Проведен = Ложьили с флагомОбменДанными.Загрузка = Истина. Если вручную сбросить свойствоПроведен = Ложьпри включённомОбменДанными.Загрузка = Истинаи вызватьЗаписать(), в журнале документ станет непроведённым, но все его движения в регистрах останутся в базе.
Найти документы с расхождениями между табличной частью и движениями в регистрах или быстро собрать обработку пакетного перепроведения помогает ИИ Консоль кода 1С: опишите задачу своими словами, и агент подготовит проверенный код под вашу конфигурацию.
Частые вопросы о получении объекта и режимах записи в 1С
Почему нельзя получить объект по ссылке на клиенте в управляемой форме?
В управляемом приложении 1С 8.3 объектные типы данных (СправочникОбъект, ДокументОбъект) существуют только в памяти сервера, поэтому метод ПолучитьОбъект() доступен только в процедурах с директивами &НаСервере или &НаСервереБезКонтекста. Если нужно изменить объект по действию пользователя на форме, передайте ссылку в серверную процедуру и выполните ПолучитьОбъект() и Записать() на сервере.
Чем отличается РежимЗаписиДокумента.Запись от Проведение для уже проведённого документа?
Если документ уже проведён, вызов Записать(РежимЗаписиДокумента.Запись) обновит реквизиты шапки и табличных частей в базе, сохранит признак Проведен = Истина, но не вызовет обработчик ОбработкаПроведения и не перезапишет движения по регистрам. Чтобы движения пересчитались по новым данным документа, необходимо вызывать Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный).
Как программно отменить проведение документа, не удаляя сам документ?
Получите объект документа на сервере через ДокОбъект = Ссылка.ПолучитьОбъект(), проверьте, что ДокОбъект <> Неопределено, и вызовите ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения). Платформа автоматически снимет флаг Проведен, выполнит обработчик ОбработкаУдаленияПроведения и очистит движения документа во всех регистрах.
ИИ Консоль кода 1С
Лайт
Для ознакомления с возможностями
- Полный набор инструментов без урезаний
- Без ввода карты
Старт
Для индивидуального использования
- До 5 конфигураций
- Встроенный агент запросов 1С
-
≈ 100 задач Подробнее про лимиты
- Техническая поддержка
Продвинутый
Популярный выборДля интенсивного использования или команд
- До 15 конфигураций
- Встроенный агент запросов 1С
-
≈ 300 задач Подробнее про лимиты
-
Свои подписки Codex, Claude и любые OpenAI-совместимые
-
Внешние обработки без Конфигуратора
- Приоритетная техническая поддержка