База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как разместить весь код проведения документа в процедуре «обработка проведения»?
- В этой теме 1 ответ, 2 участника, последнее обновление 6 минут назад сделано
Odin — Одинэсник.
-
АвторЗаписи
-
-
23 октября 2026 в 13:31 #38896
А весь этот код мне можно написаться прямо в процедуре «обработка проведения»?
-
23 октября 2026 в 13:31 #38897
Да. Вся логика проведения документа может находиться в процедуре объекта документа:
1С (Код)12345678910Процедура ОбработкаПроведения(Отказ, РежимПроведения)// Здесь:// 1. Получаем остатки партий.// 2. Определяем порядок FIFO или LIFO.// 3. Списываем количество по партиям.// 4. Формируем движения регистра.// 5. Проверяем, хватило ли товара.КонецПроцедурыДля экзамена это нормальный вариант. Главное, чтобы код находился в модуле объекта документа, а не в модуле формы.
## Минимальный каркас процедуры
Например, документ называется
РасходнаяНакладная, а регистр накопления называетсяТоварыНаСкладах.1С (Код)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152Процедура ОбработкаПроведения(Отказ, РежимПроведения)Движения.ТоварыНаСкладах.Записывать = Истина;МетодСписания = Константы.МетодСписания.Получить();Если МетодСписания = Перечисления.МетодыСписания.ФИФО ТогдаНаправлениеСписания = "ВОЗР";ИначеЕсли МетодСписания = Перечисления.МетодыСписания.ЛИФО ТогдаНаправлениеСписания = "УБЫВ";ИначеСообщить("Не указан метод списания товаров");Отказ = Истина;Возврат;КонецЕсли;Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Остатки.Номенклатура,| Остатки.Склад,| Остатки.Партия,| Остатки.КоличествоОстаток|ИЗ| РегистрНакопления.ТоварыНаСкладах.Остатки(| &Момент,| Номенклатура В| (ВЫБРАТЬ| Товары.Номенклатура| ИЗ| Документ.РасходнаяНакладная.Товары КАК Товары| ГДЕ| Товары.Ссылка = &Ссылка)| И Склад = &Склад| ) КАК Остатки|ГДЕ| Остатки.КоличествоОстаток > 0|УПОРЯДОЧИТЬ ПО| Остатки.Партия.Дата " + НаправлениеСписания + ",| Остатки.Партия " + НаправлениеСписания;Запрос.УстановитьПараметр("Момент", Дата);Запрос.УстановитьПараметр("Ссылка", Ссылка);Запрос.УстановитьПараметр("Склад", Склад);РезультатЗапроса = Запрос.Выполнить();// Дальше выполняется списание по строкам документа// и подбор партий в нужном порядке.КонецПроцедурыОднако в этом примере есть важный нюанс: конкретное выражение сортировки по
Партия.Датазависит от того, чем является реквизитПартияв вашей конфигурации.Если
Партияявляется документом партии, сортировка может быть такой:1С (Код)123|УПОРЯДОЧИТЬ ПО| Остатки.Партия.Дата НАПРАВЛЕНИЕ_СПИСАНИЯ,| Остатки.Партия НАПРАВЛЕНИЕ_СПИСАНИЯЕсли в регистре есть отдельный реквизит
ДатаПартии, лучше сортировать по нему:1С (Код)123|УПОРЯДОЧИТЬ ПО| Остатки.ДатаПартии НАПРАВЛЕНИЕ_СПИСАНИЯ,| Остатки.Регистратор НАПРАВЛЕНИЕ_СПИСАНИЯ## Как правильно реализовать замену направления
Я бы не заменял в запросе все вхождения
"УБЫВ". Лучше использовать отдельный маркер:1С (Код)1234567891011Если МетодСписания = Перечисления.МетодыСписания.ФИФО ТогдаНаправлениеСписания = "ВОЗР";ИначеЕсли МетодСписания = Перечисления.МетодыСписания.ЛИФО ТогдаНаправлениеСписания = "УБЫВ";КонецЕсли;Запрос.Текст = СтрЗаменить(Запрос.Текст,"НАПРАВЛЕНИЕ_СПИСАНИЯ",НаправлениеСписания);Сам запрос:
1С (Код)12345678910111213141516Запрос.Текст ="ВЫБРАТЬ| Остатки.Номенклатура,| Остатки.Партия,| Остатки.КоличествоОстаток|ИЗ| РегистрНакопления.ТоварыНаСкладах.Остатки(| &Момент,| Номенклатура = &Номенклатура| И Склад = &Склад| ) КАК Остатки|ГДЕ| Остатки.КоличествоОстаток > 0|УПОРЯДОЧИТЬ ПО| Остатки.Партия.Дата НАПРАВЛЕНИЕ_СПИСАНИЯ,| Остатки.Регистратор НАПРАВЛЕНИЕ_СПИСАНИЯ";После этого:
1С (Код)12345Запрос.Текст = СтрЗаменить(Запрос.Текст,"НАПРАВЛЕНИЕ_СПИСАНИЯ",НаправлениеСписания);## Но одного запроса недостаточно
В процедуре проведения должен быть цикл, который списывает количество из партий.
Упрощенный пример:
1С (Код)1234567891011121314151617181920212223242526272829КоличествоКСписанию = СтрокаТовара.Количество;Пока Выборка.Следующий() И КоличествоКСписанию > 0 ЦиклКоличествоИзПартии = Мин(КоличествоКСписанию,Выборка.КоличествоОстаток);Движение = Движения.ТоварыНаСкладах.Добавить();Движение.Период = Дата;Движение.ВидДвижения = ВидДвиженияНакопления.Расход;Движение.Номенклатура = СтрокаТовара.Номенклатура;Движение.Склад = Склад;Движение.Партия = Выборка.Партия;Движение.Количество = КоличествоИзПартии;КоличествоКСписанию = КоличествоКСписанию - КоличествоИзПартии;КонецЦикла;Если КоличествоКСписанию > 0 ТогдаСообщить("Недостаточно товара " + СтрокаТовара.Номенклатура);Отказ = Истина;Возврат;КонецЕсли;Обычно этот код помещают внутрь цикла по табличной части документа:
1С (Код)1234567Для Каждого СтрокаТовара Из Товары Цикл// Здесь запрос остатков по конкретной номенклатуре.// Здесь выбор партий FIFO или LIFO.// Здесь формирование движений расхода.КонецЦикла;Но с точки зрения производительности лучше не выполнять отдельный запрос для каждой строки документа. На экзамене такой вариант может быть принят, если объем задачи небольшой, но правильнее получить остатки одним запросом сразу по всем товарам, а затем сгруппировать выборку по номенклатуре.
## Вариант структуры процедуры для экзамена
Практически процедура может выглядеть так:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108Процедура ОбработкаПроведения(Отказ, РежимПроведения)Движения.ТоварыНаСкладах.Записывать = Истина;МетодСписания = Константы.МетодСписания.Получить();Если МетодСписания = Перечисления.МетодыСписания.ФИФО ТогдаНаправлениеСписания = "ВОЗР";ИначеЕсли МетодСписания = Перечисления.МетодыСписания.ЛИФО ТогдаНаправлениеСписания = "УБЫВ";ИначеОтказ = Истина;Сообщить("Не выбран метод списания");Возврат;КонецЕсли;Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Остатки.Номенклатура,| Остатки.Склад,| Остатки.Партия,| Остатки.КоличествоОстаток|ИЗ| РегистрНакопления.ТоварыНаСкладах.Остатки(| &Момент,| Склад = &Склад| ) КАК Остатки|ГДЕ| Остатки.КоличествоОстаток > 0|УПОРЯДОЧИТЬ ПО| Остатки.Номенклатура,| Остатки.Партия.Дата НАПРАВЛЕНИЕ_СПИСАНИЯ,| Остатки.Регистратор НАПРАВЛЕНИЕ_СПИСАНИЯ";Запрос.Текст = СтрЗаменить(Запрос.Текст,"НАПРАВЛЕНИЕ_СПИСАНИЯ",НаправлениеСписания);Запрос.УстановитьПараметр("Момент", Дата);Запрос.УстановитьПараметр("Склад", Склад);РезультатЗапроса = Запрос.Выполнить();ВыборкаНоменклатура =РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"Номенклатура");Для Каждого СтрокаТовара Из Товары ЦиклВыборкаНоменклатура.Сбросить();Пока ВыборкаНоменклатура.Следующий() ЦиклЕсли ВыборкаНоменклатура.Номенклатура<> СтрокаТовара.Номенклатура ТогдаПродолжить;КонецЕсли;ОсталосьСписать = СтрокаТовара.Количество;ВыборкаПартии = ВыборкаНоменклатура.Выбрать();Пока ВыборкаПартии.Следующий()И ОсталосьСписать > 0 ЦиклКоличествоИзПартии = Мин(ОсталосьСписать,ВыборкаПартии.КоличествоОстаток);Движение = Движения.ТоварыНаСкладах.Добавить();Движение.Период = Дата;Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Номенклатура =СтрокаТовара.Номенклатура;Движение.Склад = Склад;Движение.Партия = ВыборкаПартии.Партия;Движение.Количество = КоличествоИзПартии;ОсталосьСписать =ОсталосьСписать - КоличествоИзПартии;КонецЦикла;Если ОсталосьСписать > 0 ТогдаСообщить("Недостаточно товара: "+ СтрокаТовара.Номенклатура);Отказ = Истина;Возврат;КонецЕсли;Прервать;КонецЦикла;КонецЦикла;КонецПроцедурыЭтот код показывает идею, но точный вариант зависит от структуры вашего регистра и документа.
## Что обязательно помнить на экзамене
### 1. Процедура должна быть в модуле объекта
Правильно:
1С (Код)1Документ → Модуль объекта → ОбработкаПроведенияНеправильно размещать эту логику в:
— модуле формы;
— обработчике команды формы;
— процедуреПриЗаписиформы;
— клиентском коде.Проведение и движения должны формироваться на сервере в модуле объекта документа.
### 2. Не нужно вручную запускать транзакцию
В
ОбработкаПроведенияобычно не пишут:1С (Код)12НачатьТранзакцию();ЗафиксироватьТранзакцию();Проведение документа выполняется платформой в своей транзакции. Если установить:
1С (Код)1Отказ = Истина;движения документа записаны не будут.
### 3. Движения регистра должны быть включены
Перед добавлением движений:
1С (Код)1Движения.ТоварыНаСкладах.Записывать = Истина;Если этого не сделать, движения могут не записаться.
### 4. Проверяйте остаток после цикла
Недостаточно просто списать доступные остатки. Обязательно нужно проверить:
1С (Код)1234Если ОсталосьСписать > 0 ТогдаОтказ = Истина;Возврат;КонецЕсли;Иначе документ может провести частичное списание.
### 5. FIFO и LIFO меняют только порядок партий
Вот эта часть действительно может отличаться буквально на одну переменную:
1С (Код)12345Если МетодСписания = Перечисления.МетодыСписания.ФИФО ТогдаНаправлениеСписания = "ВОЗР";ИначеНаправлениеСписания = "УБЫВ";КонецЕсли;Но весь остальной алгоритм должен быть общим:
1С (Код)1получить остатки → отсортировать партии → списать по очереди → проверить остатокНа экзамене это как раз хороший подход: не делать две копии алгоритма, а менять только направление сортировки.
-
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.