Проведение и движения документа

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

Проведение — это отражение документа в учёте: платформа вызывает обработчик ОбработкаПроведения, который формирует движения по регистрам. Без движений документ ничего не меняет в итогах.

Формулировка вопроса: «Что происходит, когда пользователь проводит документ? Где и как формируются движения?» Это проверка понимания того, как данные из документа попадают в регистры и почему у документа есть галочка «Проведён». Ответ «нажимается кнопка, и всё сохраняется» собеседование не пройдёт — важна цепочка событий.

Что происходит при проведении

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

Процедура ОбработкаПроведения(Отказ, Режим)

    Движения.ТоварыНаСкладах.Записывать = Истина; // просим платформу записать набор

    Для Каждого СтрокаТовары Из Товары Цикл
        Движение = Движения.ТоварыНаСкладах.Добавить();
        Движение.ВидДвижения  = ВидДвиженияНакопления.Приход;
        Движение.Период       = Дата;
        Движение.Склад        = Склад;
        Движение.Номенклатура = СтрокаТовары.Номенклатура;
        Движение.Количество   = СтрокаТовары.Количество;
    КонецЦикла;

КонецПроцедуры

Что такое НаборЗаписей

Коллекция Движения.ТоварыНаСкладах — это набор записей регистра, привязанный к текущему документу-регистратору. Когда вы ставите Записывать = Истина, платформа при завершении проведения сама очистит старые движения этого документа и запишет новые. Это удобно: при перепроведении не нужно вручную удалять прошлые записи.

Параметр Отказ — как отменить проведение

Если в процессе выясняется, что проводить нельзя (например, не хватает остатка), выставляют Отказ = Истина. Тогда транзакция откатывается, движения не записываются, документ остаётся непроведённым.

Если СтрокаТовары.Количество <= 0 Тогда
    Сообщить("Количество должно быть больше нуля.");
    Отказ = Истина;
    Возврат;
КонецЕсли;

Оперативное и неоперативное проведение

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

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

Неоперативное проведение — это проведение «задним числом» или групповое: документ проводится не текущим моментом, а своей датой. Контроль остатков в реальном времени тут не имеет смысла (на дату в прошлом остаток мог быть другим), поэтому такие проверки при неоперативном режиме обычно пропускают. Практический вывод: жёсткий контроль «не уходить в минус» вешают только на оперативный режим, иначе перепроведение старых документов будет постоянно спотыкаться.

А что при отмене проведения

Логичный добивающий вопрос: «Куда деваются движения, когда документ распроводят?» При отмене проведения платформа вызывает ОбработкаУдаленияПроведения и очищает наборы записей документа — движения удаляются, итоги в регистрах пересчитываются. Обычно этот обработчик оставляют пустым: стандартной очистки достаточно. Писать в него код нужно лишь тогда, когда при распроведении требуется дополнительная логика (например, снять резерв или уведомить смежную систему).

Процедура ОбработкаУдаленияПроведения(Отказ)
    // Платформа сама очистит движения этого документа.
    // Здесь — только дополнительная логика при распроведении, если нужна.
КонецПроцедуры

Как отвечать

Разложите ответ по шагам: «При проведении срабатывает ОбработкаПроведения, где я формирую движения по регистрам через наборы записей Движения.ИмяРегистра. Всё пишется в одной транзакции; при ошибке ставлю Отказ = Истина, и изменения откатываются. Режим бывает оперативный — для контроля в реальном времени, например остатков, — и неоперативный, для проведения прошедшей датой и групповых операций». Такой ответ показывает, что вы понимаете и событийную модель, и транзакционность, и смысл режимов.

Частые ошибки на собеседовании

  • «Движения формируются при записи документа». Нет — при проведении. Запись просто сохраняет реквизиты; итоги в регистрах меняет проведение.
  • Вручную удалять старые движения перед записью. Набор записей с Записывать = Истина делает это сам. Ручная чистка — лишний код и источник ошибок.
  • Вешать контроль остатков на любой режим. Тогда перепроведение задним числом валится на нехватке остатка. Жёсткий контроль — только для оперативного режима.
  • Забыть про транзакцию. Кандидат думает, что можно записать часть движений. На деле проведение атомарно: Отказ откатывает всё.
  • Путать «Проведён» и «Записан». Документ может быть записан, но не проведён — тогда в учёте его нет.

Итоги-шпаргалка

  • Проведение вызывает ОбработкаПроведения, где формируются движения по регистрам.
  • Движения.ИмяРегистра — набор записей; при Записывать = Истина платформа сама перезапишет движения документа.
  • Всё выполняется в одной транзакции; Отказ = Истина откатывает проведение.
  • Оперативный режим — «сейчас», для контроля в реальном времени (остатки); неоперативный — прошедшей датой и группой.
  • Контроль «не уходить в минус» вешают только на оперативное проведение.
Проверьте себя
1. В каком обработчике документа формируются движения по регистрам?
AПередЗаписью
BОбработкаПроведения
CПриОткрытии
DОбработкаЗаполнения
2. Чем оперативное проведение отличается от неоперативного?
AОперативное записывает движения быстрее за счёт кэша
BОперативное выполняется текущим моментом и позволяет контролировать данные в реальном времени, например остатки
CНеоперативное не формирует движения вообще
DНеоперативное всегда игнорирует параметр Отказ