8.х Как написать запрос с глубокой входимостью запрашиваемых данных

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем selig, 7 мар 2014.

  1. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Доброго времени суток!
    ВНИМАНИЕ: голодным людям или перед обедом дальше лучше не читать (сам сижу пишу это перед обедом) - дальше будет много упоминаний о еде :)


    Вообщем такое безобразие:
    Необходимо написать запрос для последующей обработки в СКД. Конфигурация полностью самописная, служит для составления рецептур блюд. В конфигурации 2 основных справочника: "Сырье" и "Рецептура". Сырье сидит в табличной части "Состав" рецептур. В силу рецепта в составе сырьем может служить другое блюдо (в конфигурации - другая рецептура, соответственно реквизит табличной части составного типа). Так вот таких входимостей может быть несколько (см ниже).
    [​IMG]
    И создается документ "Расход сырья"(см. ниже), по которому затем формируется отчет нормированный расход сырья - нужен расход именно по сырью.
    [​IMG]
    Сформировал запрос который пока выводит лишь до первого уровня.
    Код:
    ВЫБРАТЬ
        РецептураСостав.НаименованиеПродукта КАК Сырье,
        СУММА(РецептураСостав.БРУТТО * РасходСырьяПродукция.Количество / РецептураСостав.Ссылка.КоличествоВыходаБлюд) КАК Расход,
        СУММА(РецептураСостав.Цена * РасходСырьяПродукция.Количество / РецептураСостав.Ссылка.КоличествоВыходаБлюд) КАК Сумма
    ИЗ
        Документ.РасходСырья.Продукция КАК РасходСырьяПродукция
            ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Рецептура.Состав КАК РецептураСостав
            ПО РасходСырьяПродукция.Блюдо = РецептураСостав.Ссылка
    ГДЕ
        РасходСырьяПродукция.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
        И РасходСырьяПродукция.Ссылка.НомерСтоловой = &НомерСтоловой
    
    СГРУППИРОВАТЬ ПО
        РецептураСостав.НаименованиеПродукта


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

    Заранее благодарен!

    Вложения:

    • 2342343.png
      2342343.png
      Размер файла:
      96,1 КБ
      Просмотров:
      50
    • 4545454.png
      4545454.png
      Размер файла:
      14,5 КБ
      Просмотров:
      7
  2. Thelearning
    Offline

    Thelearning Профессионал в 1С Команда форума

    Регистрация:
    9 сен 2010
    Сообщения:
    701
    Симпатии:
    72
    Баллы:
    54
    Это задача по разузлованию номенклатуры. Посмотрите в интернете есть несколько решений, но одним запросом я не видел чтобы делали. Можно рекурсией. Можно в цикле менять текст запроса подставляя в него новые таблицы.
    selig нравится это.
  3. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.410
    Симпатии:
    316
    Баллы:
    104
    Насчет "прям в запросе" - не уверен, что оно получится (или что рационально).
    Типовая конфигурация под рукой есть (КА, УПП)? Там для подобных целей есть хорошая функция РазузлованиеНоменклатуры.РазузловатьНоменклатуру().
    selig нравится это.
  4. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Под рукой только Бухгалтерия 2.0 и там нету.

    Ну тогда буду делать в цикле/рекурсии.
  5. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Возникла небольшая проблема, подскажите пожалуйста
    Код:
    Процедура СосчитатьКолвоСырьяРекурсия()
       
        СырьеСписок.Очистить();
        Для Каждого ТекСтрокаПродукция Из Продукция Цикл
            Для Каждого ТекСтрокаБлюдо Из ТекСтрокаПродукция.Блюдо.Состав Цикл
                Если ТипЗнч(ТекСтрокаБлюдо.НаименованиеПродукта) = Тип("СправочникСсылка.Сырье") Тогда
                    НоваяСтрока            = СырьеСписок.Добавить();
                    НоваяСтрока.Сырье      = ТекСтрокаБлюдо.НаименованиеПродукта;
                    НоваяСтрока.Количество = ТекСтрокаБлюдо.НЕТТО * ТекСтрокаПродукция.Количество / ТекСтрокаПродукция.Блюдо.КоличествоВыходаБлюд;
                КонецЕсли;
                Если ТипЗнч(ТекСтрокаБлюдо.НаименованиеПродукта) = Тип("СправочникСсылка.Рецептура") Тогда
                    Коэффцнт = ТекСтрокаБлюдо.НЕТТО * ТекСтрокаПродукция.Количество / (ТекСтрокаПродукция.Блюдо.КоличествоВыходаБлюд * ПолучитьВесВКг(ТекСтрокаПродукция.Блюдо.Вес));
                    РазузловатьРецептуру(Знач Коэффцнт, ТекСтрокаБлюдо.НаименованиеПродукта.Состав, ТекСтрокаБлюдо.НаименованиеПродукта);   
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;        
    КонецПроцедуры
    
    Ошибка:
    {Документ.РасходСырья.Форма.ФормаДокумента.Форма(154,26)}: Ожидается выражение
    РазузловатьРецептуру(<<?>>Знач Коэффцнт, ТекСтрокаБлюдо.НаименованиеПродукта.Состав, ТекСтрокаБлюдо.НаименованиеПродукта); (Проверка: Толстый клиент (обычное приложение))
    {Документ.РасходСырья.Форма.ФормаДокумента.Форма(154,5)}: Недостаточно фактических параметров (РазузловатьРецептуру)
    <<?>>РазузловатьРецептуру(Знач Коэффцнт, ТекСтрокаБлюдо.НаименованиеПродукта.Состав, ТекСтрокаБлюдо.НаименованиеПродукта); (Проверка: Толстый клиент (обычное приложение))


    ну и соответственно процедура вызываемая

    Код:
    Процедура РазузловатьРецептуру(Коэффцнт, Таблица, ОбъектВладелец)   
       
        Для Каждого ТекСтрока Из Таблица Цикл
           
            Если ТипЗнч(ТекСтрока.НаименованиеПродукта) = Тип("СправочникСсылка.Сырье") Тогда
                НоваяСтрока            = СырьеСписок.Добавить();
                НоваяСтрока.Сырье      = ТекСтрока.НаименованиеПродукта;
                НоваяСтрока.Количество = Коэффцнт * ТекСтрока.НЕТТО/(ОбъектВладелец.КоличествоВыходаБлюд * ПолучитьВесВКг(ОбъектВладелец.Вес));
            КонецЕсли;
           
            Если ТипЗнч(ТекСтрока.НаименованиеПродукта) = Тип("СправочникСсылка.Рецептура") Тогда
                Коэффцнт = Коэффцнт * ТекСтрока.НЕТТО/(ОбъектВладелец.КоличествоВыходаБлюд * ПолучитьВесВКг(ОбъектВладелец.Вес));
                РазузловатьРецептуру(Знач Коэффцнт, ТекСтрока.НаименованиеПродукта.Состав, ТекСтрока.НаименованиеПродукта);   
            КонецЕсли;  
     
        КонецЦикла;   
             
    КонецПроцедуры
    
    Ошибка:
    {Документ.РасходСырья.Форма.ФормаДокумента.Форма(75,25)}: Ожидается выражение
    РазузловатьРецептуру(<<?>>Знач Коэффцнт, ТекСтрока.НаименованиеПродукта.Состав, ТекСтрока.НаименованиеПродукта); (Проверка: Толстый клиент (обычное приложение))
    {Документ.РасходСырья.Форма.ФормаДокумента.Форма(75,4)}: Недостаточно фактических параметров (РазузловатьРецептуру)
    <<?>>РазузловатьРецептуру(Знач Коэффцнт, ТекСтрока.НаименованиеПродукта.Состав, ТекСтрока.НаименованиеПродукта); (Проверка: Толстый клиент (обычное приложение))
  6. nbIpKuH_BaH9I
    Online

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.989
    Симпатии:
    399
    Баллы:
    104
    Знач уберите в заголовок процедуры.
  7. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Убрать в заголовок процедуры?
    В смысле так?
    Код:
    Процедура РазузловатьРецептуру(Знач Коэффцнт, Таблица, ОбъектВладелец)
    те же ошибки
  8. nbIpKuH_BaH9I
    Online

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.989
    Симпатии:
    399
    Баллы:
    104
    Ну из вызова надо это убрать...
  9. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Так вот мне именно значение нужно передать. Иначе он перемножится лишнего и ...
  10. nbIpKuH_BaH9I
    Online

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.989
    Симпатии:
    399
    Баллы:
    104
    Слово Знач в процедуре уже подразумевает что передается по значению туда параметр.
  11. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Вы меня окончательно запутали
  12. nbIpKuH_BaH9I
    Online

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.989
    Симпатии:
    399
    Баллы:
    104
    Когда в процедуре указываете знач, то значение параметра передается по значению. Пример:
    Код:
    Процедура РазузловатьРецептуру(Знач Коэффициент)
    В месте вызова этой процедуры след код.
    Код:
    Коэффициент = 10;
    РазузловатьРецептуру(Коэффициент);
    Так вот. В процедуру будет передано только значение коэффициента, т.е. 10. Если в процедуре вы будете менять переменную Коэффициент, то она не поменяется вне этой процедуры, а если без Знач, то поменяется.
  13. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Знач
    Необязательное ключевое слово, которое указывает на то, что следующий за ним параметр передается по значению, т.е. изменение значения формального параметра при выполнении процедуры никак не повлияет на фактический параметр, переданный при вызове процедуры. Если это ключевое слово не указано, то параметр процедуры передается по ссылке, то есть изменение внутри процедуры значения формального параметра приведет к изменению значения соответствующего фактического параметра.

    Это я знаю и именно мне только значение и нужно передавать. Вопрос: почему "Знач" при вызове процедуры выдает ошибку?
  14. nbIpKuH_BaH9I
    Online

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.989
    Симпатии:
    399
    Баллы:
    104
    Да не надо там знач писать...
    --- Объединение сообщений, 17 мар 2014 ---
    Синтаксис соблюдайте.
    selig нравится это.
  15. TopicStarter Overlay
    selig
    Offline

    selig Опытный в 1С

    Регистрация:
    30 май 2012
    Сообщения:
    50
    Симпатии:
    0
    Баллы:
    26
    Теперь понятно :)

Поделиться этой страницей