- Explain step by step what happens during posting
- Create records in code and with the wizard, and control balances
- Use object modules, manager modules and event subscriptions in the right place
Elvin, the storekeeper, posts a “Goods sale” document. The program must do two things: reduce the stock balance and refuse to post the document if there is not enough tea. In this lesson we write the engine of posting: the ОбработкаПроведения procedure, register records and balance control.
What happens during posting
- The platform opens a transaction and writes the document with
Проведен = Истина. ОбработкаПроведения(Отказ, РежимПроведения)(Posting) is called in the object module — records are filled here.- Record sets with
Записывать = Истинаare written and replace this document's old records — so re-posting never doubles the data. - If the code set
Отказ = Истина(Cancel), the transaction is rolled back: neither the document nor the records are saved.
On the document's Движения (Register records) tab, Проведение (Posting) must be Разрешить (Allow) and the registers must be ticked. There is also the Удаление движений property: Удалять автоматически, Удалять автоматически при отмене проведения or Не удалять автоматически — it decides what happens to old records on unposting and re-posting.
Creating register records
- 1Open the wizard
On the
Движенияtab ofПриходТовара, tick theОстаткиТоваровregister and clickКонструктор движений(Register records wizard). - 2Choose the source and expressions
Tabular section
Товары, record typeПриход. ClickЗаполнить выражения(Fill expressions) — the wizard matches register fields with attributes of the same name; type the rest by hand. - 3Check the code
Click
ОК:ОбработкаПроведенияappears in the object module. Post a document with F5 and view its records viaПерейти › Остатки товаров(Go to).
// Модуль объекта документа ПриходТовара
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого СтрокаТовары Из Товары Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Период = Дата;
Движение.Товар = СтрокаТовары.Товар;
Движение.Склад = Склад;
Движение.Количество = СтрокаТовары.Количество;
КонецЦикла;
КонецПроцедурыДата, Склад, Товары. The platform fills the Регистратор field itself.Balance control
The РасходТовара document reduces the balance. The modern (“new”) method is: first write the Расход records, then check with one query that no balance has gone negative. Before writing, set БлокироватьДляИзменения = Истина (LockForUpdate) so that users working in parallel cannot “spend” the same stock at the same moment. If a negative balance is found — Отказ = Истина.
// Модуль объекта документа РасходТовара
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого СтрокаТовары Из Товары Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Товар = СтрокаТовары.Товар;
Движение.Склад = Склад;
Движение.Количество = СтрокаТовары.Количество;
КонецЦикла;
Движения.ОстаткиТоваров.БлокироватьДляИзменения = Истина;
Движения.ОстаткиТоваров.Записать();
ПроверитьОстатки(Отказ);
КонецПроцедурыПроцедура ПроверитьОстатки(Отказ)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Товар КАК Товар,
| Остатки.КоличествоОстаток КАК Остаток
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки(&Момент, Склад = &Склад) КАК Остатки
|ГДЕ
| Остатки.КоличествоОстаток < 0";
Запрос.УстановитьПараметр("Момент", Новый Граница(МоментВремени(), ВидГраницы.Включая));
Запрос.УстановитьПараметр("Склад", Склад);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(СтрШаблон("Товара %1 не хватает: %2", Выборка.Товар, -Выборка.Остаток));
Отказ = Истина;
КонецЦикла;
КонецПроцедурыНовый Граница(…, ВидГраницы.Включая) includes the document's own records in the balance. We will study the query language in detail in the next module.Object module, manager module and event subscriptions
| Where | What goes there | Example |
|---|---|---|
| Object module | events of one particular object | ОбработкаПроведения, ПередЗаписью, ОбработкаПроверкиЗаполнения, ОбработкаЗаполнения |
| Manager module | export functions for the whole type | Документы.РасходТовара.ПечатнаяФорма(Ссылка) |
| Event subscription | one handler for many objects | checking the date in all documents |
An event subscription (Общие › Подписки на события) is set up with three properties: Источник (Source — which objects), Событие (Event, for example ПередЗаписью) and Обработчик (Handler) — an export procedure in a server common module. It lets you extend the behaviour of a typical configuration's objects without touching their modules.
// Общий модуль ПроверкиДокументов (флаг «Сервер»)
Процедура ПроверитьДатуПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат; // при загрузке из обмена проверки не выполняем
КонецЕсли;
Если Источник.Дата > КонецДня(ТекущаяДатаСеанса()) Тогда
Сообщить("Нельзя записать документ будущей датой");
Отказ = Истина;
КонецЕсли;
КонецПроцедурыПередЗаписью (BeforeWrite) event. The ОбменДанными.Загрузка check is the standard way to skip checks during data exchange.Key points
- Posting runs in a transaction:
ОбработкаПроведенияfills the records,Отказ = Истинаcancels everything. - Record sets with
Записывать = Истинаreplace the document's old records. - New method: write the records → check for negative balances with one query on the
Остаткиvirtual table. - Object module — events of one object; manager module — functions for the whole type.
- Event subscriptions extend behaviour without touching the objects' modules.
Check yourself
10 questions. Every correct answer earns XP.