Имя: Пароль:
1C
1C 7.7
v7: sql запрос. Получить количество дней, где остаток больше 0
0 Lacoster
 
14.11.13
07:42
Всем привет! Как из темы ясно, нужно получить количество дней где остаток у номенклатуры больше 0. Это необходимо для расчета динамики.
Я задаю интервал и менеджера (чья это номенклатура).
Собственно получить остаток на дату не сложно $РегистрОстатки.ОстаткиТМЦ(:ВыбДата~,,
    |,
    |Номенклатура,) и т.д.
вопрос как пробежать по диапазону дат? Циклом бежать по датам и подставлять нужную в запрос а потом Union all? В итоге получится здоровенный запрос (если скажем динамику за год посчитать нужно) и попытаться его выполнить?
Или всё же есть более простые и лаконичные решения? В этом вопрос.
1 dk
 
14.11.13
08:04
Много лишнего, но принцип понятен - получение остатков по дням движения и потом цикл с простановкой остатков

Функция СреднедневнаяПродажаСУчетомПрисутствия(Дата1, Дата2, фМФТМ="", фМФНоменклатура="", фМФНомИскл="", фМФСклад="", фМФСкладИскл="")
    Перем Результат;

    Состояние("Расчет средних по магазину");
    
    Результат = СоздатьОбъект("ТаблицаЗначений");
    Результат.НоваяКолонка("Товар",        "Справочник.Номенклатура");
    Результат.НоваяКолонка("Дни",        "Число");
    Результат.НоваяКолонка("ОборотКол",    "Число");
    
    рс = СоздатьОбъект("ODBCRecordset");
    
    // ((( dk 31/05/2013
    // Зададим фильтр по складам
    флНуженФильтрПоСкладу = 0;
    Если ПустоеЗначение(фМФСклад) = 0 Тогда
        флНуженФильтрПоСкладу = 1;
        рс.УложитьСписокОбъектов(фМФСклад, "#фМФСклад", "МестаХранения");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФСкладИскл) = 0 Тогда
        флНуженФильтрПоСкладу = 1;
        рс.УложитьСписокОбъектов(фМФСкладИскл, "#фМФСкладИскл", "МестаХранения");
    КонецЕсли;

    Если флНуженФильтрПоСкладу <> 0 Тогда
        
        ТекстЗапроса = "
        |if (select object_id('tempdb..#mytemptableFilterSklad')) is NOT null DROP TABLE #mytemptableFilterSklad
        |CREATE TABLE #mytemptableFilterSklad (
        |    Val        char(9)       DEFAULT $ПустойИд  NOT NULL,
        |UNIQUE CLUSTERED (Val))
        |";
        
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
        ТекстЗапроса = "
        |INSERT INTO #mytemptableFilterSklad
        |SELECT
        |    МестаХранения.ID
        |FROM
        |    $Справочник.МестаХранения AS МестаХранения With (NOLOCK)
        |WHERE
        |    (1=1)"+?(ПустоеЗначение(фМФСклад)=0," AND (МестаХранения.ID IN (SELECT VAL FROM #фМФСклад)) ","")+
                    ?(ПустоеЗначение(фМФСкладИскл)=0," AND (МестаХранения.ID NOT IN (SELECT val FROM #фМФСкладИскл))","")+"
        |";
    
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
    КонецЕсли;    //"Если флНуженФильтрПоСкладу <> 0 Тогда
    
    // Зададим фильтр по товару
    флНуженФильтрПоТовару = 0;
    
    Если ПустоеЗначение(фМФТМ) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФТМ, "#фМФТМ", "ТорговыеМарки");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФНоменклатура) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФНоменклатура, "#фМФНоменклатура", "Номенклатура");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФНомИскл) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФНомИскл, "#фМФНомИскл", "Номенклатура");
    КонецЕсли;
    
    Если флНуженФильтрПоТовару <> 0 Тогда
        
        ТекстЗапроса = "
        |if (select object_id('tempdb..#mytemptableFilterTovar')) is NOT null DROP TABLE #mytemptableFilterTovar
        |CREATE TABLE #mytemptableFilterTovar (
        |    Val        char(9)       DEFAULT $ПустойИд  NOT NULL,
        |UNIQUE CLUSTERED (Val))
        |";
        
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
        ТекстЗапроса = "
        |INSERT INTO #mytemptableFilterTovar
        |SELECT
        |    Номенклатура.ID
        |FROM
        |    $Справочник.Номенклатура AS Номенклатура With (NOLOCK)
        |WHERE
        |    (1=1)"+?(ПустоеЗначение(фМФТМ)=0," AND ($Номенклатура.ТорговаяМарка IN (SELECT val FROM #фМФТМ)) ","")+
                    ?(ПустоеЗначение(фМФНоменклатура)=0," AND (Номенклатура.ID IN (SELECT val FROM #фМФНоменклатура))","")+
                    ?(ПустоеЗначение(фМФНомИскл)=0," AND (Номенклатура.ID NOT IN (SELECT val FROM #фМФНомИскл))","");
    
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
    КонецЕсли;    //"Если флНуженФильтрПоТовару <> 0 Тогда
    
    ТекстЗапроса = "
    |if (select object_id('tempdb..#mytemptableSrednie')) is NOT null DROP TABLE #mytemptableSrednie
    |
    |CREATE TABLE #mytemptableSrednie (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |
    |if (select object_id('tempdb..#mytemptableSrednie1')) is NOT null DROP TABLE #mytemptableSrednie1
    |
    |CREATE TABLE #mytemptableSrednie1 (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |
    |if (select object_id('tempdb..#mytemptableSrednie2')) is NOT null DROP TABLE #mytemptableSrednie2
    |
    |CREATE TABLE #mytemptableSrednie2 (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ТекстЗапроса = "
    |INSERT INTO #mytemptableSrednie1
    |SELECT
    |    
    |     Вложенный.Товар1 _Товар
    |    , Вложенный.Период1 _День
    |    , sum(Вложенный.Остаток1) _Остаток
    |    , sum(Вложенный.ОборотКол1)    _ОборотКол
    |    , sum(0) _Дни
    |    , sum(Вложенный.Флаг1) _Флаг
    |
    |FROM (
        |SELECT
        |        ТовОстаткиОбороты.Товар Товар1
        |    ,    NullIf(ТовОстаткиОбороты.Период, '17530101') Период1
        |    ,    sum(ТовОстаткиОбороты.ОстатокТовараКонечныйОстаток) Остаток1
        |    ,    min(0) ОборотКол1
        |    ,    min(1) Флаг1
        |
        |FROM $РегистрОстаткиОбороты.ОстаткиТоваров(:НачДата,
        |        :КонДата~,
        |        День,
        |        ДвиженияИГраницыПериода,,"+?(флНуженФильтрПоСкладу <> 0,"(Склад IN (SELECT val FROM #mytemptableFilterSklad))","")+?(флНуженФильтрПоТовару<>0,?(флНуженФильтрПоСкладу <> 0," AND ","")+"(Товар IN (SELECT val FROM #mytemptableFilterTovar))","")+",(Товар),(ОстатокТовара)) AS ТовОстаткиОбороты With (NOLOCK)
        |GROUP BY
        |    ТовОстаткиОбороты.Товар, NullIf(ТовОстаткиОбороты.Период, '17530101')
        |
        |UNION ALL
        |
        |SELECT
        |    $Продажи.Товар _Товар
        |    , NullIf(Cast(Left(Продажи.DATE_TIME_IDDOC, 8) AS datetime), '17530101') Документ_дата
        |    , min(0) _Остаток
        |    , sum($Продажи.Количество) ОборотКол
        |    , min(0) Флаг
        |
    |FROM $Регистр.Продажи AS Продажи With (NOLOCK)
    |    INNER JOIN    $Справочник.Магазины AS СпрМаг With (NOLOCK) ON $СпрМаг.Клиент = $Продажи.Клиент
    |WHERE (Продажи.DATE_TIME_IDDOC  between :НачДата AND :КонДата~) "+?(флНуженФильтрПоСкладу <> 0," AND ($СпрМаг.Склад IN (SELECT val FROM #mytemptableFilterSklad))","")+?(флНуженФильтрПоТовару<>0," AND ($Продажи.Товар IN (SELECT val FROM #mytemptableFilterTovar))","")+"
    |GROUP BY $Продажи.Товар, NullIf(Cast(Left(Продажи.DATE_TIME_IDDOC, 8) AS datetime), '17530101')
    |) AS Вложенный
    |GROUP BY
    |    Вложенный.Товар1, Вложенный.Период1
    |";
    
    рс.УстановитьТекстовыйПараметр("НачДата", Дата1);
    рс.УстановитьТекстовыйПараметр("КонДата", Дата2);
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    Если ((флНужныДанные8 <> 0) ИЛИ (фМФСклад.РазмерСписка() > 1)) И (Макс(Дата1, ДатаРазделения8) <= Дата2) Тогда
        Состояние("Средние продажи по магазину (УТ 11)");
        ЗапросУТ = БазаУТ.NewObject("Запрос");
        ЗапросУТ.Текст = "
            |ВЫБРАТЬ
            |    ВЛОЖ.УИД КАК Товар,
            |    ВЛОЖ.День КАК День,
            |    СУММА(ВЛОЖ.Остаток) КАК Остаток,
            |    СУММА(ВЛОЖ.Продажа) КАК ОборотКол,
            |    СУММА(0) КАК Дни,
            |    СУММА(Флаг) КАК Флаг
            |ИЗ
            |(ВЫБРАТЬ
            |    Остатки.Номенклатура.УИД КАК УИД,
            |    Остатки.Период ДЕНЬ,
            |    Остатки.ВНаличииКонечныйОстаток Остаток,
            |    0 Продажа,
            |    1 КАК Флаг
            |ИЗ
            |    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(
            |            &д1,
            |            КонецПериода(&д2, ДЕНЬ),
            |            День,
            |            ДвиженияИГраницыПериода,
            |            "+?(фМФСклад.РазмерСписка()=1,"Склад = &Склад","") +"
            |                И Номенклатура.УИД В (&СписокТоваров)) КАК Остатки
            |                
            |ОБЪЕДИНИТЬ ВСЕ
            |
            |ВЫБРАТЬ
            |    Выручка.АналитикаУчетаНоменклатуры.Номенклатура.УИД КАК УИД,
            |    Выручка.Период ДЕНЬ,
            |    0 Остаток,
            |    Выручка.КоличествоОборот КАК Продажа,
            |    0 КАК Флаг
            |ИЗ
            |    РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(
            |            &д1,
            |            КонецПериода(&д2, ДЕНЬ),
            |            День,
            |            АналитикаУчетаНоменклатуры.Номенклатура.УИД В (&СписокТоваров)
            |                "+?(фМФСклад.РазмерСписка()=1,"И АналитикаУчетаНоменклатуры.Склад = &Склад","") +") КАК Выручка
            |) ВЛОЖ
            |СГРУППИРОВАТЬ ПО
            |    ВЛОЖ.УИД, ВЛОЖ.День
            |";        
        
        ЗапросУТ.УстановитьПараметр("СписокТоваров", СписокТоваровУТ);
        ЗапросУТ.УстановитьПараметр("Склад",             СкладУТ);
        ЗапросУТ.УстановитьПараметр("д1",             Макс(Дата1, ДатаРазделения8));
        ЗапросУТ.УстановитьПараметр("д2",             Дата2);
        
        Выборка = ЗапросУТ.Выполнить().Выгрузить();
        
        ВремТЗ = СоздатьОбъект("ТаблицаЗначений");
        ВремТЗ.НоваяКолонка("Товар",        "Строка", 9);
        ВремТЗ.НоваяКолонка("День",        "Дата");
        ВремТЗ.НоваяКолонка("Остаток",    "Число");
        ВремТЗ.НоваяКолонка("ОборотКол",    "Число");
        ВремТЗ.НоваяКолонка("Дни",        "Число");
        ВремТЗ.НоваяКолонка("Флаг",        "Число");
        
        Для СчСтр = 0 По Выборка.Количество() - 1 Цикл
            Стр = Выборка.Получить(СчСтр);
            ВремТЗ.НоваяСтрока();
            ВремТЗ.Товар        = Стр.Товар;
            ВремТЗ.День            = Стр.День;
            ВремТЗ.Остаток        = Стр.Остаток;
            ВремТЗ.ОборотКол    = Стр.ОборотКол;
            ВремТЗ.Дни            = Стр.Дни;
            ВремТЗ.Флаг            = Стр.Флаг;
        КонецЦикла;
        
        Стр = "";
        Выборка = "";
        ЗапросУТ = "";
    
        рс.Подготовить("INSERT INTO #mytemptableSrednie2 VALUES(?, ?, ?, ?, ?, ?)");
        рс.ВыполнитьSQL_ИзТЗ(ВремТЗ);
        
        ВремТЗ = "";        
        
    КонецЕсли;    //"Если флНужныДанные8 <> 0 Тогда
        
    ТекстЗапроса = "
    |INSERT INTO #mytemptableSrednie
    |SELECT
    |    Товар
    |    ,День
    |    , SUM(Остаток)        Остаток
    |    , SUM(ОборотКол)    ОборотКол
    |    , SUM(Дни)            Дни
    |    , SUM(Флаг)            Флаг
    |FROM
    |(SELECT
    |    Товар
    |    ,День
    |    ,Остаток
    |    ,ОборотКол
    |    ,Дни
    |    ,Флаг
    |FROM
    |    #mytemptableSrednie1
    |
    |UNION ALL
    |
    |SELECT
    |    Товар
    |    ,День
    |    ,Остаток
    |    ,ОборотКол
    |    ,Дни
    |    ,Флаг
    |FROM
    |    #mytemptableSrednie2) Влож
    |GROUP BY
    |    Товар, День
    |
    |DROP TABLE #mytemptableSrednie1
    |
    |DROP TABLE #mytemptableSrednie2
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    // ((( dk 30/11/2012 - Почистим от всплеска
    ТекстЗапроса = "
    |DECLARE @d numeric(19,5)
    |DECLARE @s numeric(19,5)
    |
    |SET @s = (Select max(ОборотКол)from #mytemptableSrednie)
    |SET @d = (Select max(ОборотКол)from #mytemptableSrednie where ОборотКол < @s)
    |
    |IF (@S > 0) AND (@S > @d*1.2)
    |BEGIN
    |    UPDATE #mytemptableSrednie
    |    SET
    |        ОборотКол = @d
    |    FROM #mytemptableSrednie Темп,(SELECT TOP 1 * FROM #mytemptableSrednie WHERE ОборотКол = @s) Влож
    |    WHERE (Влож.Товар = Темп.Товар) AND (Влож.День=Темп.День) AND (Влож.ОборотКол=Темп.ОборотКол)
    |END
    |";
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    // dk )))
    
    // ((( dk 18/10/2013
    //ТекстЗапроса = "
    //    |INSERT INTO #mytemptableSrednie (Товар, День)
    //    |SELECT B.Товар, A.date
    //    |FROM (SELECT date = Cast((b.number * 0x100) + a.number AS datetime)
    //    |    FROM master..spt_values a
    //    |        INNER JOIN master..spt_values b ON (b.number * 0x100) + a.number <= Cast(Cast(:КонДата AS datetime) AS integer)
    //    |            AND (b.number * 0x100) + a.number >= Cast(Cast(:НачДата AS datetime) AS integer)
    //    |    WHERE (a.type = 'p') AND (b.type = 'p')
    //    |        AND (b.number * 0x100 <= Cast(Cast(:КонДата AS datetime) AS integer))
    //    |    ) A CROSS JOIN
    //    |    (SELECT DISTINCT Товар
    //    |    FROM #mytemptableSrednie) B
    //    |WHERE NOT Exists(SELECT * FROM #mytemptableSrednie WHERE #mytemptableSrednie.Товар = B.Товар AND #mytemptableSrednie.День = A.date)
    //    |";
    //    
    //рс.УстановитьТекстовыйПараметр("НачДата", Дата1);
    //рс.УстановитьТекстовыйПараметр("КонДата", Дата2);
    //рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ВремТЗ = СоздатьОбъект("ТаблицаЗначений");
    ВремТЗ.НоваяКолонка("Дата", "Дата");
    Для Сч = Дата1 По Дата2 Цикл
        ВремТЗ.НоваяСтрока();
        ВремТЗ.Дата = Сч;
    КонецЦикла;
    
    ТекстЗапроса = "
    |if (select object_id('tempdb..#mytemptableDate')) is NOT null DROP TABLE #mytemptableDate
    |
    |CREATE TABLE #mytemptableDate (
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |UNIQUE CLUSTERED (День))
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);    
    
    рс.Подготовить("INSERT INTO #mytemptableDate VALUES(?)");
    рс.ВыполнитьSQL_ИзТЗ(ВремТЗ);    
    
    ВремТЗ = "";
    
    ТекстЗапроса = "
        |INSERT INTO #mytemptableSrednie (Товар, День)
        |SELECT B.Товар, A.День
        |FROM #mytemptableDate A
        |CROSS JOIN    (SELECT DISTINCT Товар FROM #mytemptableSrednie) B
        |WHERE NOT Exists(SELECT * FROM #mytemptableSrednie WHERE #mytemptableSrednie.Товар = B.Товар AND #mytemptableSrednie.День = A.День)
        |";
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    // dk )))
    
    ТекстЗапроса = "
        |DECLARE @n numeric(19,5)
        |DECLARE @s char(9)
        |SET @n = 0
        |SET @s = $ПустойИд
        |
        |UPDATE #mytemptableSrednie
        |SET @n = CASE WHEN (Остаток = 0) AND (Товар = @s) AND (Флаг = 0) THEN @n ELSE Остаток END,
        |    Остаток = @n,
        |    Дни = CASE WHEN ((@n <> 0) OR (ОборотКол <> 0)) THEN 1 ELSE 0 END,
        |    @s = Товар
        |";
        
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ТекстЗапроса = "
        |SELECT
        // ((( dk 17/10/2013
        //|    Товар          [Товар $Справочник.Номенклатура]
        |    Товар          Товар
        // dk )))
        |,    sum(Дни)       Дни
        |,    sum(ОборотКол) ОборотКол
        |FROM
        |    #mytemptableSrednie
        |GROUP BY
        |    Товар";
    
    Результат = рс.ВыполнитьИнструкцию(ТекстЗапроса);
    
    //Результат.ВыбратьСтроку();
    
    рс.ВыполнитьСкалярный("DROP TABLE #mytemptableSrednie");
    
    Возврат Результат;
    
КонецФункции    //глСреднедневнаяПродажаСУчетомПрисутствия
2 Lacoster
 
14.11.13
08:12
(1) ??
3 dk
 
14.11.13
08:17
хрень какая получилась, хотя теги вроде ставил
4 dk
 
14.11.13
08:23
попробую без комментариев

Функция СреднедневнаяПродажаСУчетомПрисутствия(Дата1, Дата2, фМФТМ="", фМФНоменклатура="", фМФНомИскл="", фМФСклад="", фМФСкладИскл="")
    Перем Результат;

    Состояние("Расчет средних по магазину");
    
    Результат = СоздатьОбъект("ТаблицаЗначений");
    Результат.НоваяКолонка("Товар",        "Справочник.Номенклатура");
    Результат.НоваяКолонка("Дни",        "Число");
    Результат.НоваяКолонка("ОборотКол",    "Число");
    
    рс = СоздатьОбъект("ODBCRecordset");
    
    флНуженФильтрПоСкладу = 0;
    Если ПустоеЗначение(фМФСклад) = 0 Тогда
        флНуженФильтрПоСкладу = 1;
        рс.УложитьСписокОбъектов(фМФСклад, "#фМФСклад", "МестаХранения");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФСкладИскл) = 0 Тогда
        флНуженФильтрПоСкладу = 1;
        рс.УложитьСписокОбъектов(фМФСкладИскл, "#фМФСкладИскл", "МестаХранения");
    КонецЕсли;

    Если флНуженФильтрПоСкладу <> 0 Тогда
        
        ТекстЗапроса = "
        |if (select object_id('tempdb..#mytemptableFilterSklad')) is NOT null DROP TABLE #mytemptableFilterSklad
        |CREATE TABLE #mytemptableFilterSklad (
        |    Val        char(9)       DEFAULT $ПустойИд  NOT NULL,
        |UNIQUE CLUSTERED (Val))
        |";
        
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
        ТекстЗапроса = "
        |INSERT INTO #mytemptableFilterSklad
        |SELECT
        |    МестаХранения.ID
        |FROM
        |    $Справочник.МестаХранения AS МестаХранения With (NOLOCK)
        |WHERE
        |    (1=1)"+?(ПустоеЗначение(фМФСклад)=0," AND (МестаХранения.ID IN (SELECT VAL FROM #фМФСклад)) ","")+
                    ?(ПустоеЗначение(фМФСкладИскл)=0," AND (МестаХранения.ID NOT IN (SELECT val FROM #фМФСкладИскл))","")+"
        |";
    
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
    КонецЕсли;
    
    флНуженФильтрПоТовару = 0;
    
    Если ПустоеЗначение(фМФТМ) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФТМ, "#фМФТМ", "ТорговыеМарки");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФНоменклатура) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФНоменклатура, "#фМФНоменклатура", "Номенклатура");
    КонецЕсли;
    
    Если ПустоеЗначение(фМФНомИскл) = 0 Тогда
        флНуженФильтрПоТовару = 1;
        рс.УложитьСписокОбъектов(фМФНомИскл, "#фМФНомИскл", "Номенклатура");
    КонецЕсли;
    
    Если флНуженФильтрПоТовару <> 0 Тогда
        
        ТекстЗапроса = "
        |if (select object_id('tempdb..#mytemptableFilterTovar')) is NOT null DROP TABLE #mytemptableFilterTovar
        |CREATE TABLE #mytemptableFilterTovar (
        |    Val        char(9)       DEFAULT $ПустойИд  NOT NULL,
        |UNIQUE CLUSTERED (Val))
        |";
        
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
        ТекстЗапроса = "
        |INSERT INTO #mytemptableFilterTovar
        |SELECT
        |    Номенклатура.ID
        |FROM
        |    $Справочник.Номенклатура AS Номенклатура With (NOLOCK)
        |WHERE
        |    (1=1)"+?(ПустоеЗначение(фМФТМ)=0," AND ($Номенклатура.ТорговаяМарка IN (SELECT val FROM #фМФТМ)) ","")+
                    ?(ПустоеЗначение(фМФНоменклатура)=0," AND (Номенклатура.ID IN (SELECT val FROM #фМФНоменклатура))","")+
                    ?(ПустоеЗначение(фМФНомИскл)=0," AND (Номенклатура.ID NOT IN (SELECT val FROM #фМФНомИскл))","");
    
        рс.ВыполнитьСкалярный(ТекстЗапроса);
        
    КонецЕсли;
    
    ТекстЗапроса = "
    |if (select object_id('tempdb..#mytemptableSrednie')) is NOT null DROP TABLE #mytemptableSrednie
    |
    |CREATE TABLE #mytemptableSrednie (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |
    |if (select object_id('tempdb..#mytemptableSrednie1')) is NOT null DROP TABLE #mytemptableSrednie1
    |
    |CREATE TABLE #mytemptableSrednie1 (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |
    |if (select object_id('tempdb..#mytemptableSrednie2')) is NOT null DROP TABLE #mytemptableSrednie2
    |
    |CREATE TABLE #mytemptableSrednie2 (
    |    Товар        char(9)       DEFAULT $ПустойИд  NOT NULL,
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |    Остаток        numeric(19,5) DEFAULT 0          NOT NULL,
    |    ОборотКол    numeric(19,5) DEFAULT 0          NOT NULL,
    |    Дни            numeric(19,0) DEFAULT 0          NOT NULL,
    |    Флаг        numeric(1,0)  DEFAULT 0          NOT NULL,
    |UNIQUE CLUSTERED (Товар, День))
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ТекстЗапроса = "
    |INSERT INTO #mytemptableSrednie1
    |SELECT
    |    
    |     Вложенный.Товар1 _Товар
    |    , Вложенный.Период1 _День
    |    , sum(Вложенный.Остаток1) _Остаток
    |    , sum(Вложенный.ОборотКол1)    _ОборотКол
    |    , sum(0) _Дни
    |    , sum(Вложенный.Флаг1) _Флаг
    |
    |FROM (
        |SELECT
        |        ТовОстаткиОбороты.Товар Товар1
        |    ,    NullIf(ТовОстаткиОбороты.Период, '17530101') Период1
        |    ,    sum(ТовОстаткиОбороты.ОстатокТовараКонечныйОстаток) Остаток1
        |    ,    min(0) ОборотКол1
        |    ,    min(1) Флаг1
        |
        |FROM $РегистрОстаткиОбороты.ОстаткиТоваров(:НачДата,
        |        :КонДата~,
        |        День,
        |        ДвиженияИГраницыПериода,,"+?(флНуженФильтрПоСкладу <> 0,"(Склад IN (SELECT val FROM #mytemptableFilterSklad))","")+?(флНуженФильтрПоТовару<>0,?(флНуженФильтрПоСкладу <> 0," AND ","")+"(Товар IN (SELECT val FROM #mytemptableFilterTovar))","")+",(Товар),(ОстатокТовара)) AS ТовОстаткиОбороты With (NOLOCK)
        |GROUP BY
        |    ТовОстаткиОбороты.Товар, NullIf(ТовОстаткиОбороты.Период, '17530101')
        |
        |UNION ALL
        |
        |SELECT
        |    $Продажи.Товар _Товар
        |    , NullIf(Cast(Left(Продажи.DATE_TIME_IDDOC, 8) AS datetime), '17530101') Документ_дата
        |    , min(0) _Остаток
        |    , sum($Продажи.Количество) ОборотКол
        |    , min(0) Флаг
        |
    |FROM $Регистр.Продажи AS Продажи With (NOLOCK)
    |    INNER JOIN    $Справочник.Магазины AS СпрМаг With (NOLOCK) ON $СпрМаг.Клиент = $Продажи.Клиент
    |WHERE (Продажи.DATE_TIME_IDDOC  between :НачДата AND :КонДата~) "+?(флНуженФильтрПоСкладу <> 0," AND ($СпрМаг.Склад IN (SELECT val FROM #mytemptableFilterSklad))","")+?(флНуженФильтрПоТовару<>0," AND ($Продажи.Товар IN (SELECT val FROM #mytemptableFilterTovar))","")+"
    |GROUP BY $Продажи.Товар, NullIf(Cast(Left(Продажи.DATE_TIME_IDDOC, 8) AS datetime), '17530101')
    |) AS Вложенный
    |GROUP BY
    |    Вложенный.Товар1, Вложенный.Период1
    |";
    
    рс.УстановитьТекстовыйПараметр("НачДата", Дата1);
    рс.УстановитьТекстовыйПараметр("КонДата", Дата2);
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    Если ((флНужныДанные8 <> 0) ИЛИ (фМФСклад.РазмерСписка() > 1)) И (Макс(Дата1, ДатаРазделения8) <= Дата2) Тогда
        Состояние("Средние продажи по магазину (УТ 11)");
        ЗапросУТ = БазаУТ.NewObject("Запрос");
        ЗапросУТ.Текст = "
            |ВЫБРАТЬ
            |    ВЛОЖ.УИД КАК Товар,
            |    ВЛОЖ.День КАК День,
            |    СУММА(ВЛОЖ.Остаток) КАК Остаток,
            |    СУММА(ВЛОЖ.Продажа) КАК ОборотКол,
            |    СУММА(0) КАК Дни,
            |    СУММА(Флаг) КАК Флаг
            |ИЗ
            |(ВЫБРАТЬ
            |    Остатки.Номенклатура.УИД КАК УИД,
            |    Остатки.Период ДЕНЬ,
            |    Остатки.ВНаличииКонечныйОстаток Остаток,
            |    0 Продажа,
            |    1 КАК Флаг
            |ИЗ
            |    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(
            |            &д1,
            |            КонецПериода(&д2, ДЕНЬ),
            |            День,
            |            ДвиженияИГраницыПериода,
            |            "+?(фМФСклад.РазмерСписка()=1,"Склад = &Склад","") +"
            |                И Номенклатура.УИД В (&СписокТоваров)) КАК Остатки
            |                
            |ОБЪЕДИНИТЬ ВСЕ
            |
            |ВЫБРАТЬ
            |    Выручка.АналитикаУчетаНоменклатуры.Номенклатура.УИД КАК УИД,
            |    Выручка.Период ДЕНЬ,
            |    0 Остаток,
            |    Выручка.КоличествоОборот КАК Продажа,
            |    0 КАК Флаг
            |ИЗ
            |    РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(
            |            &д1,
            |            КонецПериода(&д2, ДЕНЬ),
            |            День,
            |            АналитикаУчетаНоменклатуры.Номенклатура.УИД В (&СписокТоваров)
            |                "+?(фМФСклад.РазмерСписка()=1,"И АналитикаУчетаНоменклатуры.Склад = &Склад","") +") КАК Выручка
            |) ВЛОЖ
            |СГРУППИРОВАТЬ ПО
            |    ВЛОЖ.УИД, ВЛОЖ.День
            |";        
        
        ЗапросУТ.УстановитьПараметр("СписокТоваров", СписокТоваровУТ);
        ЗапросУТ.УстановитьПараметр("Склад",             СкладУТ);
        ЗапросУТ.УстановитьПараметр("д1",             Макс(Дата1, ДатаРазделения8));
        ЗапросУТ.УстановитьПараметр("д2",             Дата2);
        
        Выборка = ЗапросУТ.Выполнить().Выгрузить();
        
        ВремТЗ = СоздатьОбъект("ТаблицаЗначений");
        ВремТЗ.НоваяКолонка("Товар",        "Строка", 9);
        ВремТЗ.НоваяКолонка("День",        "Дата");
        ВремТЗ.НоваяКолонка("Остаток",    "Число");
        ВремТЗ.НоваяКолонка("ОборотКол",    "Число");
        ВремТЗ.НоваяКолонка("Дни",        "Число");
        ВремТЗ.НоваяКолонка("Флаг",        "Число");
        
        Для СчСтр = 0 По Выборка.Количество() - 1 Цикл
            Стр = Выборка.Получить(СчСтр);
            ВремТЗ.НоваяСтрока();
            ВремТЗ.Товар        = Стр.Товар;
            ВремТЗ.День            = Стр.День;
            ВремТЗ.Остаток        = Стр.Остаток;
            ВремТЗ.ОборотКол    = Стр.ОборотКол;
            ВремТЗ.Дни            = Стр.Дни;
            ВремТЗ.Флаг            = Стр.Флаг;
        КонецЦикла;
        
        Стр = "";
        Выборка = "";
        ЗапросУТ = "";
    
        рс.Подготовить("INSERT INTO #mytemptableSrednie2 VALUES(?, ?, ?, ?, ?, ?)");
        рс.ВыполнитьSQL_ИзТЗ(ВремТЗ);
        
        ВремТЗ = "";        
        
    КонецЕсли;
        
    ТекстЗапроса = "
    |INSERT INTO #mytemptableSrednie
    |SELECT
    |    Товар
    |    ,День
    |    , SUM(Остаток)        Остаток
    |    , SUM(ОборотКол)    ОборотКол
    |    , SUM(Дни)            Дни
    |    , SUM(Флаг)            Флаг
    |FROM
    |(SELECT
    |    Товар
    |    ,День
    |    ,Остаток
    |    ,ОборотКол
    |    ,Дни
    |    ,Флаг
    |FROM
    |    #mytemptableSrednie1
    |
    |UNION ALL
    |
    |SELECT
    |    Товар
    |    ,День
    |    ,Остаток
    |    ,ОборотКол
    |    ,Дни
    |    ,Флаг
    |FROM
    |    #mytemptableSrednie2) Влож
    |GROUP BY
    |    Товар, День
    |
    |DROP TABLE #mytemptableSrednie1
    |
    |DROP TABLE #mytemptableSrednie2
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ВремТЗ = СоздатьОбъект("ТаблицаЗначений");
    ВремТЗ.НоваяКолонка("Дата", "Дата");
    Для Сч = Дата1 По Дата2 Цикл
        ВремТЗ.НоваяСтрока();
        ВремТЗ.Дата = Сч;
    КонецЦикла;
    
    ТекстЗапроса = "
    |if (select object_id('tempdb..#mytemptableDate')) is NOT null DROP TABLE #mytemptableDate
    |
    |CREATE TABLE #mytemptableDate (
    |    День        datetime      DEFAULT '17530101' NOT NULL,
    |UNIQUE CLUSTERED (День))
    |";
    
    рс.ВыполнитьСкалярный(ТекстЗапроса);    
    
    рс.Подготовить("INSERT INTO #mytemptableDate VALUES(?)");
    рс.ВыполнитьSQL_ИзТЗ(ВремТЗ);    
    
    ВремТЗ = "";
    
    ТекстЗапроса = "
        |INSERT INTO #mytemptableSrednie (Товар, День)
        |SELECT B.Товар, A.День
        |FROM #mytemptableDate A
        |CROSS JOIN    (SELECT DISTINCT Товар FROM #mytemptableSrednie) B
        |WHERE NOT Exists(SELECT * FROM #mytemptableSrednie WHERE #mytemptableSrednie.Товар = B.Товар AND #mytemptableSrednie.День = A.День)
        |";
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ТекстЗапроса = "
        |DECLARE @n numeric(19,5)
        |DECLARE @s char(9)
        |SET @n = 0
        |SET @s = $ПустойИд
        |
        |UPDATE #mytemptableSrednie
        |SET @n = CASE WHEN (Остаток = 0) AND (Товар = @s) AND (Флаг = 0) THEN @n ELSE Остаток END,
        |    Остаток = @n,
        |    Дни = CASE WHEN ((@n <> 0) OR (ОборотКол <> 0)) THEN 1 ELSE 0 END,
        |    @s = Товар
        |";
        
    рс.ВыполнитьСкалярный(ТекстЗапроса);
    
    ТекстЗапроса = "
        |SELECT
        |    Товар          Товар
        |,    sum(Дни)       Дни
        |,    sum(ОборотКол) ОборотКол
        |FROM
        |    #mytemptableSrednie
        |GROUP BY
        |    Товар";
    
    Результат = рс.ВыполнитьИнструкцию(ТекстЗапроса);
    рс.ВыполнитьСкалярный("DROP TABLE #mytemptableSrednie");
    
    Возврат Результат;
    
КонецФункции
5 Lacoster
 
14.11.13
08:34
(4) Идея интересная. Вот только где у тебя такое что если товар пришел сегодня и сегодня его весь продали?
6 dk
 
14.11.13
08:43
(5) там же есть объединение с продажами - так что строчка должна быть, хотя я такую ситуацию не рассматривал подробно
7 Mikeware
 
14.11.13
08:45
Да возьмите вы ОстаткиОбороты в разрезе дня, получите количество дней где есть остатки и/или движения.
8 dk
 
14.11.13
08:46
Дни = CASE WHEN ((@n <> 0) OR (ОборотКол <> 0)) THEN 1 ELSE 0 END
вот тут единичка в день пишется если есть остаток или был оборот (продажа)
9 dk
 
14.11.13
08:47
(7) если нет движений, то этот день пропустит
10 Lacoster
 
14.11.13
08:50
(9) неа, не пропустит. Он остаток тогда достанет. (7) походу дела это то что нужно. Щас попробую
11 dk
 
14.11.13
09:00
(10) видимо у меня какие-то неправильные ОстаткиОбороты ))
http://savepic.su/3847304.png
12 Dolly_EV
 
14.11.13
09:05
(10)
Класс "ПрямойЗапрос" ВТ РегистрОстаткиОбороты:
$РегистрОстаткиОбороты
Синтаксис: $РегистрОстаткиОбороты.<ИмяРегистра>(НачалоПериода, КонецПериода, Периодичность, МетодДополнения, Условие, Измерения, Ресурсы, Соединения)
....
•    Периодичность – Тип: Строка. Значение периодичности. Возможные значения: Период|Документ|День|Неделя|Месяц|Квартал|Год [ДОПОЛНЕНИЕ]. ЕСЛИ ПОСЛЕ ПЕРИОДИЧНОСТИ ДОБАВЛЕНА КОМАНДА «ДОПОЛНЕНИЕ», ИТОГОВАЯ ТАБЛИЦА БУДЕТ СОДЕРЖАТЬ ВСЕ ПЕРИОДЫ ВХОДЯЩИЕ В ТАБЛИЦУ, А НЕ ТОЛЬКО ТЕ КОТОРЫЕ ИМЕЛИ ОСТАТКИ И/ИЛИ ОБОРОТЫ. Дополнение невозможно по периодичности: Период, Документ. Для метода дополнения «Движения» параметр «Дополнение» игнорируется. По умолчанию: Период.

Слово "ДОПОЛНЕНИЕ" = то, что тебе и нужно....
13 Dolly_EV
 
14.11.13
09:09
(11) возьми класс "ПрямойЗапрос" - там "правильные" ОстаткиОбороты))
14 dk
 
14.11.13
09:11
(12) а есть пример с этим дополнением - у меня на синтаксис матерится
15 Lacoster
 
14.11.13
09:15
(11) подскажи что за дополнение на скрине изображено такое для запросов?
16 Dolly_EV
 
14.11.13
09:18
Это класс "ПрямойЗапрос", парсер. Не родной 1C++
http://www.1cpp.ru/forum/YaBB.pl?num=1273512019/0
17 dk
 
14.11.13
09:23
(16) а отличий от 1с++ много?
т.е. запустятся запросы написанные для 1с++ на прямом запросе?
18 Ёпрст
 
14.11.13
09:26
(17) нет, там другой синтаксис.. аля снеговик.
19 dk
 
14.11.13
09:28
(15) консоль запросов 1с++
вроде эта http://infostart.ru/public/15517/
20 dk
 
14.11.13
09:30
тогда останемся на 1с++
21 Dolly_EV
 
14.11.13
10:40
(17)(18)(20) Запустятся. При выполнении есть параметр "БезПодготовки", тогда текст запроса не парсится и отправляется как есть на выполнение.
Вся красота класса - кроссплатформенность. Ты пишешь для СКЛь и ДБФ одно и то же. Класс сам парсит или под СКЛь или под 1SQLite
22 Dolly_EV
 
14.11.13
10:41
(17) Да и как бы ничто не мешает, использую класс "ПрямойЗапрос", параллельно писать просто под 1C++
23 Lacoster
 
14.11.13
12:27
Получилось сделать проще
|SELECT Ном.ID [Элемент $Справочник.Номенклатура]
        |    , Dat1.Dat День
        |   , IsNull(Sum(Выборка.КонОст),0) Остаток
        |FROM $Справочник.Номенклатура AS Ном With (NOLOCK)
        |   Full Outer Join Dat_  As Dat1
        |                         On  1=1  
        |    Left OUTER JOIN
        |      (SELECT ОстаткиТМЦОстаткиОбороты.Номенклатура Номенк
        |       , ОстаткиТМЦОстаткиОбороты.Период Период
        |       , SUM(ОстаткиТМЦОстаткиОбороты.КоличествоКонечныйОстаток) КонОст
        |       FROM $РегистрОстаткиОбороты.ОстаткиТМЦ(:НачДата,
        |       :КонДата~,
        |       День,
        |       ДвиженияИГраницыПериода,,
        |       --(Номенклатура = :ВыбНоменклатура)
        |       (Номенклатура = :ВыбНом)
        |          And (Склад = :ВыбСклад),
        |        Номенклатура,) AS ОстаткиТМЦОстаткиОбороты
        |       GROUP BY ОстаткиТМЦОстаткиОбороты.Номенклатура
        |       , ОстаткиТМЦОстаткиОбороты.Период) As Выборка  
        |                     On (Выборка.Номенк = Ном.Id) And (Dat1.Dat=Выборка.Период)
        |   Left outer join $Справочник.СлужебныйОбщий As СпрСлОбщ On СпрСлОбщ.ParentExt = Ном.Id
        |                                             And $СпрСлОбщ.Склад = :ВыбСклад
        |WHERE (Ном.Id = :ВыбНом)
        |      -- (Ном.ID = :ВыбНоменклатура)
        |GROUP BY Ном.ID, Ном.Descr, Dat1.Dat, $Ном.МинОстаток, $СпрСлОбщ.НормаПодтоварки
        |Order By Ном.Descr, Dat1.Dat
        |";
Но тут пока по 1 номенклатуре, но список засунуть ничего не стоит
24 Lacoster
 
15.11.13
07:55
Коллеги! Я был не прав. (23) не работает так как нужно.
Вот верное решение которое отработало на отлично!
запрос=СоздатьОбъект("ПрямойЗапрос");
    текстЗапросаЗапроса="
    | select
    |РегистрОстаткиОбороты.Номенклатура [Номенк $Справочник.Номенклатура]
    |     ,   РегистрОстаткиОбороты.НачалоПериода Период
    |       , РегистрОстаткиОбороты.КоличествоКонечныйОстаток КонОст
    |       from $РегистрОстаткиОбороты.ОстаткиТМЦ(:НачДата,
    |       :КонДата~,
    |       День Дополнение,
    |       ДвиженияИГраницыПериода,
            |       (Номенклатура in (Select val from #СписокНоменклатуры))
    |          And (Склад = :ВыбСклад)
    |,
    |        (Номенклатура),(Количество)) РегистрОстаткиОбороты
    |";
    Запрос.Текст = текстЗапросаЗапроса;
    Запрос.УстановитьТекстовыйПараметр("НачДата",НачДата);
    Запрос.УстановитьТекстовыйПараметр("КонДата",КонДата);
    Запрос.УстановитьТекстовыйПараметр("ВыбНом",ВыбНом);
    Запрос.УстановитьТекстовыйПараметр("ВыбСклад",Скл);
    Запрос.УложитьСписокОбъектов(СписокНом,"#СписокНоменклатуры");
    Запрос.УложитьСписокОбъектов(СписокСкладов,"#СписокСкладов");
    //Запрос.РежимОтладки = 1;
    ИТЗ = Запрос.Выполнить();
    ИТЗ.ВыбратьСтроку();
25 Mikeware
 
15.11.13
08:36
(24) о чем и было сказано сутки назад.
26 dk
 
15.11.13
08:47
синтаксис вроде такой же как в 1с++, я разницы не вижу что-то
27 Lacoster
 
15.11.13
10:00
(26)  |       День Дополнение,
вот вся разница в этом