Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования (Linus Torvalds).
Содержание
- Страницы
- понедельник, 20 января 2014 г.
- Что конкретно будем рассматривать
- Схема проведения документа
- 1. Инициализация дополнительных свойств для проведения
- 2. Заполнение дополнительных свойств для проведения
- 3. Подготовка наборов записей документа к записи движений
- 4. Заполнение движений наборами записей
- 5. Запись движений документа
- 6. Контроль отрицательных остатков
- 7. Очистка дополнительных свойств для проведения
- 8. Дополнительные действия проведения
- Заключение
- Об авторе
- PDF-версия статьи для участников группы ВКонтакте
Страницы
понедельник, 20 января 2014 г.
Новая методика проведения документа в 1С 8.2
Процедура ОбработкаПроведения ( Отказ , Режим )
// Формирование движений регистров накопления ТоварныеЗапасы и Продажи.
Движения . ТоварныеЗапасы . Записывать = Истина;
Если Режим = РежимПроведенияДокумента . Оперативный Тогда
Движения . ТоварныеЗапасы . БлокироватьДляИзменения = Истина;
КонецЕсли;
// Создадим запрос, чтобы получать информацию об услугах
Запрос = Новый Запрос ( "ВЫБРАТЬ
| ТоварыВДокументе.НомерСтроки КАК НомерСтроки
|ИЗ
| Документ.РасходТовара.Товары КАК ТоварыВДокументе
|ГДЕ
| ТоварыВДокументе.Ссылка = &Ссылка
| И ТоварыВДокументе.Товар.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)" );
Запрос . УстановитьПараметр ( "Ссылка" , Ссылка );
РезультатУслуги = Запрос . Выполнить (). Выгрузить ();
РезультатУслуги . Индексы . Добавить ( "НомерСтроки" );
Для каждого ТекСтрокаТовары Из Товары Цикл
Строка = РезультатУслуги . Найти ( ТекСтрокаТовары . НомерСтроки , "НомерСтроки" );
Если Строка = Неопределено Тогда
// ** 1 — формируем набор записей, как-будто контроля остатков мы не выполняем,
// т.е. просто списываем товары без контроля
// и формируем набор записей
// Не услуга
Движение = Движения . ТоварныеЗапасы . Добавить ();
Движение . ВидДвижения = ВидДвиженияНакопления . Расход ;
Движение . Период = Дата ;
Движение . Товар = ТекСтрокаТовары . Товар ;
Движение . Склад = Склад ;
Движение . Количество = ТекСтрокаТовары . Количество ;
//** 2 — записываем этот набор в БД
//Запишем движения
Движения . Записать ();
//Контроль остатков при оперативном проведении
Если Режим = РежимПроведенияДокумента . Оперативный Тогда
//** 3 — и только после этого выбираем запросом актуальные остатки, и только отрицательные
// таким образом мы определяем какого товара у нас не хватает
// Создадим запрос, чтобы контролировать остатки по товарам
Запрос = Новый Запрос ( "ВЫБРАТЬ
| ТоварыВДокументе.Товар КАК Товар,
| СУММА(ТоварыВДокументе.Количество) КАК Количество,
| МАКСИМУМ(ТоварыВДокументе.НомерСтроки) КАК НомерСтроки
|
|ПОМЕСТИТЬ ТребуетсяТовара
|
|ИЗ
| Документ.РасходТовара.Товары КАК ТоварыВДокументе
|
|ГДЕ
| ТоварыВДокументе.Ссылка = &Ссылка
| И ТоварыВДокументе.Товар.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Товар)
|
|СГРУППИРОВАТЬ ПО
| ТоварыВДокументе.Товар
|
|ИНДЕКСИРОВАТЬ ПО
| Товар
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПРЕДСТАВЛЕНИЕ(ТребуетсяТовара.Товар) КАК ТоварПредставление,
| ВЫБОР
| КОГДА — ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0) > ТоварыВДокументе.Количество
| ТОГДА ТоварыВДокументе.Количество
| ИНАЧЕ — ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
| КОНЕЦ КАК Нехватка,
| ТоварыВДокументе.Количество — ВЫБОР
| КОГДА — ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0) > ТоварыВДокументе.Количество
| ТОГДА ТоварыВДокументе.Количество
| ИНАЧЕ — ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
| КОНЕЦ КАК МаксимальноеКоличество,
| ТребуетсяТовара.НомерСтроки КАК НомерСтроки
|
|ИЗ
| ТребуетсяТовара КАК ТребуетсяТовара
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварныеЗапасы.Остатки(
| ,
| Товар В
| (ВЫБРАТЬ
| ТребуетсяТовара.Товар
| ИЗ
| ТребуетсяТовара)
| И Склад = &Склад) КАК ТоварныеЗапасыОстатки
| ПО ТребуетсяТовара.Товар = ТоварныеЗапасыОстатки.Товар
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходТовара.Товары КАК ТоварыВДокументе
| ПО ТребуетсяТовара.Товар = ТоварыВДокументе.Товар
| И ТребуетсяТовара.НомерСтроки = ТоварыВДокументе.НомерСтроки
|
|ГДЕ
| ТоварыВДокументе.Ссылка = &Ссылка И
| 0 > ЕСТЬNULL(ТоварныеЗапасыОстатки.КоличествоОстаток, 0)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки" );
Запрос . УстановитьПараметр ( "Склад" , Склад );
Запрос . УстановитьПараметр ( "Ссылка" , Ссылка );
РезультатСНехваткой = Запрос . Выполнить ();
ВыборкаРезультатаСНехваткой = РезультатСНехваткой . Выбрать ();
//** 4 — если у нас есть строки, которые ушли в минус, то выдаем сообщения пользователю
// Выдадим ошибки для строк, в которых не хватает остатка
Пока ВыборкаРезультатаСНехваткой . Следующий () Цикл
Сообщение = Новый СообщениеПользователю ();
Сообщение . Текст = НСтр ( "ru = ‘Не хватает ‘" , "ru" )
+ ВыборкаРезультатаСНехваткой . Нехватка
+ НСтр ( "ru = ‘ единиц товара’" , "ru" ) + """"
+ ВыборкаРезультатаСНехваткой . ТоварПредставление
+ """"
+ НСтр ( "ru = ‘ на складе’" , "ru" )
+ """"
+ Склад
+ """."
+ НСтр ( "ru = ‘Максимальное количество: ‘" , "ru" )
+ ВыборкаРезультатаСНехваткой . МаксимальноеКоличество
+ "." ;
Сообщение . Поле = НСтр ( "ru = ‘Товары’" , "ru" )
+ "["
+ ( ВыборкаРезультатаСНехваткой . НомерСтроки — 1 )
+ "]."
+ НСтр ( "ru = ‘Количество’" , "ru" );
Сообщение . УстановитьДанные ( ЭтотОбъект );
Сообщение . Сообщить ();
//** 5 — соответственно отказываемся от проведения
Отказ = Истина;
Вот такие преимущества у новой методики проведения.
В этой статье мы разберем схему проведения документа по регистрам в типовых конфигурациях УТ 11, КА 2 и ERP 2.
Для чего это нужно?
- Доработка проведения документов по существующим и новым регистрам встречается на любом серьезном проекте.
- Другой тип задач – разобраться, почему документ формирует те или иные движения.
Нередко в документации написано одно, а по факту всё работает иначе. И приходится уходить в отладку, разбираться с общими модулями и стеком из десятка вложенных вызовов.
Что конкретно будем рассматривать
Мы разберем алгоритмы типовых конфигураций – и научимся быстро отлаживать и дорабатывать универсальные механизмы проведения документов тиражных решений фирмы 1С.
В результате Вы будете знать ответы на вопросы:
- Где находятся алгоритмы формирования движений?
- Как изменить типовое проведение документа?
- Как адаптировать документ для движений по собственному регистру?
Для ответа на поставленные вопросы, без «длительного копания в тоннах типового кода» и быстрого получения результата, необходимо знать схему проведения документа.
А что самое приятное – почти все типовые документы проводятся по одинаковой схеме, неважно, реализация это, приходный кассовый ордер или план закупок.
Поэтому, изучив общую схему, Вы сможете доработать любой документ. 🙂
Схема проведения документа
Укрупненно проведение документа происходит в два этапа, первый этап – подготовка и запись данных, второй этап – контроль отрицательных остатков.
Можно сделать вывод, что в схеме проведения документа используется новая методика контроля остатков, когда сначала формируются движения, а затем проверяется допустимость сформированных движений.
Дополнительно о методиках контроля остатков можно прочитать в другой нашей статье: https://курсы-по-1с.рф/articles/2017-02-12-two-methods-for-inventory-check/
Театр начинается с вешалки, а проведение документа – с процедуры ОбработкаПроведения() модуля объекта. Порядок действий в обработке проведения документа можно представить в виде следующей схемы:
Рассмотрим детально каждую точку алгоритма проведения на примере документа «Реализация товаров и услуг».
1. Инициализация дополнительных свойств для проведения
Вызывается процедура ИнициализироватьДополнительныеСвойстваДляПроведения() общего модуля ПроведениеСервер, в процедуру кроме ссылки и режима проведения передаются ДополнительныеСвойства.
ДополнительныеСвойства – свойство объекта документ, структура, которая может хранить некоторые значения, связанные с объектом, без изменения объекта.
Свойство доступно для изменения не только в обработке проведения, но и прочих обработчиках модуля объекта, и это свойство доступно, пока существует объект. Например, можно в обработчике перед записью поместить в это свойство некоторые данные и затем воспользоваться ими в обработке проведения.
В вызываемой процедуре инициализируются общие для всех документов структуры (ДляПроведения и ТаблицыДляДвижений), используемые при проведении документов.
Один из ключей ТаблицыДляДвижений – структура, которая будет содержать таблицы значений с данными для выполнения движений, или, проще говоря, готовые наборы движений документа.
2. Заполнение дополнительных свойств для проведения
Заполнение дополнительных свойств, сформированных на предыдущем шаге, – ключевая точка схемы проведения документа, именно на этом этапе формируются будущие наборы записей регистров и помещаются в ключ структуры ТаблицыДляДвижений.
Вызывается процедура ИнициализироватьДанныеДокумента() модуля менеджера объекта, в процедуру передается ссылка на объект и ДополнительныеСвойства.
После завершения работы процедуры каждый ключ структуры ТаблицыДляДвижений содержит таблицу значений с будущими движениями регистра.
Обратите внимание, что ключи структуры названы по шаблону Таблица[Вт][ИмяРегистраДляДвижения], где Вт – признак временной таблицы, а ИмяРегистраДляДвижения – наименование регистра, куда будут записаны движения из таблицы значений.
Процедура инициализации – это несколько шагов, каждый из которых требует рассмотрения.
Рассмотрим детально, что происходит в модуле менеджера объекта при вызове процедуры инициализации.
2.1. Заполнение параметров запроса
Создается объект запрос и формируются параметры будущего запроса по полученной ссылке на документ. Все параметры запроса, которые пригодятся для исполнения текста запроса, устанавливаются методом УстановитьПараметр().
2.2. Формирование текстов запросов
Создается список значений ТекстыЗапроса, который будет содержать тексты запроса. Для каждого регистра, по которому требуется сформировать движения, вызывается процедура ТекстЗапросаТаблица[ИмяРегистраДляДвижения], где ИмяРегистраДляДвижения – наименование регистра, для которого формируется таблица движений. Текст запроса добавляется в список значений ТекстыЗапроса.
Вот и ответ на вопрос: «Где находятся алгоритмы формирования движений?».
Именно в процедуре ТекстЗапросаТаблица[ИмяРегистраДляДвижения] содержится текст запроса, на основании которого будут сформированы движения документа в конкретный регистр учетной системы.
2.3. Получение результата запроса
Список значений ТекстыЗапроса передается в процедуру ИнициализироватьТаблицыДляДвижений() общего модуля ПроведениеСервер, в процедуре производится компоновка общего текста пакетного запроса по данным списка значений и его выполнение. Затем процедура выгружает результаты запроса в таблицы значений, в свойство ТаблицыДляДвижений, рассмотренное на первом шаге.
3. Подготовка наборов записей документа к записи движений
Будущие движения сформированы и уже хранятся в структуре ДополнительныеСвойства, теперь требуется подготовить регистры к записи. Процедура взводит флаг записи у наборов записей, по которым документ имеет движения, при этом контролируются ИсключаемыеРегистры – регистры, движения по которым формируются не из модуля менеджера документа.
Например, документ реализации формирует движения по регистру «РасчетыСКлиентамиПоДокументам», но не в момент проведения, а в дальнейшем, при помощи регламентного задания, следовательно, регистр «РасчетыСКлиентамиПоДокументам» будет помещен в исключаемые и флагу записи останется присвоенное значение «Ложь».
4. Заполнение движений наборами записей
На этом этапе для каждого регистра таблицы значений с движениями выгружаются из дополнительных свойств в наборы записей регистров. Загрузка движений по каждому из регистров производится по одинаковому алгоритму, таблица движений из дополнительных свойств загружается в движения регистра.
Результаты ранее выполненных запросов перенесены из таблиц значений в движения. Осталось только записать движения документа – рассмотрим это на следующем шаге.
5. Запись движений документа
Процедура формирует дополнительные параметры, которые будут доступны в модуле набора записей регистра (подготовка к процедуре контроля), а также выполняет запись движений. Движения записываются в единой последовательности, обеспечивается это тем, что производится запись сразу всей коллекции движений в рамках одной транзакции.
Такой подход к записи движений устраняет возможные взаимоблокировки в информационной базе, так как ресурсы в транзакции имеют одинаковый порядок захвата.
6. Контроль отрицательных остатков
Движения записаны, настало время проверки результатов проведения.
Вызывается процедура СформироватьСписокРегистровДляКонтроля(), свойства объекта дополняются массивом РегистрыДляКонтроля. По каждому из регистров, находящихся в массиве, будет проведен контроль, за контроль отвечает процедура общего модуля:
В случае выявления несоответствий флаг Отказ будет возведен в «Истину» и проведение документа будет завершено с соответствующим диагностическим сообщением.
7. Очистка дополнительных свойств для проведения
Если на предыдущем шаге система не отказала в проведении, тогда выполняется закрытие менеджера временных таблиц в структуре дополнительных свойств документа, используемых при проведении. Сформированные и использованные ранее временные таблицы удаляются, т.к. документ уже практически проведен и нет смысла хранить избыточные данные.
8. Дополнительные действия проведения
Завершающий этап обработки проведения документа. Выполняются дополнительные действия, связанные с объектом, и эти действия должны быть неразрывно связаны с моментом проведения документа, т.е. выполнены в транзакции проведения. Например, для документа реализации это актуализация счета-фактуры (приведение состояния счета-фактуры в соответствие с документом-основанием) и регистрация документа продажи, если по нему необходим счет-фактура.
Документ реализации является сложным случаем и имеет дополнительные действия. В простом случае проведения дополнительных действий может и не быть.
Заключение
В статье рассмотрена схема проведения документа по регистрам учета в типовых конфигурациях УТ 11, КА 2 и ERP 2. Подведем краткие итоги:
Алгоритм формирования движений содержится в тексте запроса, который расположен в функции ТекстЗапросаТаблица[ИмяРегистраДляДвижения] модуля менеджера объекта.
Требуется разработать свой текст запроса и поместить его вместо существующего в функцию ТекстЗапросаТаблица[ИмяРегистраДляДвижения] модуля менеджера объекта.
Такое решение подходит, если есть возможность изменять конфигурацию или использовать расширение конфигурации. В случае невозможности изменения конфигурации или использования расширений возможно реализовать функционал проведения через подписку на событие.
Требуется разработать текст запроса, формирующий движения, и поместить его в новую, нами созданную, функцию ТекстЗапросаТаблица[ИмяСвоегоНовогоРегистра] модуля менеджера объекта.
В модуле объекта добавить вызов процедуры Отразить[ИмяСвоегоНовогоРегистра] в обработке проведения документа. Текст процедуры формируется по аналогии с типовыми процедурами.
Рассмотрим эмпирическую задачу: нам требуется провести документ реализации только по одному регистру накопления, например, «Свободные остатки». Достаточно создать внешнюю обработку и разместить в ней следующий программный код:
Эта тема детально раскрыта в курсе:
Поддержка – 3 месяца. Объем курса – 32 часа видеоуроков.
Об авторе
Автор статьи – Вячеслав Вязигин
Skype: vvyazigin
PDF-версия статьи для участников группы ВКонтакте
Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.
24 комментариев для “ Схема проведения документов в типовых конфигурациях УТ 11, ERP 2 и КА 2 ”
Помогите пожалуйста с реализацией задачи. Необходимо реализовать создание Заказа клиента на основании документа Плана продаж, при этом заказать можно только ту номенклатуру, которая есть в Плане продаж и количество в Заказе не должно превышать количества в Плане продаж. И еще присутствует такая особенность, у каждой номенклатуры есть основная номенклатура, у разной номенклатуры может быть одинаковая основная номенклатура. В Заказе клиента (созданного на основании Плана продаж) необходимо реализовать возможность заменять номенклатуру на ту у которой одинаковая основная номенклатура, при этом должен так же работать контроль количества, т.е. нельзя заказать больше чем указано в плане продаж. Вопрос в том как это все правильно реализовать? Для контроля остатков лучше наверное создать регистр накопления, но из каких измерений должен состоять этот регистр и какую номенклатуру в этот регистр писать, брать основную номенклатуру или как в табличной части записывать набор?
Добрый день!
Создайте регистр накопления остатков, в качестве измерения возьмите номенклатуру (тип данных же одинаковый у исходной номенклатуры и основной). В качестве регистраторов укажите документ План продаж и Заказ клиента. Вы приход количества будете регистрировать не по основной номенклатуре, а по исходной номенклатуре из ТЧ документа План продаж, значит Расход – по исходной номенклатуре ТЧ документа Заказ клиента (сгруппируйте данные по номенклатуре перед записью в регистр).
А как можно отладить запрос ВтТаблицаТовары? Если он берет данные левым соединением из других временных таблиц, видимо полученных чуть раньше?
Приемы отладки запроса в механизмах проведения ничем не отличаются от прочих моментов. На нашем ресурсе есть замечательная статья, которая Вам поможет https://xn—-1-bedvffifm4g.xn--p1ai/articles/2017-09-07-4-methods-of-query-debugging/
Добрый день!
Как вывести сумму а регистре накопления, добавлял несколько реквизитов в регистре “РасчетСебестоимости, ХозяйственнаяОперация, ДокументДвижения”, но не помогло расчетом суммы ?
Не совсем понятно откуда и куда Вы хотите вывести сумму, уточните вопрос.
Здравствуйте!
УТ11 + CRM.
Хочу добавить движения документа “Чек ККМ” в Регистры “Расчеты с клиентами” и “Расчеты с клиентами по документам”.
По Вашей статье сделал, что записи в первый регистр записываются.
А вот как делаются записи в другой регистр, например, Приходным кассовым ордером – не нашел.
Если делать принудительно (по аналогии с первым регистром), то записи делаются без заполнения поля “Расчетный документ”.
Помогите разобраться, пожалуйста.
Решил. Все дело было в Определяемом типе Измерения регистра.
Еще раз спасибо за статью.
Здравствуйте. Спасибо за статью ! Не подскажете – по такому же алгоритму можно делать движения в регистрах, с независимым режимом записи (не подчиненным никакому регистратору) ? А также – как делать отмену проведения по таким регистрам ? Предусмотрены ли для этого механизмы в общих модулях ?
Да, таким же образом можно формировать движения в регистрах без регистратора, никаких ограничений платформа на этот счет не накладывает.
Для отмены проведения Вам понадобится скорректировать процедуру ОбработкаУдаленияПроведения() с собственным алгоритмом очистки движений, т.к. типовые механизмы опираются на коллекцию движений объекта, которая ничего не знает о движениях в независимом регистре.
Здравствуйте. Статья отличная, но не раскрыта тема доработки проведения через подписки на события. В частности я планировал добавить в документ реализация дополнительные движения по регистру РасчетыСКлиентами. В подписке ОбработкаПроведения я получил данные, добавил из в набор записей регистра, все как по нотам, но эти записи, в итоге, не записываются. Вот пример кода:
ТаблицаРасчеты = З.Выполнить().Выгрузить();
Если Отказ ИЛИ ТаблицаРасчеты.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для каждого Стр Из ТаблицаРасчеты Цикл
Если Стр.ВидДвижения = ВидДвиженияНакопления.Приход Тогда
СтрДвижений = ДвиженияРасчеты.ДобавитьПриход();
ИначеЕсли Стр.ВидДвижения = ВидДвиженияНакопления.Расход Тогда
СтрДвижений = ДвиженияРасчеты.ДобавитьРасход();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрДвижений,Стр);
КонецЦикла;
после чего выдается ошибка в процедуре ПередЗаписью в модуле НабораЗаписейРегистра…
…
Не установлен менеджер временных таблиц
По представленной Вами информации невозможно диагностировать по какой причине происходит ошибка исполнения кода, очень мало данных.
Тема адаптации конфигурации, в том числе механизмов проведения, очень подробно раскрыта в материалах курса, все уместить в статью невозможно 🙂
Когда обрабатываются тексты для получения данных по запросам они объединяются в пакетный запрос, потом идет выполнение пакета. Поэтому запросы с временными таблицами для формирования регистра использовать нельзя, иначе номер запроса в пакете не будет совпадать с фактическим.
Ваше утверждение на сегодняшний день некорректно. Обращение к результатам запроса по номерам присутствовало в старой редакции УТ.
На сегодняшний день обработка пакетного запроса идет не по индексу, а по текстовому представлению (имени регистра). Использование временных таблиц допустимо и широко применяется на практике.
// Процедура компонует текст запроса, выполняет запрос и выгружает результаты запроса в таблицы.
//
// Параметры:
// Запрос — Запрос — запрос, параметры которого предварительно установлены.
// ТекстыЗапроса — СписокЗначений — в списке перечислены тексты запросов и их имена.
// Таблицы — Структура — структура в которую будут помещены полученные таблицы для движений.
// ДобавитьРазделитель — Булево — Истина, если нужно добавить разделитель ";" между запросами.
// ДобавлятьСловоТаблица — Булево — Истина, если к имени таблицы движений нужно вначало добавить слово "Таблица".
// ТолькоОтмеченные — Булево — признак пропуска инициализации таблицы движения.
//
Процедура ИницализироватьТаблицыДляДвижений(Запрос, ТекстыЗапроса, Таблицы, ДобавитьРазделитель = Ложь, ДобавлятьСловоТаблица = Истина, ТолькоОтмеченные = Ложь) Экспорт
ТаблицыЗапроса = ОбщегоНазначенияУТ.ВыгрузитьРезультатыЗапроса(Запрос, ТекстыЗапроса,, ДобавитьРазделитель);
// Помещение результатов запроса в таблицы
Для Каждого ТекстЗапроса из ТекстыЗапроса Цикл
Если Не ПустаяСтрока(ИмяТаблицы) И (Не ТолькоОтмеченные Или ТекстЗапроса.Пометка) Тогда
Если ДобавлятьСловоТаблица Тогда
// Таблицы для проведения должны начинаться с "Таблица"
Если НЕ СтрНачинаетсяС(ИмяТаблицы, "Таблица") Тогда
ИмяТаблицы = "Таблица" + ИмяТаблицы;
КонецЕсли;
КонецЕсли;
Алгоритм проведения документа с учетом подписок на события
Если посмотреть свойства документа через палитру свойств, то можно увидеть два важных свойства: "Удаление движений" и "Запись движений при проведении", причем второе НЕ вынесено на закладку "Движения" окна редактирования документа.
1. Удаление движений.
Если свойство "Удаление движений" уставновлено в "Удалять автоматически", то ПЕРЕД началом проведения программа очищает все движения по регистрам. Фактически это означает запись пустого набора записей регистра с видом записи — замещение. А значит, программа выполняет код из процедур "ПередЗаписью" и "ПриЗаписи" модуля набора записей регистров.
Если для какого-либо регистра определена подписка на событие "При записи", то выполняется код из связанной процедуры.
2. Процедура "ОбработкаПроведения" модуля документа.
Обратим внимание: в начале обработки проведения у всех движений флаг модифицированности Ложь (значение возвращает метод Движения.Регистр.Модифицированность() ).
При работе с набором записей регистра (например, Движения.Регистр.Очистить() , Движения.Регистр.Добавить() и т.д.) флаг модифицированности становится Истина.
После записи движения в базу Движения.Регистр.Записать() модифицированность снова ложь.
Если в модуле процедуры подписки происходит запись набора регистра в явном виде ( .Записать() ), то программа выполняет код из процедур "ПередЗаписью" и "ПриЗаписи" модуля набора записей регистров и процедуры из подписки на событие "При записи" регистра.
3. Подписки на событие "При проведении" документа
Важно понимать : если в обработке проведения документа или в подписках на событие, вызванных ранее, не происходила запись движений регистров в явном виде (Движения.Регистр.Записать()), то движения документа еще НЕ записаны в базу. Поэтому их нельзя получить с помощью запроса, но можно получить из коллекции движений источника.
Очередность подписок на одно и то же событие явным образом не определяется 1С, но на практике подписки вызываются в порядке следования в ветке "Подписки на события" окна редактирования конфигурации.
Если регистры записываются с помощь метода Записать () , то выполняются все связанные процедуры.
4. Запись движений.
Вспомним про свойство "Запись движений при проведении" из настроек документа.
Если оно равно "Записывать модифицированные", то в базу будут записаны все движения документа, у которых флаг "Модифицированность" Истина.
Если оно равно "Записывать выбранные", то в базу будут записаны движения регистров, для которых мы явным образом указали необходимость записи.
Запись движений в базу происходит с режимом замещения Истина . Это означает, что будут записаны записи из текущего набора записей регистра коллекции Движения и очищены предыдущие записи.
И в конце р ассмотрим несколько примеров:
Пусть свойство документа "Запись движений при проведении" равно "Записывать модифицированные", а "Удаление движений" — "Не удалять автоматически".
При такой процедуре проведения документ при каждом перепроведении будет добавлять запись в регистр, записи будут множиться. Т.к. строка //*** добавляет записи в регистр, признак Модифицированности снимается.
Правильнее будет написать строку //*** как
или вообще ее опустить, и тогда программа сама запишет модифицированные движения.
В 1С 8 движения документа могут формироваться не только в обработке проведения, но и извне, например, из некоторой служебной обработки (так реализовано допроведение документов, восстановление авансов и т.д.).
В этом случае при перепроведении документа, если происходит изменение движений регистра бухгалтерии (флаг Модифицированности Истина), записи будут замещены записями, сформированными документом.
Перед началом проведения документа все реквизиты документа записываются в базу данных (т.е. программист может их получить с помощью запроса). Во внутренней памяти создается Объект документа, и у этого объекта есть коллекция движений, которая будет записана после окончания процедуры проведения (см. этап 4).
Если в процессе проведения документа движения по регистрам формируются не с помощью коллекции Движения, принадлежащей внутреннему объекту , а другими способами (вручную в форме набора записей или как в примере 2 и т.д.), то на этапе 4 эти записи будут замещены. Чтобы избежать замещения в типовых базах, для документа "ОперацияБух" свойство документа "Проведение" устанавливается в "Запретить".
Если документ должен проводиться по другим регистрам и нельзя запретить проведение, тогда нужно внимательно настраивать свойства документа:
— выбрать вариант записи движений "Записывать выбранные" и убедиться, что Движения.Регистр.Записывать = Ложь
— выбрать вариант записи движений "Записывать модифицированные" и контролировать признак Модифицированности для набора записей этого регистра.
Нужно понимать, что объект, полученный по ссылке (назовем его "ОбъектДок"), и внутренний объект ("ЭтотОбъект"), созданный в памяти в момент проведения, это два разных экземляра объектов.
Соответственно и коллекции движений у них будут разные. У "ОбъектаДок" коллекция движений будет включать только записанный в базу набор записей регистра, а у "ЭтогоОбъекта" — как записанные, так и добавленные и незаписанные записи. По окончании проведения (этап 4) в базу будут записаны наборы записей "ЭтогоОбъекта", причем с признаком Замещать = Истина.
Если записи в набор записей добавляются по способу, описанному выше, то они могут быть замещены на этапе 4.