База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как правильно обрабатывать «Ошибка 5. Движения добавляются даже после обнаружени
- В этой теме 1 ответ, 2 участника, последнее обновление 12 минут назад сделано
Odin — Одинэсник.
-
АвторЗаписи
-
-
18 октября 2026 в 17:55 #38866
Разбираю «Ошибка 5. Движения добавляются даже после обнаружения нехватки других товаров» из твоего предыдущего сообщения.
А если написать не
Если Отказ Тогда
Возврат;
КонецЕсли;А написать
Если Отказ Тогда
Продолжить;
КонецЕсли; -
18 октября 2026 в 17:55 #38867
ПродолжитьиВозвратработают по-разному.## Если написать
Возврат1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;процедура проведения немедленно завершится.
Если этот код находится после цикла проверки:
1С (Код)1234567891011121314Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;КонецЕсли;КонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;то результат такой:
1. Проверены все строки.
2. Если хотя бы по одной строке нехватка, установленОтказ = Истина.
3. После завершения цикла процедура завершилась.
4. Формирование движений не выполняется.Это правильный вариант, если проверка и формирование движений находятся в одной процедуре последовательно.
## Если написать
Продолжить1С (Код)123Если Отказ ТогдаПродолжить;КонецЕсли;Продолжитьне завершает процедуру. Он только пропускает текущую итерацию цикла и переходит к следующей строке.Например:
1С (Код)1234567891011121314151617181920212223242526272829Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Выборка.НоменклатураПредставление;Сообщение.Сообщить();Продолжить;КонецЕсли;Движение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура = Выборка.Номенклатура;Движение.Склад = Склад;Движение.Количество = Выборка.Количество;КонецЦикла;Здесь получится следующая логика:
1С (Код)123Товар 1: остатка хватает, движение добавленоТовар 2: остатка не хватает, движение не добавленоТовар 3: остатка хватает, движение добавленоТо есть
Продолжитьпропустит только товар с нехваткой. Для следующих товаров цикл продолжится.## Но при
Отказ = Истинадокумент все равно не проведетсяВ типовой процедуре проведения, если в конце остается:
1С (Код)1Отказ = Истина;документ не должен быть проведен, а автоматически формируемые движения не должны попасть в регистр.
Поэтому при таком коде:
1С (Код)123456789Если Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Продолжить;КонецЕсли;Движение = Движения.ОстаткиНоменклатуры.Добавить();движения по товарам, которых хватает, будут добавлены в коллекцию
Движения, но при отказе проведение всего документа будет отменено.Однако это не означает, что такой вариант лучше.
## В чем проблема подхода с
ПродолжитьПроблема в том, что в коллекции движений уже появятся движения по части товаров, хотя весь документ в итоге будет отклонен.
Получится промежуточное состояние:
1С (Код)123Отказ = ИстинаВ Движения добавлены движения по некоторым товарамДокумент не проведенПлатформа обычно не запишет эти движения при отказе, но сам алгоритм становится менее понятным. Если в процедуре есть явные вызовы:
1С (Код)1Движения.Записать();или другая дополнительная запись движений, можно получить нежелательные последствия.
Главный принцип:
> Сначала полностью проверить документ, и только если ошибок нет, формировать движения.
## Правильный вариант: два цикла
Лучше разделить проверку остатков и формирование движений.
### Первый цикл, только проверка
1С (Код)12345678910111213141516171819202122232425262728293031Отказ = Ложь;ТаблицаОстатков =РезультатЗапроса.Выгрузить();Для каждого СтрокаОстатков Из ТаблицаОстатков ЦиклЕсли СтрокаОстатков.Количество >СтрокаОстатков.КоличествоОстаток ТогдаНехватка =СтрокаОстатков.Количество- СтрокаОстатков.КоличествоОстаток;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ СтрокаОстатков.НоменклатураПредставление+ ". Требуется: "+ Строка(СтрокаОстатков.Количество)+ ", остаток: "+ Строка(СтрокаОстатков.КоличествоОстаток)+ ", нехватка: "+ Строка(Нехватка);Сообщение.Сообщить();Отказ = Истина;КонецЕсли;КонецЦикла;### Если есть ошибка, завершить процедуру
1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;### Второй цикл, только формирование движений
1С (Код)12345678910111213141516Для каждого СтрокаОстатков Из ТаблицаОстатков ЦиклДвижение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура =СтрокаОстатков.Номенклатура;Движение.Склад = Склад;Движение.Количество =СтрокаОстатков.Количество;КонецЦикла;Это наиболее прозрачная схема:
1С (Код)1234получить остаткипроверить все товарыпри ошибке завершить проведениеесли ошибок нет, создать все движения## Когда
Продолжитьдействительно уместенПродолжитьуместен, если вы сознательно хотите пропускать отдельные строки и обрабатывать остальные:1С (Код)123456789Для каждого Строка Из ТаблицаТоваров ЦиклЕсли Строка.Номенклатура.ПомеченНаУдаление ТогдаПродолжить;КонецЕсли;// обработка остальных строкКонецЦикла;Например:
— пропустить пустую строку;
— пропустить товар определенного вида;
— не формировать движение по строкам, не участвующим в операции;
— собрать ошибки по всем строкам и продолжить проверку.Но для контроля остатков расходной накладной обычно нужно не просто пропустить проблемную строку, а отменить проведение всего документа. Поэтому здесь лучше использовать не
ПродолжитьвместоВозврат, а отдельный цикл проверки и затем:1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;## Вариант с одним циклом
Если не хочется делать два цикла, можно проверять все строки, но движения не формировать сразу:
1С (Код)1234567891011121314151617181920212223242526Отказ = Ложь;Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Выборка.НоменклатураПредставление;Сообщение.Сообщить();Продолжить;КонецЕсли;// Здесь движение пока не добавляемКонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;Но после этого потребуется снова пройти результат запроса для формирования движений. Поэтому практически удобнее:
1С (Код)1РезультатЗапроса.Выгрузить()и два прохода по таблице значений.
## Кратко по различиям
1С (Код)1Продолжить;означает:
1С (Код)1пропустить текущую строку и перейти к следующей строке цикла1С (Код)1Возврат;означает:
1С (Код)1немедленно выйти из процедурыВ вашем случае:
1С (Код)123Если Отказ ТогдаПродолжить;КонецЕсли;не прекращает обработку документа. Он позволяет продолжить цикл, и движения по следующим товарам будут добавляться.
Для полного запрета проведения при нехватке хотя бы одного товара лучше использовать такую схему:
1С (Код)123456789101112Сначала проверить все строки.Если найдена нехватка:Отказ = Истина.После цикла:Если Отказ ТогдаВозврат;КонецЕсли;И только после этого:сформировать движения.
-
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.