29.03.2018 00:44
KirillHome
 
Позвонил клиент с ошибкой расчета себестоимости в 1с Розница 2.2.7.39

Сама ошибка
Цитата:
{ОбщийМодуль.ЗапасыСервер.Модуль(437)}: Ошибка при вызове метода контекста (Выполнить)
Результат = Запрос.Выполнить();
по причине:
Ошибка выполнения запроса
по причине:
Ошибка при выполнении операции над данными:
Ошибка SQL: Деление на 0
по причине:
Ошибка SQL: Деление на 0
по причине:
Деление на 0 значения типа Numeric
Посмотрел в конфигуратор.
В общем модуле ЗапасыСервер в процедуре
СформироватьУзлыКорректировкиСписанияСтоимости используется следующий запрос:
Код запроса:

Код:
ВЫБРАТЬ
	ТоварыНаСкладахОстатки.Склад.Магазин КАК Магазин,
	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
	ТоварыНаСкладахОстатки.Характеристика КАК Характеристика,
	СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК Остаток
ПОМЕСТИТЬ Остатки
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки(&НачалоПериода, ) КАК ТоварыНаСкладахОстатки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.СебестоимостьПоставкиТоваров.Обороты(&НачалоПериода, &КонецПериода, , ) КАК СебестоимостьПоставкиТоваровОбороты
		ПО ТоварыНаСкладахОстатки.Номенклатура = СебестоимостьПоставкиТоваровОбороты.Номенклатура
			И ТоварыНаСкладахОстатки.Характеристика = СебестоимостьПоставкиТоваровОбороты.Характеристика

СГРУППИРОВАТЬ ПО
	ТоварыНаСкладахОстатки.Склад.Магазин,
	ТоварыНаСкладахОстатки.Номенклатура,
	ТоварыНаСкладахОстатки.Характеристика
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ЕСТЬNULL(СебестоимостьПоставки.Магазин, СебестоимостьПеремещения.Магазин) КАК Магазин,
	ЕСТЬNULL(СебестоимостьПоставки.Номенклатура, СебестоимостьПеремещения.Номенклатура) КАК Номенклатура,
	ЕСТЬNULL(СебестоимостьПоставки.Характеристика, СебестоимостьПеремещения.Характеристика) КАК Характеристика,
	ЕСТЬNULL(СебестоимостьПеремещения.КоличествоОборот, 0) КАК КоличествоПеремещение,
	ЕСТЬNULL(СебестоимостьПоставки.КоличествоОборот, 0) + ЕСТЬNULL(СебестоимостьПеремещения.КоличествоОборот, 0) КАК Количество,
	ЕСТЬNULL(СебестоимостьПоставки.СуммаОборот, 0) + ЕСТЬNULL(СебестоимостьПеремещения.СуммаОборот, 0) КАК СуммаОборот,
	ЕСТЬNULL(ВЫБОР
			КОГДА ЕСТЬNULL(СебестоимостьПоставки.КоличествоОборот, 0) + ЕСТЬNULL(СебестоимостьПеремещения.КоличествоОборот, 0) = 0
				ТОГДА 0
			ИНАЧЕ (ЕСТЬNULL(СебестоимостьПоставки.СуммаОборот, 0) + ЕСТЬNULL(СебестоимостьПеремещения.СуммаОборот, 0)) / (ЕСТЬNULL(СебестоимостьПоставки.КоличествоОборот, 0) + ЕСТЬNULL(СебестоимостьПеремещения.КоличествоОборот, 0))
		КОНЕЦ, 0) КАК Стоимость,
	ЕСТЬNULL(СебестоимостьПеремещения.МагазинОтправитель, ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК МагазинОтправитель
ПОМЕСТИТЬ СебестоимостьПоПоступлениям
ИЗ
	(ВЫБРАТЬ
		Поставки.Магазин КАК Магазин,
		Поставки.Номенклатура КАК Номенклатура,
		Поставки.Характеристика КАК Характеристика,
		Поставки.КоличествоОборот КАК КоличествоОборот,
		Поставки.СуммаОборот КАК СуммаОборот
	ИЗ
		РегистрНакопления.СебестоимостьПоставкиТоваров.Обороты(&НачалоПериода, &КонецПериода, , МагазинОтправитель = ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК Поставки
	
	ОБЪЕДИНИТЬ
	
	ВЫБРАТЬ
		Остатки.Магазин,
		Остатки.Номенклатура,
		Остатки.Характеристика,
		Остатки.Остаток,
		ЕСТЬNULL(ВЫБОР
				КОГДА Себестоимость.Период ЕСТЬ НЕ NULL 
						И СебестоимостьПустойМагазин.Период ЕСТЬ НЕ NULL 
					ТОГДА ВЫБОР
							КОГДА Себестоимость.Период >= СебестоимостьПустойМагазин.Период
								ТОГДА Себестоимость.Цена
							ИНАЧЕ СебестоимостьПустойМагазин.Цена
						КОНЕЦ
				ИНАЧЕ ВЫБОР
						КОГДА Себестоимость.Период ЕСТЬ НЕ NULL 
							ТОГДА Себестоимость.Цена
						ИНАЧЕ СебестоимостьПустойМагазин.Цена
					КОНЕЦ
			КОНЕЦ, 0) * Остатки.Остаток
	ИЗ
		Остатки КАК Остатки
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СебестоимостьНоменклатуры.СрезПоследних(&НачалоПериода, Магазин <> ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК Себестоимость
			ПО Остатки.Магазин = Себестоимость.Магазин
				И Остатки.Номенклатура = Себестоимость.Номенклатура
				И Остатки.Характеристика = Себестоимость.Характеристика
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СебестоимостьНоменклатуры.СрезПоследних(&НачалоПериода, Магазин = ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК СебестоимостьПустойМагазин
			ПО Остатки.Номенклатура = СебестоимостьПустойМагазин.Номенклатура
				И Остатки.Характеристика = СебестоимостьПустойМагазин.Характеристика) КАК СебестоимостьПоставки
		ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
			СебестоимостьПоставкиТоваровОбороты.Магазин КАК Магазин,
			СебестоимостьПоставкиТоваровОбороты.МагазинОтправитель КАК МагазинОтправитель,
			СебестоимостьПоставкиТоваровОбороты.Номенклатура КАК Номенклатура,
			СебестоимостьПоставкиТоваровОбороты.Характеристика КАК Характеристика,
			СебестоимостьПоставкиТоваровОбороты.КоличествоОборот КАК КоличествоОборот,
			СебестоимостьПоставкиТоваровОбороты.СуммаОборот КАК СуммаОборот
		ИЗ
			РегистрНакопления.СебестоимостьПоставкиТоваров.Обороты(&НачалоПериода, &КонецПериода, , НЕ МагазинОтправитель = ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК СебестоимостьПоставкиТоваровОбороты) КАК СебестоимостьПеремещения
		ПО СебестоимостьПоставки.Номенклатура = СебестоимостьПеремещения.Номенклатура
			И СебестоимостьПоставки.Характеристика = СебестоимостьПеремещения.Характеристика
			И СебестоимостьПоставки.Магазин = СебестоимостьПеремещения.Магазин
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	СебестоимостьПоПоступлениям.Магазин КАК Магазин,
	СебестоимостьПоПоступлениям.Номенклатура КАК Номенклатура,
	СебестоимостьПоПоступлениям.Характеристика КАК Характеристика,
	СУММА(СебестоимостьПоПоступлениям.КоличествоПеремещение) КАК КоличествоПеремещение,
	СУММА(СебестоимостьПоПоступлениям.Количество) КАК Количество,
	СУММА(СебестоимостьПоПоступлениям.СуммаОборот) КАК СуммаОборот,
	СУММА(СебестоимостьПоПоступлениям.СуммаОборот) / СУММА(СебестоимостьПоПоступлениям.Количество) КАК Стоимость,
	СебестоимостьПоПоступлениям.МагазинОтправитель КАК МагазинОтправитель
ПОМЕСТИТЬ СебестоимостьПоПоступлениямСвернуто
ИЗ
	СебестоимостьПоПоступлениям КАК СебестоимостьПоПоступлениям

СГРУППИРОВАТЬ ПО
	СебестоимостьПоПоступлениям.Магазин,
	СебестоимостьПоПоступлениям.Номенклатура,
	СебестоимостьПоПоступлениям.Характеристика,
	СебестоимостьПоПоступлениям.МагазинОтправитель
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	СебестоимостьПоПоступлениям.Магазин КАК Магазин,
	СебестоимостьПоПоступлениям.Номенклатура КАК Номенклатура,
	СебестоимостьПоПоступлениям.Характеристика КАК Характеристика,
	СебестоимостьПоПоступлениям.КоличествоПеремещение КАК КоличествоПеремещение,
	СебестоимостьПоПоступлениям.Количество КАК Количество,
	СебестоимостьПоПоступлениям.СуммаОборот КАК СуммаОборот,
	СебестоимостьПоПоступлениям.Стоимость КАК Стоимость,
	ВЫБОР
		КОГДА Себестоимость.Период ЕСТЬ НЕ NULL 
				И СебестоимостьПустойМагазин.Период ЕСТЬ НЕ NULL 
			ТОГДА ВЫБОР
					КОГДА Себестоимость.Период >= СебестоимостьПустойМагазин.Период
						ТОГДА Себестоимость.Цена
					ИНАЧЕ СебестоимостьПустойМагазин.Цена
				КОНЕЦ
		ИНАЧЕ ВЫБОР
				КОГДА Себестоимость.Период ЕСТЬ НЕ NULL 
					ТОГДА Себестоимость.Цена
				ИНАЧЕ СебестоимостьПустойМагазин.Цена
			КОНЕЦ
	КОНЕЦ КАК СебестоимостьИзРегистра,
	ЕСТЬNULL(Остатки.Остаток, 0) КАК Остаток
ПОМЕСТИТЬ ВТ
ИЗ
	СебестоимостьПоПоступлениямСвернуто КАК СебестоимостьПоПоступлениям
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СебестоимостьНоменклатуры.СрезПоследних(&НачалоПериода, Магазин <> ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК Себестоимость
		ПО СебестоимостьПоПоступлениям.Магазин = Себестоимость.Магазин
			И СебестоимостьПоПоступлениям.Номенклатура = Себестоимость.Номенклатура
			И СебестоимостьПоПоступлениям.Характеристика = Себестоимость.Характеристика
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СебестоимостьНоменклатуры.СрезПоследних(&НачалоПериода, Магазин = ЗНАЧЕНИЕ(Справочник.Магазины.ПустаяСсылка)) КАК СебестоимостьПустойМагазин
		ПО (Себестоимость.Номенклатура = СебестоимостьПустойМагазин.Номенклатура)
			И (Себестоимость.Характеристика = СебестоимостьПустойМагазин.Характеристика)
		ЛЕВОЕ СОЕДИНЕНИЕ Остатки КАК Остатки
		ПО СебестоимостьПоПоступлениям.Магазин = Остатки.Магазин
			И СебестоимостьПоПоступлениям.Номенклатура = Остатки.Номенклатура
			И СебестоимостьПоПоступлениям.Характеристика = Остатки.Характеристика
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ.Магазин КАК Магазин,
	ВТ.Номенклатура КАК Номенклатура,
	ВТ.Характеристика КАК Характеристика,
	ВТ.КоличествоПеремещение КАК КоличествоПеремещение,
	ВТ.Количество КАК Количество,
	ВЫБОР
		КОГДА ЕСТЬNULL(ВТ.Стоимость, 0) = 0 И НЕ ВТ.Остаток = 0
			ТОГДА ЕСТЬNULL(ВТ.СебестоимостьИзРегистра, 0)
		ИНАЧЕ ЕСТЬNULL(ВТ.Стоимость, 0)
	КОНЕЦ КАК Стоимость,
	ВЫБОР
		КОГДА ЕСТЬNULL(ВТ.СуммаОборот, 0) = 0 И НЕ ВТ.Остаток = 0
			ТОГДА ЕСТЬNULL(ВТ.СебестоимостьИзРегистра * ВТ.Количество, 0)
		ИНАЧЕ ЕСТЬNULL(ВТ.СуммаОборот, 0)
	КОНЕЦ КАК СуммаОборот
ПОМЕСТИТЬ СебестоимостьПоступлений
ИЗ
	ВТ КАК ВТ

Даже простой взгляд видит, что нет проверки на 0 для СУММА(СебестоимостьПоПоступлениям.Количество) в выражении
Код:
	СУММА(СебестоимостьПоПоступлениям.СуммаОборот) / СУММА(СебестоимостьПоПоступлениям.Количество) КАК Стоимость,
Обходится через расширение.
В расширении изменяем эту строчку на
Код:
ВЫБОР КОГДА СУММА(СебестоимостьПоПоступлениям.Количество)  = 0 ТОГДА 0
ИНАЧЕ СУММА(СебестоимостьПоПоступлениям.Количество) КОНЕЦ КАК Стоимость,
Или изменить (добавить) условие (наверное, это даже правильнее)
Было:
Код:
СГРУППИРОВАТЬ ПО
	СебестоимостьПоПоступлениям.Магазин,
	СебестоимостьПоПоступлениям.Номенклатура,
	СебестоимостьПоПоступлениям.Характеристика,
	СебестоимостьПоПоступлениям.МагазинОтправитель
Стало:
Код:
СГРУППИРОВАТЬ ПО
	СебестоимостьПоПоступлениям.Магазин,
	СебестоимостьПоПоступлениям.Номенклатура,
	СебестоимостьПоПоступлениям.Характеристика,
	СебестоимостьПоПоступлениям.МагазинОтправитель

ИМЕЮЩИЕ
	СУММА(СебестоимостьПоПоступлениям.Количество) <> 0
Само исправление, не снимая конфигурации с поддержки, делается через расширение (во вложении - расширение, в котором для строк с нулевым количество ставится нулевая себестоимость, кто захочет под себя переделать на неучитывание таких строк - решение так же описано в данном топике).
При подключении расширения снимаем "птичку" безопасного режима, перезапускаем 1с.
Вложения
Тип файла: 7z РасчетСебестоимости.7z (5.3 Кб, 196 просмотров)
30.03.2018 00:28
KirillHome
 
Увы, данное расширение в клиент-серверном варианте не работает (надо расширять серверные вызовы, что легко делается в файловом варианте, и с некоторыми усилиями - в клиент-серверном).

Вот объясняюющий кусок из документации

Цитата:
Серверные методы расширяются не всегда

Факт того, что ваше расширение успешно подключено к типовой конфигурации, ещё не означает, что все перехватчики, которые есть в вашем расширении, будут применены и начнут выполняться. Тут есть некоторые особенности, связанные с безопасностью.

Если прикладное решение работает в файловом варианте или в клиент-серверном варианте без профилей безопасности, то при подключении вашего расширения:
  • В обычном режиме исполнения встроенного языка - будут расширяться все методы типового решения, и клиентские, и серверные;
  • В безопасном режиме исполнения встроенного языка - будут расширяться только клиентские методы и серверные обработчики форм. К остальным серверным процедурам / функциями расширение применяться не будет.
Когда прикладное решение работает в клиент-серверном варианте и при подключении расширения указан конкретный профиль безопасности, либо информационной базе назначены профили обычного и безопасного режима, то «серверная» часть расширения будет применяться так, как указано в соответствующем профиле.

Для этого в профиль безопасности мы добавили несколько новых свойств.


Самое простое из них – это флажок к расширению всех модулей в группе Разрешен полный доступ. Он «одним махом» разрешает расширение серверного контекста.

Есть и более точная настройка с помощью полей Доступные для расширения модули и Недоступные для расширения модули. Мы предполагаем, что вы будет использовать их следующим образом:

Если полный доступ к расширениям вы не разрешали, то в поле Доступные для расширения модули вы перечисляете имена тех модулей, для которых расширение серверного контекста допустимо и не страшно;
Если вы разрешили полный доступ к расширениям, то в поле Недоступные для расширения модули вы перечисляете некоторые модули, в которых всё-таки не нужно допускать расширения серверного контекста.
02.04.2018 20:33
KirillHome
 
О как смешно - оказывается, эта ошибка ползёт давно https://olegon.ru/showthread.php?t=26502 (ещё с 2.1.9.2)

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.