Кнопка «Записать» в 1С: что происходит с данными, блокировками и проверками
Содержание
Записать в 1С — значит сохранить объект (документ, элемент справочника, набор записей регистра) в информационную базу. До записи все изменения живут только в открытой форме, и их видит один пользователь. После записи объект получает ссылку, номер или код, и с ним могут работать другие сотрудники и отчёты.
Для документа «Записать» и «Провести» — разные действия. Записанный, но не проведённый документ лежит в базе, но не делает движений: нет проводок, не меняются остатки, не считаются взаиморасчёты. Отсюда главная путаница новичков: «документ есть, а в оборотке пусто».
Что происходит в базе, когда вы нажимаете «Записать»
С точки зрения платформы 1С:Предприятие 8.3 запись — это одна транзакция. Внутри неё выполняется цепочка действий, и если хоть одно звено отказывает, откатывается всё.
Порядок для документа из формы такой:
- 🖥️ Клиент передаёт данные формы на сервер.
- 🔍 Если выбран режим проведения — выполняется проверка заполнения (обязательные поля, табличные части).
- 🔒 Платформа открывает транзакцию и ставит блокировку на сам объект.
- ⚙️ Вызываются обработчики модуля объекта:
ПередЗаписью, затем физическая запись, затемПриЗаписи. - 📊 При проведении —
ОбработкаПроведенияи запись движений в регистры. - ✅ Транзакция фиксируется, блокировки снимаются, форма получает обновлённые данные.
Если в любом обработчике установлено Отказ = Истина или возникло исключение, транзакция откатывается. В базе остаётся та версия объекта, что была до нажатия кнопки.
События формы при записи
Кроме модуля объекта, свои обработчики есть у управляемой формы. Они срабатывают только при записи из формы, а при программном Записать() — нет. Порядок такой:
ПередЗаписью(Отказ, ПараметрыЗаписи)— на клиенте. Здесь задают вопросы пользователю, например «Провести документ с пустым комментарием?».ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)— на сервере, до записи объекта. Удобно перенести вТекущийОбъектданные, которых нет в реквизитах формы.- Обработчики модуля объекта:
ПередЗаписью,ПриЗаписи, при проведении —ОбработкаПроведения. ПриЗаписиНаСервере— ещё внутри транзакции; отказ здесь тоже откатит запись.ПослеЗаписиНаСервере— после фиксации транзакции; форма уже получила новые данные объекта.ПослеЗаписи— на клиенте, обычно для оповещения других форм.
Проверки, которые должны работать всегда, пишите в модуле объекта. Проверка только в форме не сработает при загрузке, обмене или записи из обработки.
Кнопки формы и что они делают
| Кнопка | Сохраняет в базу | Делает движения | Закрывает форму |
|---|---|---|---|
«Записать» (Ctrl+S) | да | нет для непроведённого документа | нет |
| «Провести» | да | да | нет |
| «Провести и закрыть» | да | да | да |
| «Записать и закрыть» (справочники) | да | — | да |
Если документ уже проведён, запись из формы выполняется с перепроведением: движения удаляются и формируются заново по новым данным. Поэтому исправить проведённый документ «без последствий для учёта» через «Записать» не получится.
Записать, провести, отменить проведение: режимы записи документа
В языке 1С у метода Записать() документа есть параметр режима. Это и есть «виды записи», о которых обычно спрашивают.
| Режим | Что делает | Признак «Проведён» |
|---|---|---|
РежимЗаписиДокумента.Запись | сохраняет реквизиты, движения не трогает | не меняется |
РежимЗаписиДокумента.Проведение | сохраняет и формирует движения | становится Истина |
РежимЗаписиДокумента.ОтменаПроведения | сохраняет и удаляет движения | становится Ложь |
Второй параметр — режим проведения:
- ⏱️ Оперативный (
РежимПроведенияДокумента.Оперативный) — документ проводится текущим моментом времени. Здесь обычно работает контроль остатков: продать то, чего нет на складе, не дадут. - 📅 Неоперативный — проведение задним числом или будущей датой. Контроль остатков в типовых конфигурациях в этом режиме ведётся мягче или не ведётся вовсе, а последствия разбираются при восстановлении последовательности или закрытии месяца.
Пример программной записи документа с проведением:
ДокОбъект = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
ДокОбъект.Дата = ТекущаяДатаСеанса();
// ... заполнение реквизитов и табличных частей
Попытка
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
Сообщить("Не удалось провести: " + ОписаниеОшибки());
КонецПопытки;
Вызов Записать() без параметров для документа означает режим Запись — без проведения.
Как запись связана с блокировками
Блокировки нужны, чтобы два пользователя не испортили данные друг другу. В 1С 8.3 они работают на двух уровнях.
Объектные блокировки — пока форма открыта
Когда пользователь начинает менять открытый документ, платформа ставит на него пессимистическую объектную блокировку. Второй пользователь сможет открыть тот же документ, но при попытке редактировать получит сообщение, что объект уже заблокирован.
Есть и оптимистическая проверка: при записи платформа сравнивает версию объекта в базе с версией, которую читала форма. Если кто-то успел записать объект раньше (например, обработкой без открытия формы), запись отклоняется с сообщением, что объект изменён или удалён другим пользователем. Лечится перечитыванием: закройте форму, откройте заново и повторите правку.
Транзакционные блокировки — в момент записи
Внутри транзакции записи действуют блокировки данных. Как именно — определяет свойство конфигурации «Режим управления блокировкой данных»:
| Режим | Как блокирует | Где встречается |
|---|---|---|
| Автоматический | блокировки ставит СУБД, часто целыми таблицами или страницами | старые и самописные конфигурации |
| Управляемый | блокирует платформа, только нужные записи, по правилам из кода | все актуальные типовые: БП 3.0, ЗУП 3.1, УТ 11, ERP |
| Автоматический и управляемый | режим задаётся для каждого объекта отдельно | переходные конфигурации |
В управляемом режиме разработчик сам ставит блокировку на то, что читает для контроля. Классический пример — остатки перед списанием:
Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
Элемент.Режим = РежимБлокировкиДанных.Исключительный;
Элемент.ИсточникДанных = Товары;
Элемент.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Элемент.УстановитьЗначение("Склад", Склад);
Блокировка.Заблокировать();
Код ставится в ОбработкаПроведения до чтения остатков. Без него два кладовщика одновременно спишут последнюю единицу товара, и остаток уйдёт в минус.
Запись справочников, документов и регистров: в чём разница
Метод один — Записать(), но поведение у разных объектов отличается.
Справочники
- 🔢 Код присваивается при первой записи, если включена автонумерация.
- 🧩 Уникальность кода проверяется платформой, если в свойствах справочника включён «Контроль уникальности».
- 🗂️ Запись элемента с подчинёнными (табличными частями) идёт целиком: нельзя сохранить шапку без строк.
- 🗑️ Установка пометки удаления — тоже запись. Объект не удаляется, а только помечается; физическое удаление выполняет отдельная обработка удаления помеченных объектов.
Документы
- 🔢 Номер присваивается при первой записи. Если запись откатилась, номер может «сгореть» — отсюда пропуски в нумерации, и это нормально.
- 📌 Признак «Проведён» меняется только через режимы записи из предыдущего раздела.
- 📊 Движения пишутся не самим документом, а наборами записей регистров, подчинёнными регистратору.
- 🆕 В обработчиках отличить первую запись от повторной помогает метод
ЭтоНовый(): он возвращаетИстина, пока объект ни разу не записан. Так обычно делают действия «только при создании» — например, заполнение автора документа или отправку уведомления.
Регистры сведений и накопления
У регистров записывается не одна строка, а набор записей по отбору. Ключевой параметр — замещение:
Набор = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
Набор.Отбор.Валюта.Установить(Валюта);
Набор.Отбор.Период.Установить(Дата);
Запись = Набор.Добавить();
Запись.Валюта = Валюта;
Запись.Период = Дата;
Запись.Курс = 92.15;
Запись.Кратность = 1;
Набор.Записать(Истина); // Истина = заменить записи по отбору
Записать(Истина)— старые записи по отбору удаляются, новые пишутся. Это режим по умолчанию.Записать(Ложь)— новые записи добавляются к существующим. Для регистра сведений это может дать ошибку дубля ключа, для регистра накопления — задвоение движений.
Самая частая ошибка в обработках — записать набор с пустым отбором и замещением. Набор без отбора с Записать(Истина) очищает весь регистр и пишет только свои строки. Перед запуском такой обработки на рабочей базе сделайте резервную копию.
В модуле проведения документа наборы уже связаны с регистратором. Там пишут через Движения.ИмяРегистра, ставят Записывать = Истина, а платформа сама сохраняет наборы в конце проведения.
Проверки перед записью: заполнение, уникальность, отказ
Данные проходят несколько фильтров. Ошибка на любом из них останавливает запись.
- Проверка заполнения — свойство реквизита «Проверка заполнения: Выдавать ошибку» и обработчик
ОбработкаПроверкиЗаполнения. Для справочника выполняется при интерактивной записи, для документа — при проведении. Пользователь видит сообщение видаПоле "Контрагент" не заполнено. - Обработчик
ПередЗаписью— здесь разработчик проверяет логику: дату, суммы, права на период. Отказ ставится так:Отказ = Истина. - Дата запрета изменения — в типовых конфигурациях не даёт записать документ в закрытом периоде. Настраивается в
Администрирование → Пользователи и права → Даты запрета изменения. - Ограничения уровня СУБД и платформы — уникальность кода, длина строк, ссылочная целостность при удалении.
Отдельный режим — загрузка данных при обмене:
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать();
Обработчики ПередЗаписью и ПриЗаписи при этом всё равно вызываются. Но типовой код в них начинается со строки Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;, поэтому бизнес-проверки и пересчёты пропускаются. Это ускоряет обмен, но переносит ответственность за корректность данных на того, кто загружает.
Почему 1С не даёт записать: типичные ошибки
Ниже — симптомы, которые чаще всего приводят пользователя к вопросу «что значит записать и почему не записывается».
ОписаниеОшибки() или в журнале регистрации: Администрирование → Обслуживание → Журнал регистрации.Журнал регистрации показывает, кто и когда записал объект, если включён уровень «Изменения» или выше. Отберите события «Данные. Изменение» по нужному объекту — так проще всего найти, кто перезаписал документ.
Массовая запись без тормозов
Когда обработка записывает тысячи объектов, каждая лишняя операция умножается. Что реально ускоряет:
- 📦 Пачки в одной транзакции. Оберните запись 100–500 объектов в
НачатьТранзакцию()/ЗафиксироватьТранзакцию(). Одна большая транзакция на 50 000 объектов надолго держит блокировки и при ошибке откатывает всё. - 🚫
ОбменДанными.Загрузка = Истина— если данные уже проверены и пересчёты в обработчиках не нужны. - 🔁 Не записывать неизменённое. Перед
Записать()проверьте, изменились ли реквизиты: запись без изменений тоже создаёт транзакцию, версию объекта и событие в журнале. - 📊 Наборы записей вместо поштучной записи. Сто строк регистра в одном наборе пишутся быстрее, чем сто наборов по строке.
- 🧮 Отключение итогов регистра накопления на время загрузки:
РегистрыНакопления.ТоварыНаСкладах.УстановитьИспользованиеИтогов(Ложь), после окончания —Истина. Включение итогов пересчитывает их, это занимает время. - 🌙 Время запуска. Массовые записи с проведением — вне рабочих часов, иначе пользователи упрутся в ожидание блокировок.
Шаблон пачечной записи с корректным откатом:
Счётчик = 0;
НачатьТранзакцию();
Попытка
Для Каждого Строка Из ТаблицаДанных Цикл
Объект = Строка.Ссылка.ПолучитьОбъект();
Объект.Комментарий = Строка.НовыйКомментарий;
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Счётчик = Счётчик + 1;
Если Счётчик % 200 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
При ошибке откатится только текущая пачка; предыдущие уже зафиксированы. Учитывайте это при повторном запуске: обработка должна уметь пропускать уже обработанные объекты.
Массовая перезапись проведённых документов с режимом Проведение меняет движения задним числом. В бухгалтерских базах после этого придётся заново закрывать затронутые месяцы.