Остатки по 2 складам
Здравствуйте.
Возник следующий вопрос. Нужно получить остатки товара по 2 складам (остатки по каждому из этих складов должны идти отдельной колонкой). При этом нужно проигнорировать те позиции товара, которые есть на 2 складе, но нет на 1 складе.
Придумал 2 пути решения
1) Отдельно рассчитывать остатки для одного склада и для другого, а потом объединять их. Недостаток данного варианта является, то что приходится обращаться к регистру остатков дважды. Запрос будет выглядеть примерно так:
2) Оба склада поместить в список значений. Далее выбрать запросом данные сразу по двум складам. После чего результат выгрузить в таблицу значений и обработать её.
Обращение к регистру остатков одно, но зато дополнительно будет обрабатываться таблица значений.
Запрос будет выглядеть примерно так:
Какой вариант в данной ситуации будет более рациональным? Кто что думает по этому поводу?
Возник следующий вопрос. Нужно получить остатки товара по 2 складам (остатки по каждому из этих складов должны идти отдельной колонкой). При этом нужно проигнорировать те позиции товара, которые есть на 2 складе, но нет на 1 складе.
Придумал 2 пути решения
1) Отдельно рассчитывать остатки для одного склада и для другого, а потом объединять их. Недостаток данного варианта является, то что приходится обращаться к регистру остатков дважды. Запрос будет выглядеть примерно так:
ВЫБРАТЬ
СвободныеОстаткиОстатки.ВНаличииОстаток,
СвободныеОстаткиОстатки.Номенклатура,
СвободныеОстаткиОстатки1.ВНаличииОстаток КАК ВНаличииОстаток1
ИЗ
РегистрНакопления.СвободныеОстатки.Остатки(&Дата, Склад = &Склад1) КАК СвободныеОстаткиОстатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СвободныеОстатки.Остатки(&Дата, Склад = &Склад2) КАК СвободныеОстаткиОстатки1
ПО СвободныеОстаткиОстатки.Номенклатура = СвободныеОстаткиОстатки1.Номенклатура
ГДЕ
СвободныеОстаткиОстатки.ВНаличииОстаток > 0
Показать2) Оба склада поместить в список значений. Далее выбрать запросом данные сразу по двум складам. После чего результат выгрузить в таблицу значений и обработать её.
Обращение к регистру остатков одно, но зато дополнительно будет обрабатываться таблица значений.
Запрос будет выглядеть примерно так:
ВЫБРАТЬ
СвободныеОстаткиОстатки.ВНаличииОстаток,
СвободныеОстаткиОстатки.Склад,
СвободныеОстаткиОстатки.Номенклатура
ИЗ
РегистрНакопления.СвободныеОстатки.Остатки(&Дата, Склад В (&СписокЗначенийСклады)) КАК СвободныеОстаткиОстатки
Какой вариант в данной ситуации будет более рациональным? Кто что думает по этому поводу?
Найденные решения
мне одному кажется, что тут вообще никаких соединений не нужно в запросе ?
Выбираем остатки, используем В (&Склады) или &Склад1 Или &Склад2
где остатки, там вычисляемое поле
По второму складу отдельное вычисляемое поле.
Группируем по номенклатуре, склад нам уже не нужен.
И ставим на выходе условие, "ГДЕ Колонка1>0 и Колонка2>0"
P.S.
Готовый запрос рисовать лень, но в целом идея понятна.
Выбираем остатки, используем В (&Склады) или &Склад1 Или &Склад2
где остатки, там вычисляемое поле
Выбор
Когда Выборка.Склад = &Склад1 тогда остаток Выборка.Остаток
Иначе 0
Конец
По второму складу отдельное вычисляемое поле.
Группируем по номенклатуре, склад нам уже не нужен.
И ставим на выходе условие, "ГДЕ Колонка1>0 и Колонка2>0"
P.S.
Готовый запрос рисовать лень, но в целом идея понятна.
Остальные ответы
В избранное
Подписаться на ответы
Сортировка:
Древо развёрнутое
Свернуть все
(2) Не понял Вашу мысль... Вы думаете, что можно левое/правое соединение использовать как-то более рационально, чем это предложил сделать я в своём первом варианте?
Информации по соединениям в интернете много, но нигде не рассматривается (по крайней мере я не нашёл) вопрос как лучше строить соединение, когда одна и та же таблица соединятеся "сама с собой"
Информации по соединениям в интернете много, но нигде не рассматривается (по крайней мере я не нашёл) вопрос как лучше строить соединение, когда одна и та же таблица соединятеся "сама с собой"
(8) Ну да, про временные таблицы я тоже думал.
Запрос примерно такой получался:
Но конкретно в моём случае, наиболее оптимальный вариант озвучен в (5), поскольку в моём конкретном случае ещё один склад в этой обработке вряд ли появится.
Ну а так, со временными таблицами вариант более универсальный.
Запрос примерно такой получался:
ВЫБРАТЬ
СвободныеОстаткиОстатки.ВНаличииОстаток,
СвободныеОстаткиОстатки.Склад,
СвободныеОстаткиОстатки.Номенклатура
ПОМЕСТИТЬ ТаблицаОстатков
ИЗ
РегистрНакопления.СвободныеОстатки.Остатки(&Дата, (Склад = &Склад1 Или Склад = &Склад2)) КАК СвободныеОстаткиОстатки
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ТаблицаОстатков.ВНаличииОстаток,
ТаблицаОстатков.Номенклатура,
ТаблицаОстатков1.ВНаличииОстаток КАК ВНаличииОстаток1
ИЗ
ТаблицаОстатков КАК ТаблицаОстатков
ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаОстатков КАК ТаблицаОстатков1
ПО ТаблицаОстатков.Номенклатура = ТаблицаОстатков1.Номенклатура
ГДЕ
ТаблицаОстатков.Склад = &Склад1
И ТаблицаОстатков.ВНаличииОстаток > 0
И ТаблицаОстатков1.Склад = &Склад2
ПоказатьНо конкретно в моём случае, наиболее оптимальный вариант озвучен в (5), поскольку в моём конкретном случае ещё один склад в этой обработке вряд ли появится.
Ну а так, со временными таблицами вариант более универсальный.
Пользуйся 1 вариантом, только соединение делай внутреннее и без ГДЕ.
ВЫБРАТЬ
СвободныеОстаткиОстатки.ВНаличииОстаток,
СвободныеОстаткиОстатки.Номенклатура,
СвободныеОстаткиОстатки1.ВНаличииОстаток КАК ВНаличииОстаток1
ИЗ
РегистрНакопления.СвободныеОстатки.Остатки(&Дата, Склад = &Склад1) КАК СвободныеОстаткиОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.СвободныеОстатки.Остатки(&Дата, Склад = &Склад2) КАК СвободныеОстаткиОстатки1
ПО СвободныеОстаткиОстатки.Номенклатура = СвободныеОстаткиОстатки1.Номенклатура
Показать
(4) (4) Внутренее соединение здесь сработает не совсем верно. Поскольку оно отсечёт ту номенклатуру, которая есть на складе 1, но нет на складе 2. А нужно отсечь только ту, которой нет на складе 1, при этом она может присутствовать на складе 2.
Меня в этом первом варианте смущает то что запрос будет обходить регистр остатков дважды. Что на мой взгляд может быть не оптимально...
Меня в этом первом варианте смущает то что запрос будет обходить регистр остатков дважды. Что на мой взгляд может быть не оптимально...
мне одному кажется, что тут вообще никаких соединений не нужно в запросе ?
Выбираем остатки, используем В (&Склады) или &Склад1 Или &Склад2
где остатки, там вычисляемое поле
По второму складу отдельное вычисляемое поле.
Группируем по номенклатуре, склад нам уже не нужен.
И ставим на выходе условие, "ГДЕ Колонка1>0 и Колонка2>0"
P.S.
Готовый запрос рисовать лень, но в целом идея понятна.
Выбираем остатки, используем В (&Склады) или &Склад1 Или &Склад2
где остатки, там вычисляемое поле
Выбор
Когда Выборка.Склад = &Склад1 тогда остаток Выборка.Остаток
Иначе 0
Конец
По второму складу отдельное вычисляемое поле.
Группируем по номенклатуре, склад нам уже не нужен.
И ставим на выходе условие, "ГДЕ Колонка1>0 и Колонка2>0"
P.S.
Готовый запрос рисовать лень, но в целом идея понятна.
Вот подобный пример:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КодыНоменклатуры.Код77 КАК Код77,
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета, Склад В (&СписокЗначенийСклады)) КАК ТоварыНаСкладахОстатки
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| НоменклатураДополнительныеРеквизиты.Ссылка КАК Номенклатура,
| НоменклатураДополнительныеРеквизиты.Значение КАК Код77
| ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
| ГДЕ
| НоменклатураДополнительныеРеквизиты.Свойство = &Свойство) КАК КодыНоменклатуры
| ПО ТоварыНаСкладахОстатки.Номенклатура = КодыНоменклатуры.Номенклатура
|ГДЕ
| ТоварыНаСкладахОстатки.Номенклатура.ВидНоменклатуры В(&ВидНоменклатуры)
|
|УПОРЯДОЧИТЬ ПО
| ТоварыНаСкладахОстатки.Номенклатура.Наименование";
Список = Новый Массив;
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция"));
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Полуфабрикаты"));
Если Объект.ПоказатьОстаткиМатериалов Тогда
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Материалы производства"));
КонецЕсли;
Запрос.УстановитьПараметр("ВидНоменклатуры",Список);
Запрос.УстановитьПараметр("ДатаОтчета",НачалоДня(НачДата));
СписокЗначенийСклады = Новый СписокЗначений;
Если НЕ ЗначениеЗаполнено(Объект.Склад) Тогда
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад1"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад2"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад3"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад4"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад5"));
Иначе
СписокЗначенийСклады.Добавить(Объект.Склад));
Если Объект.Склад = Справочники.Склады.НайтиПоНаименованию("Склад1") Тогда
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад3"));
КонецЕсли;
КонецЕсли;
Запрос.УстановитьПараметр("Склад",СписокЗначенийСклады);
Запрос.УстановитьПараметр("Свойство",ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Код77"));
РезультатЗапроса = Запрос.Выполнить();
В Инструментарии разработчика работает на "ура", а в модуле ошибка:
Не задано значение параметра "СписокЗначенийСклады"
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета, Склад В(<<?>>&СписокЗначенийСклады)) КАК ТоварыНаСкладахОстатки
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КодыНоменклатуры.Код77 КАК Код77,
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК ВНаличииОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета, Склад В (&СписокЗначенийСклады)) КАК ТоварыНаСкладахОстатки
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| НоменклатураДополнительныеРеквизиты.Ссылка КАК Номенклатура,
| НоменклатураДополнительныеРеквизиты.Значение КАК Код77
| ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
| ГДЕ
| НоменклатураДополнительныеРеквизиты.Свойство = &Свойство) КАК КодыНоменклатуры
| ПО ТоварыНаСкладахОстатки.Номенклатура = КодыНоменклатуры.Номенклатура
|ГДЕ
| ТоварыНаСкладахОстатки.Номенклатура.ВидНоменклатуры В(&ВидНоменклатуры)
|
|УПОРЯДОЧИТЬ ПО
| ТоварыНаСкладахОстатки.Номенклатура.Наименование";
Список = Новый Массив;
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Продукция"));
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Полуфабрикаты"));
Если Объект.ПоказатьОстаткиМатериалов Тогда
Список.Добавить(Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Материалы производства"));
КонецЕсли;
Запрос.УстановитьПараметр("ВидНоменклатуры",Список);
Запрос.УстановитьПараметр("ДатаОтчета",НачалоДня(НачДата));
СписокЗначенийСклады = Новый СписокЗначений;
Если НЕ ЗначениеЗаполнено(Объект.Склад) Тогда
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад1"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад2"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад3"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад4"));
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад5"));
Иначе
СписокЗначенийСклады.Добавить(Объект.Склад));
Если Объект.Склад = Справочники.Склады.НайтиПоНаименованию("Склад1") Тогда
СписокЗначенийСклады.Добавить(Справочники.Склады.НайтиПоНаименованию("Склад3"));
КонецЕсли;
КонецЕсли;
Запрос.УстановитьПараметр("Склад",СписокЗначенийСклады);
Запрос.УстановитьПараметр("Свойство",ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя","Код77"));
РезультатЗапроса = Запрос.Выполнить();
В Инструментарии разработчика работает на "ура", а в модуле ошибка:
Не задано значение параметра "СписокЗначенийСклады"
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОтчета, Склад В(<<?>>&СписокЗначенийСклады)) КАК ТоварыНаСкладахОстатки
Прикрепленные файлы:
Вакансии
Программист с опытом реализации проектов через 1С:Конвертацию данных
Санкт-Петербург
зарплата от 1 300 руб.
Временный (на проект)
Санкт-Петербург
зарплата от 1 300 руб.
Временный (на проект)
Программист 1С
Краснознаменск (Московская обл.)
зарплата от 150 000 руб. до 250 000 руб.
Полный день
Краснознаменск (Московская обл.)
зарплата от 150 000 руб. до 250 000 руб.
Полный день
Специалист техподдержки
Краснознаменск (Московская обл.)
зарплата от 50 000 руб. до 100 000 руб.
Полный день
Краснознаменск (Московская обл.)
зарплата от 50 000 руб. до 100 000 руб.
Полный день