Задача 1.13 1С:Специалист - запрос для отчета по стеллажам

24.12.18

Разработка - Запросы

Описание подводных каменей отчета по стеллажам (задача 1.13 1С:Специалист) и способов их преодоления.

Несмотря на кажущуюся простоту отчета, построение запроса для выгрузки данных имеет ряд подводных камней.

Рассмотрим пошагово, где какие проблемы могут возникнуть и как их решать.

Для начала суть отчета – нужно вывести остатки стеллажей (пересчитав из остатка деталей) и сгруппировать по складам. Количество стеллажей определяется по минимальной кратности из всех деталей.  Т.е. если стеллаж состоит из 3х деталей – А(5 шт), Б (10 шт) и В (20 шт), а остаток на складе по деталям – А (21 шт), Б (23 шт), В (25 шт), то целый стеллаж только один.

Для получения результатов запросов используется консоль запросов.

Начнем с простого подхода  – к остаткам по складам соединяем (чуть не написал ВПРим) левым соединением данные с составом стеллажей из регистра сведений, чтобы получить количество стеллажей.  Делим остаток деталей на количество деталей в стеллаже, группируем по складу, стеллажу и определяем минимум по «количеству стеллажей».

Для отладки – следующие исходные данные:

Два стеллажа:

Стеллаж 1 состоит из 4-х стоек, 5-ти полок, 20-ти болтов,

Стеллаж 2 – из 4-х стенок и 17-ти гаек.

Остатки на складах (Деталь |Количество | Склад): Стойка – 50 шт (Склад 1), Полка – 45 шт (склад 1), Болт – 30 шт (Склад 1), Стенка – 15 шт (Склад 2), Гайка – 64 шт (Склад 2)

Текст запроса:

ВЫБРАТЬ
	ОстаткиНоменклатурыОстатки.Склад,
	ПринадлежностьДеталей.Стеллаж,
	МИНИМУМ(ОстаткиНоменклатурыОстатки.КоличествоОстаток / ПринадлежностьДеталей.КоличествоВСтеллаже) КАК КоличествоСтеллажей
ИЗ
	РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатурыОстатки
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПринадлежностьДеталей КАК ПринадлежностьДеталей
		ПО ОстаткиНоменклатурыОстатки.Номенклатура = ПринадлежностьДеталей.Деталь

СГРУППИРОВАТЬ ПО
	ОстаткиНоменклатурыОстатки.Склад,
	ПринадлежностьДеталей.Стеллаж

Результат – в скриншоте ниже.

Для начала, как видим, необходимо избавиться от дробной части.

Не вдаваясь в подробности, используем следующую конструкцию: ВЫРАЗИТЬ(Значение - 0.5 КАК число(15,0)) , где Значение – число, которое необходимо округлить.

Редактируем поле «КоличествоСтеллажей» на

МИНИМУМ(ВЫРАЗИТЬ(ОстаткиНоменклатурыОстатки.КоличествоОстаток / ПринадлежностьДеталей.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))) КАК КоличествоСтеллажей

Выгружаем результат

Вроде все ОК.

НО!..

Удалим из остатков позицию Болт (все 30 шт). И выполним запрос.

Как же так – позиции Стеллаж1 вообще не должно быть в отчете (болтов вообще нет), а отражается 10 шт?

Посмотрим результат запроса с номенклатурой (для более очевидного результата изменим соединение с левого на правое).

Как видим – по математике – все верно. Из имеющихся (остаток) на складе деталей минимальная кратность – 10 (т.е. на 10 стеллажей). А должно быть 0.

Вывод – математика верная, логика неточная – необходимо доработать логику запроса.

Вариант 1.

В запрос добавляем дополнительную логику: если «ингредиентов» (видов деталей) для стеллажа на складе меньше, чем должно быть в составе стеллажа, значит остаток стеллажей на складе – 0. Например, если стеллаж состоит из трех видов деталей, а на складе есть только два – значит остаток стеллажей на складе – ноль.

Для этого в исходном запросе

А) добавляем в начале временную таблицу с количеством видов деталей для каждого стеллажа

Б) из результата исключаем строки где видов деталей для стеллажа на складе меньше, чем должно быть (т.е. оставляем, где равно)

В) добавляем исключение из итогового результата строк с нулевым результатом (т.е. для тех ситуаций, когда на складе есть все виды деталей, но хотя бы по одной детали нет количества даже на один стеллаж)

Для наглядности – результат после пункта А (по Стеллажу1 должно быть три элемента, а на складе есть только два элемента)

Итоговый текст  запроса:

ВЫБРАТЬ
	ПринадлежностьДеталей.Стеллаж КАК Стеллаж,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПринадлежностьДеталей.КоличествоВСтеллаже) КАК КоличествоВСтеллаже
ПОМЕСТИТЬ ЭлементоВСтеллаже
ИЗ
	РегистрСведений.ПринадлежностьДеталей КАК ПринадлежностьДеталей

СГРУППИРОВАТЬ ПО
	ПринадлежностьДеталей.Стеллаж

ИНДЕКСИРОВАТЬ ПО
	Стеллаж
;

//
ВЫБРАТЬ
	ОстаткиНоменклатурыОстатки.Склад,
	ПринадлежностьДеталей.Стеллаж,
	МИНИМУМ(ВЫРАЗИТЬ(ОстаткиНоменклатурыОстатки.КоличествоОстаток / ПринадлежностьДеталей.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))) КАК КоличествоСтеллажей,
	МАКСИМУМ(ЭлементоВСтеллаже.КоличествоВСтеллаже) КАК ТребуетсяЭлементов,
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ОстаткиНоменклатурыОстатки.Номенклатура) КАК ФактическиЭлементовНаСкладе
ИЗ
	РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатурыОстатки
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПринадлежностьДеталей КАК ПринадлежностьДеталей
			ЛЕВОЕ СОЕДИНЕНИЕ ЭлементоВСтеллаже КАК ЭлементоВСтеллаже
			ПО ПринадлежностьДеталей.Стеллаж = ЭлементоВСтеллаже.Стеллаж
		ПО ОстаткиНоменклатурыОстатки.Номенклатура = ПринадлежностьДеталей.Деталь

СГРУППИРОВАТЬ ПО
	ОстаткиНоменклатурыОстатки.Склад,
	ПринадлежностьДеталей.Стеллаж

ИМЕЮЩИЕ
МАКСИМУМ(ЭлементоВСтеллаже.КоличествоВСтеллаже) = КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ОстаткиНоменклатурыОстатки.Номенклатура) 
И
(МИНИМУМ(ВЫРАЗИТЬ(ОстаткиНоменклатурыОстатки.КоличествоОстаток / ПринадлежностьДеталей.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))) > 0)

 

Вариант 2. (уточнение логики исходного запроса)

Строим логику на том, что для каждого склада (на котором есть остатки) формируем список и состав всех стеллажей (т.е. максимально возможные варианты), а потом уже к ним левым соединение подгружаем фактические данные. Если на таком-то складе для такого-то стеллажа нет такой-то делали – то через ЕСТЬNULL формируем ноль.

Для реализации данной логики сначала к регистру сведений с составами стеллажей из виртуальной таблицы остаток добавляем склады (без установки связей между таблицами). В итоге для каждой номенклатуры каждого стеллажа будут добавлены все склады, на которых есть хоть какой-то остаток.

Выгружаем результат во временную таблицу и на следующем этапе присоединяем к ней остатки по складам по Номенклатуре и Стеллажу (по остаткам необходимо обнулить пустые).

Делаем поле с округлением….

МИНИМУМ(ВЫРАЗИТЬ(ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) / МаксимальныеВарианты.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0)))

и … получаем отрицательные результаты, если точнее – то минус 1 стеллаж.

Что в принципе логично, т.к. когда в конструкции  ВЫРАЗИТЬ(Значение - 0.5 КАК число(15,0)) Значение равно нулю, то при округлении -0,5 до целого получается -1.

Дорабатываем конструкцию через ВЫБОР

ВЫБОР
КОГДА   ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0)=0 
ТОГДА 0 
ИНАЧЕ
ВЫРАЗИТЬ(ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) / МаксимальныеВарианты.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))
КОНЕЦ

Теперь все ОК

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

Итоговый текст запроса:

ВЫБРАТЬ
	ПринадлежностьДеталей.Стеллаж КАК Стеллаж,
	ПринадлежностьДеталей.Деталь,
	ПринадлежностьДеталей.КоличествоВСтеллаже,
	ОстаткиНоменклатурыОстатки.Склад КАК Склад
ПОМЕСТИТЬ МаксимальныеВарианты
ИЗ
	РегистрСведений.ПринадлежностьДеталей КАК ПринадлежностьДеталей,
	РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатурыОстатки
;

//
ВЫБРАТЬ
	МаксимальныеВарианты.Стеллаж,
	МаксимальныеВарианты.Склад,
	МИНИМУМ(ВЫБОР
			КОГДА ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) = 0
				ТОГДА 0
			ИНАЧЕ ВЫРАЗИТЬ(ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) / МаксимальныеВарианты.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))
		КОНЕЦ) КАК КоличествоСтеллажей
ИЗ
	МаксимальныеВарианты КАК МаксимальныеВарианты
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатурыОстатки
		ПО МаксимальныеВарианты.Деталь = ОстаткиНоменклатурыОстатки.Номенклатура
			И МаксимальныеВарианты.Склад = ОстаткиНоменклатурыОстатки.Склад

СГРУППИРОВАТЬ ПО
	МаксимальныеВарианты.Стеллаж,
	МаксимальныеВарианты.Склад

ИМЕЮЩИЕ
МИНИМУМ(ВЫБОР
			КОГДА ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) = 0
				ТОГДА 0
			ИНАЧЕ ВЫРАЗИТЬ(ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) / МаксимальныеВарианты.КоличествоВСтеллаже - 0.5 КАК ЧИСЛО(15, 0))
		КОНЕЦ)
	> 0

 

Подводя итоги – вариантов реализации запроса для отчета два:

  1. Для каждого стеллажа определяем максимальное число элементов и сравниваем с числом элементов на складе. Если на складе меньше – значит стеллажей ноль
  2. Определяем все возможные комбинации составов стеллажей/деталей  со складами (склады где есть остатки) и затем присоединяем фактические остатки.

Возможно имеются и другие варианты, но я пока их не нашел.

 

Спасибо за внимание!

Задача 1.13 1С:Специалист отчет по стеллажам

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    127431    688    389    

740

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    2442    andrey_sag    10    

29

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    6122    KawaNoNeko    23    

26

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2203    2    Yashazz    0    

31

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6812    32    mkalimulin    31    

53

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1952    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5700    user1923546    26    

46

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16763    skovpin_sa    14    

101
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. TODD22 18 24.12.18 10:22 Сейчас в теме
Там на много проще запрос. С дробными деталями на экзамене можно не заморачивайся.
Оставьте свое сообщение