Кнопка «Записать» в 1С: что происходит с данными, блокировками и проверками

· 9 мин

Содержание

Записать в 1С — значит сохранить объект (документ, элемент справочника, набор записей регистра) в информационную базу. До записи все изменения живут только в открытой форме, и их видит один пользователь. После записи объект получает ссылку, номер или код, и с ним могут работать другие сотрудники и отчёты.

Для документа «Записать» и «Провести» — разные действия. Записанный, но не проведённый документ лежит в базе, но не делает движений: нет проводок, не меняются остатки, не считаются взаиморасчёты. Отсюда главная путаница новичков: «документ есть, а в оборотке пусто».

Что происходит в базе, когда вы нажимаете «Записать»

С точки зрения платформы 1С:Предприятие 8.3 запись — это одна транзакция. Внутри неё выполняется цепочка действий, и если хоть одно звено отказывает, откатывается всё.

Порядок для документа из формы такой:

  1. 🖥️ Клиент передаёт данные формы на сервер.
  2. 🔍 Если выбран режим проведения — выполняется проверка заполнения (обязательные поля, табличные части).
  3. 🔒 Платформа открывает транзакцию и ставит блокировку на сам объект.
  4. ⚙️ Вызываются обработчики модуля объекта: ПередЗаписью, затем физическая запись, затем ПриЗаписи.
  5. 📊 При проведении — ОбработкаПроведения и запись движений в регистры.
  6. ✅ Транзакция фиксируется, блокировки снимаются, форма получает обновлённые данные.

Если в любом обработчике установлено Отказ = Истина или возникло исключение, транзакция откатывается. В базе остаётся та версия объекта, что была до нажатия кнопки.

События формы при записи

Кроме модуля объекта, свои обработчики есть у управляемой формы. Они срабатывают только при записи из формы, а при программном Записать() — нет. Порядок такой:

  1. ПередЗаписью(Отказ, ПараметрыЗаписи) — на клиенте. Здесь задают вопросы пользователю, например «Провести документ с пустым комментарием?».
  2. ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи) — на сервере, до записи объекта. Удобно перенести в ТекущийОбъект данные, которых нет в реквизитах формы.
  3. Обработчики модуля объекта: ПередЗаписью, ПриЗаписи, при проведении — ОбработкаПроведения.
  4. ПриЗаписиНаСервере — ещё внутри транзакции; отказ здесь тоже откатит запись.
  5. ПослеЗаписиНаСервере — после фиксации транзакции; форма уже получила новые данные объекта.
  6. ПослеЗаписи — на клиенте, обычно для оповещения других форм.

Проверки, которые должны работать всегда, пишите в модуле объекта. Проверка только в форме не сработает при загрузке, обмене или записи из обработки.

Кнопки формы и что они делают

КнопкаСохраняет в базуДелает движенияЗакрывает форму
«Записать» (Ctrl+S)данет для непроведённого документанет
«Провести»даданет
«Провести и закрыть»дадада
«Записать и закрыть» (справочники)да—да

Если документ уже проведён, запись из формы выполняется с перепроведением: движения удаляются и формируются заново по новым данным. Поэтому исправить проведённый документ «без последствий для учёта» через «Записать» не получится.

Записать, провести, отменить проведение: режимы записи документа

В языке 1С у метода Записать() документа есть параметр режима. Это и есть «виды записи», о которых обычно спрашивают.

РежимЧто делаетПризнак «Проведён»
РежимЗаписиДокумента.Записьсохраняет реквизиты, движения не трогаетне меняется
РежимЗаписиДокумента.Проведениесохраняет и формирует движениястановится Истина
РежимЗаписиДокумента.ОтменаПроведениясохраняет и удаляет движениястановится Ложь

Второй параметр — режим проведения:

  • ⏱️ Оперативный (РежимПроведенияДокумента.Оперативный) — документ проводится текущим моментом времени. Здесь обычно работает контроль остатков: продать то, чего нет на складе, не дадут.
  • 📅 Неоперативный — проведение задним числом или будущей датой. Контроль остатков в типовых конфигурациях в этом режиме ведётся мягче или не ведётся вовсе, а последствия разбираются при восстановлении последовательности или закрытии месяца.

Пример программной записи документа с проведением:

ДокОбъект = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
ДокОбъект.Дата = ТекущаяДатаСеанса();
// ... заполнение реквизитов и табличных частей
Попытка
    ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
    Сообщить("Не удалось провести: " + ОписаниеОшибки());
КонецПопытки;

Вызов Записать() без параметров для документа означает режим Запись — без проведения.

Как запись связана с блокировками

Блокировки нужны, чтобы два пользователя не испортили данные друг другу. В 1С 8.3 они работают на двух уровнях.

Объектные блокировки — пока форма открыта

Когда пользователь начинает менять открытый документ, платформа ставит на него пессимистическую объектную блокировку. Второй пользователь сможет открыть тот же документ, но при попытке редактировать получит сообщение, что объект уже заблокирован.

Есть и оптимистическая проверка: при записи платформа сравнивает версию объекта в базе с версией, которую читала форма. Если кто-то успел записать объект раньше (например, обработкой без открытия формы), запись отклоняется с сообщением, что объект изменён или удалён другим пользователем. Лечится перечитыванием: закройте форму, откройте заново и повторите правку.

Транзакционные блокировки — в момент записи

Внутри транзакции записи действуют блокировки данных. Как именно — определяет свойство конфигурации «Режим управления блокировкой данных»:

РежимКак блокируетГде встречается
Автоматическийблокировки ставит СУБД, часто целыми таблицами или страницамистарые и самописные конфигурации
Управляемыйблокирует платформа, только нужные записи, по правилам из кодавсе актуальные типовые: БП 3.0, ЗУП 3.1, УТ 11, ERP
Автоматический и управляемыйрежим задаётся для каждого объекта отдельнопереходные конфигурации

В управляемом режиме разработчик сам ставит блокировку на то, что читает для контроля. Классический пример — остатки перед списанием:

Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
Элемент.Режим = РежимБлокировкиДанных.Исключительный;
Элемент.ИсточникДанных = Товары;
Элемент.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Элемент.УстановитьЗначение("Склад", Склад);
Блокировка.Заблокировать();

Код ставится в ОбработкаПроведения до чтения остатков. Без него два кладовщика одновременно спишут последнюю единицу товара, и остаток уйдёт в минус.

Запись справочников, документов и регистров: в чём разница

Метод один — Записать(), но поведение у разных объектов отличается.

Справочники

  • 🔢 Код присваивается при первой записи, если включена автонумерация.
  • 🧩 Уникальность кода проверяется платформой, если в свойствах справочника включён «Контроль уникальности».
  • 🗂️ Запись элемента с подчинёнными (табличными частями) идёт целиком: нельзя сохранить шапку без строк.
  • 🗑️ Установка пометки удаления — тоже запись. Объект не удаляется, а только помечается; физическое удаление выполняет отдельная обработка удаления помеченных объектов.

Документы

  • 🔢 Номер присваивается при первой записи. Если запись откатилась, номер может «сгореть» — отсюда пропуски в нумерации, и это нормально.
  • 📌 Признак «Проведён» меняется только через режимы записи из предыдущего раздела.
  • 📊 Движения пишутся не самим документом, а наборами записей регистров, подчинёнными регистратору.
  • 🆕 В обработчиках отличить первую запись от повторной помогает метод ЭтоНовый(): он возвращает Истина, пока объект ни разу не записан. Так обычно делают действия «только при создании» — например, заполнение автора документа или отправку уведомления.

Регистры сведений и накопления

У регистров записывается не одна строка, а набор записей по отбору. Ключевой параметр — замещение:

Набор = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
Набор.Отбор.Валюта.Установить(Валюта);
Набор.Отбор.Период.Установить(Дата);
Запись = Набор.Добавить();
Запись.Валюта = Валюта;
Запись.Период = Дата;
Запись.Курс = 92.15;
Запись.Кратность = 1;
Набор.Записать(Истина); // Истина = заменить записи по отбору
  • Записать(Истина) — старые записи по отбору удаляются, новые пишутся. Это режим по умолчанию.
  • Записать(Ложь) — новые записи добавляются к существующим. Для регистра сведений это может дать ошибку дубля ключа, для регистра накопления — задвоение движений.

Самая частая ошибка в обработках — записать набор с пустым отбором и замещением. Набор без отбора с Записать(Истина) очищает весь регистр и пишет только свои строки. Перед запуском такой обработки на рабочей базе сделайте резервную копию.

В модуле проведения документа наборы уже связаны с регистратором. Там пишут через Движения.ИмяРегистра, ставят Записывать = Истина, а платформа сама сохраняет наборы в конце проведения.

Проверки перед записью: заполнение, уникальность, отказ

Данные проходят несколько фильтров. Ошибка на любом из них останавливает запись.

  1. Проверка заполнения — свойство реквизита «Проверка заполнения: Выдавать ошибку» и обработчик ОбработкаПроверкиЗаполнения. Для справочника выполняется при интерактивной записи, для документа — при проведении. Пользователь видит сообщение вида Поле "Контрагент" не заполнено.
  2. Обработчик ПередЗаписью — здесь разработчик проверяет логику: дату, суммы, права на период. Отказ ставится так: Отказ = Истина.
  3. Дата запрета изменения — в типовых конфигурациях не даёт записать документ в закрытом периоде. Настраивается в Администрирование → Пользователи и права → Даты запрета изменения.
  4. Ограничения уровня СУБД и платформы — уникальность кода, длина строк, ссылочная целостность при удалении.

Отдельный режим — загрузка данных при обмене:

ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать();

Обработчики ПередЗаписью и ПриЗаписи при этом всё равно вызываются. Но типовой код в них начинается со строки Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;, поэтому бизнес-проверки и пересчёты пропускаются. Это ускоряет обмен, но переносит ответственность за корректность данных на того, кто загружает.

Почему 1С не даёт записать: типичные ошибки

Ниже — симптомы, которые чаще всего приводят пользователя к вопросу «что значит записать и почему не записывается».

Диагностика: выберите симптом

Журнал регистрации показывает, кто и когда записал объект, если включён уровень «Изменения» или выше. Отберите события «Данные. Изменение» по нужному объекту — так проще всего найти, кто перезаписал документ.

Массовая запись без тормозов

Когда обработка записывает тысячи объектов, каждая лишняя операция умножается. Что реально ускоряет:

  • 📦 Пачки в одной транзакции. Оберните запись 100–500 объектов в НачатьТранзакцию() / ЗафиксироватьТранзакцию(). Одна большая транзакция на 50 000 объектов надолго держит блокировки и при ошибке откатывает всё.
  • 🚫 ОбменДанными.Загрузка = Истина — если данные уже проверены и пересчёты в обработчиках не нужны.
  • 🔁 Не записывать неизменённое. Перед Записать() проверьте, изменились ли реквизиты: запись без изменений тоже создаёт транзакцию, версию объекта и событие в журнале.
  • 📊 Наборы записей вместо поштучной записи. Сто строк регистра в одном наборе пишутся быстрее, чем сто наборов по строке.
  • 🧮 Отключение итогов регистра накопления на время загрузки: РегистрыНакопления.ТоварыНаСкладах.УстановитьИспользованиеИтогов(Ложь), после окончания — Истина. Включение итогов пересчитывает их, это занимает время.
  • 🌙 Время запуска. Массовые записи с проведением — вне рабочих часов, иначе пользователи упрутся в ожидание блокировок.

Шаблон пачечной записи с корректным откатом:

Счётчик = 0;
НачатьТранзакцию();
Попытка
    Для Каждого Строка Из ТаблицаДанных Цикл
        Объект = Строка.Ссылка.ПолучитьОбъект();
        Объект.Комментарий = Строка.НовыйКомментарий;
        Объект.ОбменДанными.Загрузка = Истина;
        Объект.Записать();
        Счётчик = Счётчик + 1;
        Если Счётчик % 200 = 0 Тогда
            ЗафиксироватьТранзакцию();
            НачатьТранзакцию();
        КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

При ошибке откатится только текущая пачка; предыдущие уже зафиксированы. Учитывайте это при повторном запуске: обработка должна уметь пропускать уже обработанные объекты.

Массовая перезапись проведённых документов с режимом Проведение меняет движения задним числом. В бухгалтерских базах после этого придётся заново закрывать затронутые месяцы.

Частые вопросы

Можно ли записать документ без обязательных полей?
Да, если просто записать, а не проводить: проверка заполнения документа выполняется при проведении. Провести такой документ не получится, пока поля не заполнены.
Почему после записи изменился номер документа?
Новый документ получает номер при первой записи. До неё в поле номера пусто или стоит заготовка. Если номер повторяет существующий в том же периоде, платформа откажет в записи при включённом контроле уникальности.
Записывается ли документ при печати?
Новый документ перед печатью нужно записать: печатная форма строится по данным из базы. Типовые конфигурации предлагают записать объект сами, если он ещё не сохранён или изменён.
Чем «Записать» отличается от «Записать и закрыть»?
Только закрытием формы. Данные сохраняются одинаково. Для документов вместо «Записать и закрыть» обычно стоит «Провести и закрыть».
Можно ли отменить запись?
Отдельной кнопки отмены нет. Можно вернуть прежние значения вручную, посмотреть их в истории версий объекта (если она включена в конфигурации) или в журнале регистрации, а для документа — отменить проведение.