Разработка и оптимизация запросов в 1С:Предприятие 8.3. Модуль 7. Использование виртуальных таблиц в запросе

На данной странице задавайте вопросы по материалам и практическим заданиям седьмого модуля курса «Разработка и оптимизация запросов в 1С:Предприятие 8.3».

Практические задания

К сожалению, у Вас недостаточно прав для дальнейшего просмотра.

Если Вы приобрели курс, но еще не активировали токен — пожалуйста, активируйте доступ по инструкциям, высланным на Ваш email после покупки.

Если Вы не залогинены на сайте — залогиньтесь, вернитесь на эту страницу и обновите ее.

Если Вы залогинены, у Вас активирован токен доступа, но Вы все равно видите эту запись — напишите нам на e-mail поддержки.

Комментарии / обсуждение (488):

  1. naticun

    Здравствуйте, можно ли 24 задание выполнить так:

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

    люблю я с вложенными запросами работать..)

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  2. Кирилл Абрашин

    Добрый день!

    Василий, вот как вопрос у меня возник при решение 24 задания. Я пошёл тем же путём, что Igor и Панфилов Александр — соединил таблицу ЦеныНоменклатуры.СрезПоследних саму с собой полным соединением по номенклатуре. И «для красоты» решил попытаться привести процент наценки к формату ЧИСЛО(2,2). В итоге запрос не выдаёт ни одной строки. Если удалить функцию ВЫРАЗИТЬ из запроса, то отрабатывает нормально. В чём причина такого поведения?

    Вот запрос, который не выводит ни одной строки:
    ВЫБРАТЬ
    АктуальныеЗакупочныеЦены.Номенклатура КАК Номенклатура,
    ЕСТЬNULL(АктуальныеЗакупочныеЦены.Цена, 0) КАК ЦенаЗакупочная,
    ЕСТЬNULL(АктуальныеРозничныеЦены.Цена, 0) КАК ЦенаРозничная,
    ВЫБОР
    КОГДА ЕСТЬNULL(АктуальныеЗакупочныеЦены.Цена, 0) = 0
    ТОГДА «Бесконечно»
    ИНАЧЕ
    выразить((100 * (ЕСТЬNULL(АктуальныеРозничныеЦены.Цена, 0) — ЕСТЬNULL(АктуальныеЗакупочныеЦены.Цена, 0)) / ЕСТЬNULL(АктуальныеЗакупочныеЦены.Цена, 0)) как число(2,2))
    КОНЕЦ
    КАК ПроцентНаценки
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦенЗакупочный) КАК АктуальныеЗакупочныеЦены
    ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦенРозничный) КАК АктуальныеРозничныеЦены
    ПО (АктуальныеЗакупочныеЦены.Номенклатура = АктуальныеРозничныеЦены.Номенклатура)

    И второй вопрос, общий. В моей консоли запросов для управляемого приложения почему-то никогда не указывается количество строк. Скачал её с сайта ИТС. Может, известная ошибка? Честно, просто лень с ней разбираться, вдруг решение уже известно?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  3. IpotekaLand

    Добрый день. Вопрос по заданию №27 Модуль7.
    1) Наверное — решение в видео не полное т.к. в условии Задачи говориться что нужно «создать отчет, который будет выводить в табличный документ сведения о продажах за указанный пользователем ПЕРИОД»
    как я понимаю на форме должен появиться реквизит — Стандартный период и в зависимости от выбора у нас будут получаться разные сумма по Услуге и Товарам.
    2) Да и не как не получается задать Условие в таблице Продажи.ОБороты, чтобы обойтись без параметра «&товар» или «&услуга», чтобы у нас сразу суммирование происходило по Товарам и по Услуге (на уровне Запроса).

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  4. also11

    Здравствуйте!
    Хотел вернуться к Вашему ответу от 30.11.2015 по заданию 28
    Все же интересно, какой запрос — Ваш или приведенный, более корректен (производителен).
    И последнее, как же все-таки бороться с погрешностью?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  5. Lucia_

    Добрый день!
    Посмотрела таблицы физические в базе для регистра сведения. Поставила обе галочки: разрешить итоги для среза первых и последних. Увидела таблицы новые в базе данных. Все понятно вроде. Поэкспериментировала с запросами, увидела, как преобразуется запрос из запроса 1С в SQL, и какая таблица берется в тех или иных случаях. Не поняла одного, что за таблица «Таблица настроек хранения итогов регистра сведений»? Данных в ней никаких нет.

    • Lucia_

      Кажется, я сама нашла что это. Выключила использование итогов у этого регистра, в указанной таблице появилась строка с нулевым значением. После чего попытка посмотреть какой-либо срез заканчивается пустой выборкой.
      Только теперь не понятно, зачем это может понадобится в практике?

      И еще вопрос. Получается, что если я думаю, что придется часто запрашивать некие срезы, то для оптимизации этого процесса лучше использовать итоги для данного регистра (с созданием доп. таблиц на физ. уровне). А с какой целью это отдано на откуп разработчика? Чтобы не плодить таблицы под все регистры сведений?

      • Василий Ханевич


        (текст комментария доступен только участникам Мастер-группы)

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  6. AxiLLes

    День добрый)
    По заданию 28:

    Нашел интересное решение задачи, учитывая особенности виртуальной таблицы:

    выбрать
        ПродажиПоТоварам.Номенклатура,
        ПродажиПоТоварам.КоличествоОборот КоличествоТовар,
        //ПродажиОбщие.КоличествоОборот КоличествоОбщее,
        ПродажиПоТоварам.КоличествоОборот/ПродажиОбщие.КоличествоОборот*100 Процент
    Из
        РегистрНакопления.Продажи.Обороты ПродажиПоТоварам
        Левое Соединение
        РегистрНакопления.Продажи.Обороты ПродажиОбщие
        По
        Истина
    Итоги Сумма(КоличествоТовар), Сумма(Процент) По Общие, ПродажиПоТоварам.Номенклатура   
    ;

    запрос получает нужный результат, но такой текст запроса неустойчив скорее всего?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  7. AxiLLes

    День добрый)
    Вопрос по заданию 27. Использование объединений в запросах.

    Правильно ли понимаю что данное задание оптимальнее сделать не используя объединения, а используя конструкцию «выбор когда»?

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

    СГРУППИРОВАТЬ ПО
        ПродажиОбороты.Контрагент

    Причины:
    1) Обращаемся к вирутальной таблице 1 раз
    2) Если можно задачу выполнить одним запросом пакета, без использования ВТ, то это нужно делать

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  8. AxiLLes

    Вечер добрый)
    В параметрах виртуальной таблицы «ДвиженияССубконто» есть разделы упорядочивание и первые.
    1) Получается мы можем уже в параметрах виртуальной таблицы сказать, что нам нужны первые Н записей вот в таком порядке?
    2) Почему только для этой таблицы существуют такие настройки? Связано с частой практической необходимостью?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  9. noffkj

    День добрый, Василий.
    Помогите разобраться чем отличается ВТ РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт от РегистрБухгалтерии.Хозрасчетный.Обороты ?

    вот я сделал простой запрос

    ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.СчетДт,
    ХозрасчетныйОборотыДтКт.СуммаОборот
    ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&ДАта1, &Дата2Граница, , СчетДт = &Счет, , , , Организация = &Организация) КАК ХозрасчетныйОборотыДтКт

    Счет = 51

    В данном случае СуммаОборот это оборотДТ. то есть какой бы я счет не поставил в параметры СчетДТ, СуммаОборот всегда будет оборотДТ? я правильно понимаю?

    если я сделаю такой запрос.

    ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.СчетДт,
    ХозрасчетныйОборотыДтКт.СуммаОборот
    ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&ДАта1, &Дата2Граница, , СчетДт = &Счет, , СчетКт = &СчетКт, , Организация = &Организация) КАК ХозрасчетныйОборотыДтКт

    счетКТ = 60.01

    то СуммаОборот будет Дт оборот 51 счета в корр с 60.01 я прав?

    тогда чтобы мне получить оборот по кт 51 счета мне нужно счета поменять местами?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • noffkj

        И все таки мне не понятно «А в таблице оборотов второй счет можно не указывать.» так и в ОборотыДтКт, Кт счета можно не указывать. можно собственно вобще не указывать счетА ни там ни там и в итоге в запросе к этой таблице ОборотыДтКт в ресурсе СуммаОборот мы увидим все обороты по дт . Тоже самое мы получим и с вт. Обороты выведя ресурс СуммаОборотДТ.

        ВЫБРАТЬ
        ХозрасчетныйОборотыДтКт.СчетДт,
        ХозрасчетныйОборотыДтКт.СуммаОборот
        ИЗ
        РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&ДАта1, &Дата2Граница, , , , , , Организация = &Организация) КАК ХозрасчетныйОборотыДтКт

        и

        ВЫБРАТЬ
        ХозрасчетныйОбороты.Счет,
        ХозрасчетныйОбороты.СуммаОборотДт
        ИЗ
        РегистрБухгалтерии.Хозрасчетный.Обороты(&ДАта1, &Дата2Граница, , , , Организация = &Организация, , ) КАК ХозрасчетныйОбороты

        результат одинаковый.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  10. Igor

    «Момент времени однозначно определяет положение документа на временной оси». А на какое место временной оси укажет момент времени, если в нем выбранная дата не совпадает с датой документа по ссылке?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Igor

        Спасибо.
        «…так что указывать будет на эту отдельную дату, а не на дату из ссылки »
        В параметр вирт.таблицы остатков передаю момент времени (ссылку на документ и дату, бОльшую, чем дата документа по ссылке), но в результате все равно не попадают движения этого документа. Получается что в данном случае момент времени не смотрит на дату (первый свой параметр). Немного запутался.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

          • Igor

            Василий, извините. Сейчас все работает как вы и говорили. Наверное моя невнимательность или особенность консоли. Я менял значение даты прямо в колонке «Значение» в строке параметров — визуально все меняется, но реально при выполнении запроса учитывается предыдущее значение параметра. Когда значение меняешь, нажимая кнопку выбора — тогда все правильно работает.

            • Василий Ханевич


              (текст комментария доступен только участникам Мастер-группы)

  11. Igor

    День добрый, Василий.
    Покритикуйте, пожалуйста, мое решение 24-го задания (я его делал не через объединения):
    ВЫБРАТЬ
    Закуп.Номенклатура КАК Номенклатура,
    Закуп.Цена КАК Закупочная,
    Розница.Цена КАК Розничная,
    ВЫБОР
    КОГДА Закуп.Цена = 0
    ТОГДА 10000
    ИНАЧЕ Розница.Цена / Закуп.Цена * 100 — 100
    КОНЕЦ КАК ПроцентНаценки
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Розница) КАК Розница
    ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Закуп) КАК Закуп
    ПО (Закуп.Номенклатура = Розница.Номенклатура)

    Спасибо.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Igor

        Спасибо за комментарий. В операции выбора проверял на 0, чтобы не было ошибки деления. А вот если NULL — то никакой ошибки не возникало при делении на него.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  12. Igor

    Практическое задание 23.
    Чем обоснован выбор виртуальной таблицы СрезПоследних, а не основной таблицы для решения именно этой задачи? Ведь в условии сказано «когда-либо занимали», т.е. нам надо выбрать и отфильтровать все записи.
    Более того, если Мищенко до «Руководитель отдела закупок» работал в должности «Руководитель конструкторского отдела», то мы этого не увидим.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  13. Панфилов Александр

    Домашнее задание №27:
    «Необходимо создать отчет, который…»
    Я понял как создание не просто запроса, а полноценного внешнего отчета.

    «…о продажах за указанный пользователем период.»
    В решении преподавателя отсутствует. А хотелось бы заодно посмотреть и на варианты передачи параметров с клиента на сервер. Так же можно было бы коснуться и такой интересной детали как получение отчета за период с «открытой» датой…

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Панфилов Александр

        В одном из уроков преподаватель упомянул, что при указании периода необходимо конечную дату приводить к концу дня ( … 23:59:59 ). А в этом задании можно было закрепить это на практике:
        для запроса к регистру накопления
        «…РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , Номенклатура.ВидНоменклатуры = &Товар) КАК ПродажиОбороты…»

        указать:
        Запрос.УстановитьПараметр(«НачалоПериода», НачалоПериода);
        Запрос.УстановитьПараметр(«КонецПериода», ?(ЗначениеЗаполнено(КонецПериода), КонецДня(КонецПериода), Дата(1,1,1)));

        А ещё и добавить проверку, что конечная дата, если она указана (не Дата(1,1,1)), то ДОЛЖНА быть больше начальной… ))

        А со СтандартнымПериодом уже не так интересно, он сам всё отслеживает )))

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  14. spv

    Добрый день

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

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  15. spv

    Добрый день

    В виртуальной таблице Остатки дата остатков не включается в расчет, в таблице оборотов даты начала и окончания периода в расчет включаются.

    Для включения даты остатков в расчет для таблицы Остатки было рекомендовано использовать объект Граница, где ВидГраницы = Включая.

    Правильно ли я понимаю, что, если задать для таблицы оборотов границу со значением ВидГраницы = Исключая, то даты начала и окончания периода включаться в расчет не будут?

    Т.е. ообъектом Граница можно более тонко управлять поведением виртуальных таблиц, включая или исключая даты из расчета?

    Есть ли принципиальная разница между использованием объекта Граница со значением ВидГраницы = Включая/Исключая, и прибавлением/вычитанием секунды в исходной дате?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  16. spv

    Добрый день

    Требуется получать результату по группировкам в таком виде:

    СтатьяЗатрат, СУММА(СуммаОборотДт)
    Период для данной статьи, СУММА(СуммаОборотДт)

    Запрос:

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

    Выражение СУММА(СуммаОборотДт) по группировке Период не рассчитывает (нулевое).
    В чем может быть ошибка?

    Если переделать запрос
    (в ВЫБРАТЬ вместо
    ХозрасчетныйОбороты.СуммаОборотДт КАК СуммаОборотДт
    написать
    СУММА(ХозрасчетныйОбороты.СуммаОборотДт ) КАК СуммаОборотДт
    ), т.е.:

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

    то вообще выдает ошибку:
    «Поле не входит в группу ХозрасчетныйОбороты.Субконто1 ХозрасчетныйОбороты.Субконто1 ИЕРАРХИЯ»

    где тут нарушен синтаксис языка запросов, в чем причина ошибки?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • spv

        Да, не уровне статьи затрат числовые итоги имеются.
        А если вы развернете группировки до периодов (3 уровень), числовые итоги у вас тоже будут?
        У мена не было итогов именно по группировки Период (1й запрос), 3й уровень

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  17. vlad_u_mir

    Задание 23
    Мне кажется более эффективно использовать не КадроваяИсторияСрезПоследних, а просто регистр КадроваяИстория
    Например так:

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

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  18. annamv

    Добрый день!
    В запросе параметры виртуальной таблицы описаны следующим образом (из типовой конфигурации):
    РегистрБухгалтерии.»+ВидПланаСчетов+».Остатки(&Период, Счет = &Счет, , Истина = Истина …
    как понимать выражение «Истина = Истина»?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • annamv

        Добрый день!
        с замещением условий в запросе все понятно,
        но с условием в запросе нет (во вложении)

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  19. Игорь

    Добрый день. Вопрос по заданию №24, а можно для решения использовать такой запрос:
    ВЫБРАТЬ
    Розничные.Номенклатура КАК Товар,
    Закупочные.Цена КАК Закупочная,
    Розничные.Цена КАК Розничная,
    ВЫРАЗИТЬ((Розничные.Цена — Закупочные.Цена) / Закупочные.Цена * 100 КАК ЧИСЛО(15, 2)) КАК Процент
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Розничная) КАК Розничные
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Закупочная) КАК Закупочные
    ПО Розничные.Номенклатура = Закупочные.Номенклатура
    ?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Панфилов Александр

        «… в результат попадут только такие позиции, для которых установлены одновременно и закупочные, и розничные цены…»

        Хорошо, что Вы помните о том, что в регистре цен может быть не установлена закупочная цена! Однако в решении преподавателя НЕТ проверки во избежания деления на 0.

        ВЫБОР
        КОГДА ЕСТЬNULL(Цены_Закуп.Цена, 0) = 0
        ТОГДА 0
        ИНАЧЕ ВЫРАЗИТЬ((ЕСТЬNULL(Цены_Розница.Цена, 0) / Цены_Закуп.Цена — 1) * 100 КАК ЧИСЛО(10, 3))
        КОНЕЦ КАК ПроцентНаценки

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

    • Панфилов Александр

      1) Разумеется, здесь необходимо ПОЛНОЕ СОЕДИНЕНИЕ ! А для полного соединения не забудьте использовать ЕСТЬNULL !!
      ЕСТЬNULL(Цены_Закуп.Номенклатура, Цены_Розница.Номенклатура) КАК Номенклатура,
      ЕСТЬNULL(Цены_Закуп.Цена, 0) КАК ЦенаЗакуп,
      ЕСТЬNULL(Цены_Розница.Цена, 0) КАК ЦенаРозница,

      2) Не ясна методическая цель данного задания. Для ДАННОГО случая решение преподавателя выглядит избыточным. Вместо пакета из трёх запросов я бы использовал ОДНО соединение.

      • Василий Ханевич


        (текст комментария доступен только участникам Мастер-группы)

  20. AlexPC

    Вопрос по использованию параметров виртуальных таблиц.
    Предположим, есть регистр накопления типа остатки с тремя измерениями ссылочного типа (не составные).
    Соответственно, есть индекс по ним. Я хочу наложить отбор на виртуальную таблицу остатков по первому и третьему измерению.
    Рассуждая чисто логически, чтобы использовать индекс мне необходимо наложить условие и на второе измерение. Естественно, условие должно быть таким, чтобы записи с любыми данными во втором измерении попали в выборку. Вспоминаю, что вроде бы NULL никому не равен и накладываю условие Измерение2 не равно NULL. В результате в выборку не попали записи с незаполненным Измерением2. Из ситуации вышел, но хотелось быть понять: 1 — прав ли я в выводах относительно использования индекса, 2 — какое значение принимают измерения ссылочного типа (не составные) в записях регистров в случае если у них не заполнено значение.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • AlexPC

        Тогда я хотел бы понять почему при использовании отбора в параметрах виртуальной таблицы на измерение2 не равно null записи виртуальной таблицы отличаются от записей виртуальной таблицы без отбора, то есть грубо говоря остатки с отбором не равны остаткам без отборов при прочих равных. Оговорюсь сразу, что релиз платформы достаточно древний — 8.2.14.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

          • AlexPC

            Так вот в этом и вопрос — разве можно так преобразовывать запрос?
            У нас значение склад никогда не будет NULL, значит должна быть истина в этом выражении, а у нас получается ЛОЖЬ.
            Мой запрос сложный. Позволю себе вычленить его часть:

            ВЫБРАТЬ
                29111973 КАК Тест,
                ТоварыКПолучениюНаСкладыОстатки.Номенклатура,
                -ТоварыКПолучениюНаСкладыОстатки.КоличествоОстаток
            ИЗ
                РегистрНакопления.ТоварыКПолучениюНаСклады.Остатки(
                        ,
                        (ДокументРезерва <> НЕОПРЕДЕЛЕНО)
                        И (Склад <> NULL) И (ДокументПолучения <> NULL)
                        И Номенклатура В (&МассивНоменклатуры)
            ) КАК ТоварыКПолучениюНаСкладыОстатки

            план запроса:

            SELECT
            @P1,
            T1.Fld8151RRef,
            -(T1.Fld8157Balance_)
            FROM (SELECT
            T2._Fld8151RRef AS Fld8151RRef,
            CAST(SUM(T2._Fld8157) AS NUMERIC(32, 8)) AS Fld8157Balance_
            FROM _AccumRgT8159 T2 WITH(NOLOCK)
            WHERE T2._Period = @P2 AND (((((T2._Fld8155_TYPE <> @P3) AND 1=NULL) AND 1=NULL) AND (T2._Fld8151RRef IN (@P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16, @P17, @P18, @P19, @P20, @P21, @P22, @P23, @P24, @P25, @P26, @P27, @P28, @P29, @P30, @P31, @P32, @P33, @P34, @P35, @P36, @P37, @P38, @P39, @P40, @P41, @P42, @P43, @P44, @P45, @P46))))
            GROUP BY T2._Fld8151RRef
            HAVING (CAST(SUM(T2._Fld8157) AS NUMERIC(32, 8))) <> @P47) T1

            и я пришел к схожему выводу, что вот видимо это условие 1=NULL все убивает :) потому что запрос не возвращает записей. а такой же запрос без двух условий с NULL возвращает записи и это правильно.

            Попутно задам еще вопрос:
            будет ли более оптимальным разложить условие В (Параметр1, Параметр2, Параметр3) на три запроса с условиями = ПараметрХ и объединением результатов или SQL сервер сам справится с этим?

            В остальном запросы транслируются в СУБД одинаково и видимо планы их выполнения будут схожими.

            • Василий Ханевич


              (текст комментария доступен только участникам Мастер-группы)

  21. kamalion

    Добрый день!
    Немного не понял ситуацию с использованием флага Текущие итоги в настройках рассчета итогов.
    Возьмем ситуацию из книги в разделе «Устройство виртуальной таблицы»
    В настройках расчета итогов выставлен флаг Текущие итоги и последний рассчитанный период:31.03.2012
    Если мы берем дату, на которую нужно получить остатки, равную 17.04.1998. То каким образом будут рассчитываться итоги? Как я понял, возьмутся итоги на 01.11.3999 и все движения до 01.04.1998 По логике, оптимальнее будет использование предыдущих итогов перед 17.04.1998(при ежемесячном расчете получается это 30.03.1998). И стало быть, флаг Текущие итоги при получении остатков на даты далеко в прошлом лучше снимать?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • kamalion

        Василий, спасибо за подробный ответ. Теперь понятно. Возник еще вопрос:
        есть оборотный регистр накопления. Возможно ли в рамках одного запроса в параметр Начало периода виртуальной таблицы Обороты данного регистра передать значение даты, полученное ранее в этом же запросе? Т.е. мы получили дату, поместили во врем. таблицу и затем это значение помещаем в параметр Начальный период — и все это в одном запросе. Вообще, в параметры виртуальных таблиц можно передавать какие-нибудь значения без знака & ?

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  22. tekhneryadov

    Добрый день.
    Часто возникает необходимость передавать в параметры виртуальной таблицы набор полей, по которым нужно получить данные. Например, нужно получить из регистра накопления остатки по следующим парам «Товар-Склад»:
    Товар А — Склад 1;
    Товар В — Склад 2;
    Товар С — Склад 3;
    Не понимаю, почему текст 1 отрабатывает в несколько раз медленнее текста 2.
    Текст 1:
    (Товар, Склад) В (Выбрать вт.Товар, вт.Склад ИЗ ВременнаяТаблица КАК вт)
    Текст 2:
    Товар В (Выбрать вт.Товар ИЗ ВременнаяТаблица КАК вт) И Склад В (Выбрать вт.Склад ИЗ ВременнаяТаблица КАК вт)

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  23. enmelnik

    В задании №24 не очень понятно какие цены необходимо выбрать, существующие или по всем товарам? И не понятно зачем использовать объединение запросов, если можно обойтись левым соединением? У меня получился такой запрос:

    ВЫБРАТЬ
        Номенклатура.Ссылка КАК Товар
    ПОМЕСТИТЬ ВТ_Товары
    ИЗ
        Справочник.Номенклатура КАК Номенклатура
    ГДЕ
        НЕ Номенклатура.ЭтоГруппа
    ;

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ВТ_ЗакупочныеЦены.Товар,
        ЕСТЬNULL(ВТ_ЗакупочныеЦены.ЗакупочнаяЦена, 0) КАК ЗакупочнаяЦена,
        ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК РозничнаяЦена,
        ВЫРАЗИТЬ(ВЫБОР
                КОГДА ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) - ЕСТЬNULL(ВТ_ЗакупочныеЦены.ЗакупочнаяЦена, 0) = 0
                    ТОГДА 0
                ИНАЧЕ (ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) - ЕСТЬNULL(ВТ_ЗакупочныеЦены.ЗакупочнаяЦена, 0)) * 100 / ЕСТЬNULL(ВТ_ЗакупочныеЦены.ЗакупочнаяЦена, 0)
            КОНЕЦ КАК ЧИСЛО(15, 6)) КАК Наценка
    ИЗ
        ВТ_ЗакупочныеЦены КАК ВТ_ЗакупочныеЦены
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Розничная) КАК ЦеныНоменклатурыСрезПоследних
            ПО ВТ_ЗакупочныеЦены.Товар = ЦеныНоменклатурыСрезПоследних.Номенклатура
    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  24. DasTPID

    Добрый день!
    Неоднократно ловил себя на том, что мне гораздо проще вместо какого-то сложного соединения, отбора, условия в одном запросе сделать цепочку запросов со временными таблицами. Скажем, в практическом задании №22 у меня получился такой код:

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ВТ.Сотрудник,
        ВТ.Должность
    ИЗ
        ВТ КАК ВТ
    ГДЕ
        ВТ.Должность.Наименование ПОДОБНО "%руководитель%"

    И не нужно напрягаться вспоминать в данном конкретном случае следует ли условие подобно засовывать в параметры виртуальной таблицы или в секцию ГДЕ и т.п. По таким же соображениям я никогда не соединяю за один раз больше двух таблиц — если возникает такая задача то я соединяю две, кладу во временную таблицу и уже к ней присоединяю третью. Да, в теории быстродействие должно страдать, но если честно я такого не замечал, по крайней мере самый длинный мною написанный запрос, содержащий в себе порядка 30 временных таблиц, выполнялся достаточно быстро. Вот ещё один пример — моё решение задачи 24 — у вас две временные таблицы, у меня четыре, но мне мой код кажется нагляднее. Как считаете — имеет ли такой подход право на жизнь?

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ВТ.Номенклатура,
        ВЫБОР
            КОГДА ВТ.ТипЦен = &ТипЦенЗакупка
                ТОГДА ВТ.Цена
            ИНАЧЕ 0
        КОНЕЦ КАК ЗакупочнаяЦена,
        ВЫБОР
            КОГДА ВТ.ТипЦен = &ТипЦенРозница
                ТОГДА ВТ.Цена
            ИНАЧЕ 0
        КОНЕЦ КАК РозничнаяЦена
    ПОМЕСТИТЬ ВТ2
    ИЗ
        ВТ КАК ВТ
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ВТ2.Номенклатура,
        МАКСИМУМ(ВТ2.ЗакупочнаяЦена) КАК ЗакупочнаяЦена,
        МАКСИМУМ(ВТ2.РозничнаяЦена) КАК РозничнаяЦена
    ПОМЕСТИТЬ ВТ3
    ИЗ
        ВТ2 КАК ВТ2

    СГРУППИРОВАТЬ ПО
        ВТ2.Номенклатура
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
        ВТ3.Номенклатура,
        ВТ3.ЗакупочнаяЦена,
        ВТ3.РозничнаяЦена,
        (ВТ3.РозничнаяЦена - ВТ3.ЗакупочнаяЦена) / ВТ3.ЗакупочнаяЦена * 100 КАК ПроцентНаценки
    ИЗ
        ВТ3 КАК ВТ3

    И да, в практическом задании №23 виртуальная таблица, как мне кажется, вообще не нужна, я бы использовал просто ВЫБРАТЬ * ИЗ РегистрСведений.КадроваяИстория ГДЕ Должность.Наименование ПОДОБНО «%руководитель%»

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  25. Сергей Беляков

    Добрый день, Василий! Шестой модуль, первый урок «Использование временных таблиц». Правильно ли я себе представляю?
    1. Конструкцию МВТ = Новый МенеджерВременныхТаблиц, в принципе можно не использовать, НО созданная виртуальная таблица будет «жить» только в течении отработки того запроса, в котором она была создана.
    2 . Конструкция МВТ = Новый МенеджерВременныхТаблиц позволяет «жить» созданной виртуальной таблице в течении всей отработки процедуры. К созданной виртуальной таблице можно обратиться в другом (в рамках данной процедуры) запросе или запросах, но только при условии, что другой или другие запросы не содержат конструкцию Запрос = Новый Запрос.
    3. Самое трудное, не понял смысл или назначение конструкции Запрос.МенеджерВременныхТаблиц = МВТ
    Спасибо.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  26. nog01

    Василий, добрый день!
    Вопрос по заданию 24.
    Сделала его вложенными запросами, логике одинакова с приведенным Вами решение с помощью временных таблиц. Ваше решение безусловно более прозрачно и понятно.
    Хотела бы спросить:
    1. имеет ли место быть решение вложенными запросами или у него есть недостатки помимо плохой читаемости. Просто хотелось бы большей ясности для себя, когда лучше использовать встроенные запрос (если, он повторяется одинаковый в нескольких местах, здесь понятно, что лучше использовать ВТ), а когда ВТ.
    2. с помощью моего решения в выходной таблице числовые значения получаются прижатыми влево, т.е. выглядят как строки, специально вывела еще строковое значение для сравнения. Сделала внешнюю обработку со своим запросом, при отладке в конфигураторе в ТЗ все нормально: тип значения — число.
    Повторила Ваш запрос: все нормально — цифры прижаты вправо, строки влево. Подскажите с чем это может быть связано.

    Вот мой запрос:
    ВЫБРАТЬ
    Итоги.Номенклатура,
    Итоги.ЦенаЗакупочная,
    Итоги.ЦенаРозничная,
    ВЫБОР
    КОГДА Итоги.ЦенаЗакупочная = 0
    ТОГДА 0
    ИНАЧЕ 100 * (Итоги.ЦенаРозничная — Итоги.ЦенаЗакупочная) / Итоги.ЦенаЗакупочная
    КОНЕЦ КАК Наценка,
    «строка» КАК Поле1
    ИЗ
    (ВЫБРАТЬ
    ВложенныйЗапрос.Номенклатура КАК Номенклатура,
    СУММА(ВложенныйЗапрос.ЦенаЗакупочная) КАК ЦенаЗакупочная,
    СУММА(ВложенныйЗапрос.ЦенаРозничная) КАК ЦенаРозничная
    ИЗ
    (ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена КАК ЦенаЗакупочная,
    0 КАК ЦенаРозничная
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦенаЗакупочная) КАК ЦеныНоменклатурыСрезПоследних

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    0,
    ЦеныНоменклатурыСрезПоследних.Цена
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦенРозничная) КАК ЦеныНоменклатурыСрезПоследних) КАК ВложенныйЗапрос

    СГРУППИРОВАТЬ ПО
    ВложенныйЗапрос.Номенклатура) КАК Итоги

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • nog01

        Василий, спасибо за ответ, во втором вопросе получается, я по сути случайно использовала зарезервированное слово, на которое опирается алгоритм :). В модуль консоли я, конечно, не догадалась заглянуть. Думала, что где-то сама ошиблась.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  27. ismdev

    Видеоурок «Предназначение параметра Субконто виртуальной таблицы».
    При указании параметра «Период» в результат попадают записи, где указанное субконто в плане счетов не является первым.
    1. Это не очевидно, почему именно так ведет себя платформа, чем это обусловлено?
    2. Как в этом случае получить записи на определенную дату, где указанное субконто только на втором месте в плане счетов?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • ismdev

        Непонятно почему параметр «Период» влияет на логику параметра «Субконто».
        Практической задачи нет.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  28. shevelyov

    Сделал задание 26. На экране увидел только 6 столбцов, остальные за пределами экрана. Прокрутка внизу экрана не работает, если как обычно тянуть бегунок мышкой. Остальные столбцы можно увидеть, только если вращать колёсико мышки при нажатой клавише Shift. Почему нельзя прокрутить столбцы не прибегая к помощи колёсика?

    2015-02-27%2016-21-29%20%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%20%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0.png

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • shevelyov

        Проверил на последней: 8.3.5.1460. К сожалению, то же самое. Грустно. Тем не менее, спасибо за комментарий.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  29. shevelyov

    Здравствуйте!
    Сделал такой запрос:
    ВЫБРАТЬ
    ЕСТЬNULL(ПродажиОбороты.Организация, «») КАК Организация,
    ЕСТЬNULL(ПродажиОбороты.Контрагент, «») КАК Контрагент,
    ПродажиОбороты.СуммаОборот КАК СуммаОборот
    ИЗ
    РегистрНакопления.Продажи.Обороты(, , Год, ) КАК ПродажиОбороты
    ИТОГИ
    СУММА(СуммаОборот)
    ПО
    ОБЩИЕ,
    Организация,
    Контрагент

    Не понимаю, почему ЕСТЬNULL не работает, получаю в консоли Null вместо пустой строки.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • shevelyov

        Т.е. на уровне общих итогов от отображения NULL избавиться не удастся, я правильно понимаю?

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

            • Василий Ханевич


              (текст комментария доступен только участникам Мастер-группы)

  30. 13jaguar

    В задании 29 группировку использовать надо. И надо это потому что мы выводим не номенклатуру из виртуальной таблицы, а перечисление из физической таблицы справочника номенклатуры. Я прав? Там в плане запроса, похоже, вложенный запрос к виртуальной таблице формируется.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  31. Yarsan

    Добрый день!
    Вопрос по заданию 28
    Вы уже отвечали на него.
    >Я делал несколько временных таблиц, чтобы избежать получения РегистрНакопления.Продажи.Обороты из базы несколько раз.

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

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  32. Валерий

    Здравствуйте,
    В Задании № 26 формирование наименований для всех секций из макета в модуль производится при помощи конструктора или была где-то заготовка кода, которую вставили?
    (ОбластьШапкаМесяц = Макет.ПолучитьОбласть(«Шапка|Месяц»);)

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  33. jannetka

    Добрый день!
    А так можно? какие подводные камни? отправная точка: если есть закуп, то инфа будет достаточно полной. (Ваш метод мне тоже оч понравился, суммирование с нулем и объединение исключает как потерю данных так и искажение цен):
    ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена,
    ЦеныНоменклатурыСрезПоследних1.Номенклатура КАК Номенклатура1,
    ЦеныНоменклатурыСрезПоследних1.Цена КАК Цена1,
    (-ЦеныНоменклатурыСрезПоследних.Цена / ЦеныНоменклатурыСрезПоследних1.Цена + 1) * 100 КАК Поле1
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены1) КАК ЦеныНоменклатурыСрезПоследних
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены2) КАК ЦеныНоменклатурыСрезПоследних1
    ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = ЦеныНоменклатурыСрезПоследних1.Номенклатура

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  34. passerg

    Добрый день!
    Практическое задание 24
    Разве не проще решить задачу путем ВНУТРЕННЕГО соединения таблиц » в один прием» ?
    я сделал так:
    ВЫБРАТЬ
    ЦеныНоменклатурыЗакупочные.Номенклатура.Наименование,
    ЦеныНоменклатурыЗакупочные.Цена КАК ЦенаЗакупочная,
    ЦеныНоменклатурыРозничных.Цена КАК ЦенаРозничная,
    ВЫБОР
    КОГДА ЦеныНоменклатурыЗакупочные.Цена 0
    ТОГДА ВЫРАЗИТЬ(100 * (ЦеныНоменклатурыРозничных.Цена — ЦеныНоменклатурыЗакупочные.Цена) / ЦеныНоменклатурыЗакупочные.Цена КАК ЧИСЛО(15, 6))
    ИНАЧЕ 0
    КОНЕЦ КАК ПроцентНаценки
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Закупочные) КАК ЦеныНоменклатурыЗакупочные
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Розничные) КАК ЦеныНоменклатурыРозничных
    ПО ЦеныНоменклатурыЗакупочные.Номенклатура = ЦеныНоменклатурыРозничных.Номенклатура

    Это неверное решение?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Dmitry K

        можно решить путем ПОЛНОГО соединения. Смысл в организации виртуальных таблиц есть только если планируется их использовать дальше.

        Мой вариант:

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

        Пробовал удалять одну из цен для произвольной номенклатуры для проверки.
        p.s. Я бы усложнил задачку поправив исходные данные так, чтобы не для всех товаров были все цены. Тогда при решении через соединения эти случаи вылезут и заставят разработчика изменить запрос чтобы это учесть. А то слишком идеальная база. После других ваших курсов ждешь подвоха а его все нет.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  35. Stanislavna

    Практическое задание 27. В задании требуется выбрать данные «за указанный пользователем период». В решении про период забыли.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  36. n.poymanov

    Практическое задание 26.

    Даты месяцев в колонках таблицы выводятся в полном формате.
    01.01.2014 00:00:00. Гораздно нагляднее будут смотреться заголовки вида «Январь 2014» и пр. Вопрос: можно это сделать с помощью Формат() не прибегая к программному вмешательству? Понятно, что в этом случае можно написать свою процедуру, которая будет в зависимости от числа месяца подбирать заголовок и возвращать его. Как лучше это сделать «по-уму»? А то в голову только всякие «кривые» решения приходят, типа того, что я описал.

    Практическое задание 28.
    Как можно данный отчет привести к такому виду, где не будет погрешности? В решении сказано, что надо разносить погрешности по числам и прочее. Можно это как-то сделать без программного вмешательства?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

    • Dmitry K

      Практическое задание 26. Не прибегая к коду это можно сделать настроив параметр «Формат» у ячейки макета.

      • Василий Ханевич


        (текст комментария доступен только участникам Мастер-группы)

  37. n.poymanov

    Практическое задание 25.

    Получилось так, что сделал это задание вручную, т.е. без использования конструктора вывода результата в табличный документ. Когда посмотрел ваше решение возникло желание привести свой собственный макет к похожему виду. Возникли следующий вопросы:

    1) Как самому сделать вот так?
    http://i63.fastpic.ru/big/2015/0104/53/ee6d82a90825c9cfaf97c38c118f8f53.png

    Как в конструкторе макета в свойстве «Текст» переносить текст на новые строчки…Уже столько раз на работе возникала такая необходимость.

    2) Как самому сделать отступ в заголовках группировочных полей? Ни в макете, ни в коде перед группировками нет никаких отступов. Как конструктор запроса это сделал?

    http://i64.fastpic.ru/big/2015/0104/89/d821045a554cdb44b1af3495aebf3089.png

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

    https://titanpad.com/8VqiImpCjC

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • n.poymanov

        1) Точно!
        2) Как работает это свойство? Т.е. на что влияет значение в нем? Я поставил значение 3 (как в макете конструктора запроса) и все стало как надо. Осталось понять суть.
        3) Точно!

        Спасибо!

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  38. n.poymanov

    Практическое задание 22.

    Поясните, пожалуйста, еще раз разницу применения условия в виртуальных таблицах, и в области запроса «ГДЕ». Если по этому заданию задаю условие ПОДОБНО в условии виртуальной таблицы, то в результаты попадают три строки, а не две, как в примере. Почему? Сначала накладывается условие, получаются три строки из данных по всему регистру. После этого по идее берутся последние записи по регистру. Почему в этом случае в качестве последней строки берется строка за «01.02.14 — Руководитель отдела закупок»?

    Практическое задание 23.

    Почему для получения данных по пользователями когда-либо занимавших руководящие должности мы используем виртуальную таблицу срез последних, а не сам регистр? там ведь все данных находятся…если подумать…
    И какая логика тут? Сначала мы отбираем все записи, где встречается «руководитель», а потом делаем по ним срез последних? Какой смысл в срезе последних тогда?

    Я кажется понял! Под Срезом последних понимается получение последних данных по ИЗМЕРЕНИЯМ, а не по всему регистру целиком, верно?!

    Практическое задание 24.

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

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • Dmitry K

        Наверное стоит указать в pdf с заданием требование использовать именно виртуальную таблицу в запросе. Сам сначала сделал запрос к таблице регистра и был удивлен зачем в решении взяли виртуальную таблицу.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  39. abv55

    В методичке «Query-1Сv8-theory.pdf» на стр.219 сказано:
    «Однако в типовой конфигурации «1С:Бухгалтерия 8» в отчете
    Анализ счета выводятся не только обороты по счетам,
    но и начальное и конечное сальдо, в этом случае используется
    виртуальная таблица ОстаткиИОбороты».

    Там используется несколько таблиц. Виртуальная таблица «Обороты»
    тоже используется. В таблице «ОстаткиИОбороты» нет корреспонденции.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  40. abv55

    В ролике «Получение оборотов между корреспондирующими счетами»
    (Query-7-3-AccntRg-6.ufm):

    1. При рассмотрении таблицы «Хозрасчетный.ОборотыДтКт» (1мин. 00сек.) сказано:
    «При использовании виртуальной таблицы «ОборотыДтКт» мы четко должны сказать
    какой счет у нас дебетуется, а какой кредитуется…».
    Это совершенно не обязательно, можно ничего не указывать, можно и один только счет указать,
    например счет дебета.
    Что и далее в ролике продемонстрировано.

    2. При рассмотрении таблицы «Хозрасчетный.Обороты» (2мин. 40сек.) сказано:
    «С точки зрения параметров виртуальной таблицы, что мы видим: условие на счет у нас одно».
    Это неправда, Условие на «корр. счет» и на «корр. субконто» ниже тоже есть.

    3. Вообще слайд «Отличие таблиц ОборотыДтКт и Обороты» неправильный.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  41. natzelv

    Задание 27. Тоже мне непонятно, зачем использовать объединение запросов и зачем задавать параметры для вида номенклатуры. Вид номенклатуры — это значение перечисления, т.е. в запросе их можно получить с помощью функции ЗНАЧЕНИЕ

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

    СГРУППИРОВАТЬ ПО
    ПродажиОбороты.Контрагент

    УПОРЯДОЧИТЬ ПО
    Контрагент

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  42. natzelv

    По правде говоря, непонятно, зачем нужно объединение таблиц в задании 24. Мне кажется, что так получается проще

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

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    Цены.Номенклатура,
    Цены.Розничная,
    Цены.Закупочная,
    ВЫРАЗИТЬ(ВЫБОР
    КОГДА Цены.Розничная = 0
    ТОГДА 0
    ИНАЧЕ (Цены.Розничная — Цены.Закупочная) / Цены.Закупочная * 100
    КОНЕЦ КАК ЧИСЛО(15, 2)) КАК Наценка
    ИЗ
    Цены КАК Цены
    Или я в чем-то неправа?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  43. abv55

    Практическое задание № 28. А зачем тратить время на создание двух временных таблиц? Можно и одной обойтись:

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Товар,
    ПродажиОбороты.КоличествоОборот КАК Количество,
    ПродажиОбороты.КоличествоОборот / ВТ.КоличествоОборот * 100 КАК Процент
    ИЗ
    РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты,
    ВТ КАК ВТ
    ИТОГИ
    СУММА(Количество),
    СУММА(Процент)
    ПО
    ОБЩИЕ

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • abv55

        Согласен. Не внимательно посмотрел ролик с решением. Я по чему то подумал, что обе временные таблицы запросом к базе получаются.

      • Ренат

        Интересно…
        Как думаете, а на экзамене, запрос в котором сначала получаем количество из оборотов, а затем итоговую выборку опять из оборотов, будет считаться ошибкой?

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

  44. abv55

    Практическое задание № 27. А зачем тратить время на создание двух временных таблиц? Можно и одной обойтись:

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Товар,
    ПродажиОбороты.КоличествоОборот КАК Количество,
    ПродажиОбороты.КоличествоОборот / ВТ.КоличествоОборот * 100 КАК Процент
    ИЗ
    РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты,
    ВТ КАК ВТ
    ИТОГИ
    СУММА(Количество),
    СУММА(Процент)
    ПО
    ОБЩИЕ

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  45. abv55

    Практическое задание № 27. Конечно понятно желание продемонстрировать объединение запросов, но полученное решение, по моему, очень не оптимально. Я думаю, что использование виртуальной таблицы оборотов в данном случае вообще не нужно, т.к. при задании условия на номенклатуру системе все равно приходится разворачивать обороты до номенклатуры. Я так решил (один простой запрос без объединений и без временных таблиц):

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

    СГРУППИРОВАТЬ ПО
    Продажи.Контрагент

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • abv55

        В том то и дело, что никакого «сворачивания» при данном наложении условия не происходит. Я оба варианта попробовал и с виртуальной таблицей оборотов и с основной. Результат запроса все равно сворачивать надо. Только при использовании таблицы оборотов «План запроса» получается в несколько раз больше, и реальный запрос к базе в несколько раз больше.

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

          • Ренат

            А что думаете про подобную abv55
            выборку ?

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

            СГРУППИРОВАТЬ ПО
            ПродажиОбороты.Контрагент

            Ваш вариант решения имеет какие-то преимущества?

            • Василий Ханевич


              (текст комментария доступен только участникам Мастер-группы)

  46. serk@rarus.ru

    Здравствуйте,

    В задании 27 приводится решение с помощью объединения двух запросов.

    А можно ли использовать один запрос, в котором использовать механизм «Выбор»:
    «ВЫБОР КОГДА ПродажиОбороты.Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар) ТОГДА ПродажиОбороты.СуммаОборот ИНАЧЕ 0 КОНЕЦ КАК СуммаТоваров»
    и с последующей группировкой по контрагенту?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  47. abv55

    Практическое задание № 24. По моему более оптимально без объединения запросов. Например так:

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

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

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    ВТ.Номенклатура,
    ВТ.ЦенаЗакупочная,
    ВТ.ЦенаРозничная,
    ВЫБОР
    КОГДА ВТ.ЦенаЗакупочная = 0
    ТОГДА 0
    ИНАЧЕ (ВТ.ЦенаРозничная — ВТ.ЦенаЗакупочная) / ВТ.ЦенаЗакупочная * 100
    КОНЕЦ КАК ПроцентНаценки
    ИЗ
    ВТ КАК ВТ

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  48. Максим

    Практическое задание 24. Когда считаем процент наценки не хватает оператора Выбор, для проверки, что мы не делим на 0.
    А в плане производительности, если пишем конкретно под ms sql, что оптимальнее, полное соединение или объединение?

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  49. rut-marina

    Здравствуйте! Прокомментируйте, пожалуйста, решение 28-го ДЗ с использованием одной ВТ(в которой только суммарный итог по количеству), чем-то хуже по производительности?
    ВЫБРАТЬ
    ПродажиОбороты.КоличествоОборот
    ПОМЕСТИТЬ ВТ_итог
    ИЗ
    РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    ПродажиОбороты.Номенклатура.Наименование КАК Номенклатура,
    ПродажиОбороты.КоличествоОборот КАК Количество,
    100 * ПродажиОбороты.КоличествоОборот / ВТ_итог.КоличествоОборот КАК Процент
    ИЗ
    РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты,
    ВТ_итог КАК ВТ_итог
    ИТОГИ
    СУММА(Количество),
    СУММА(Процент)
    ПО
    ОБЩИЕ

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

  50. s.trukhachev

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

    ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследнихЗакупка.Номенклатура,
    ЕСТЬNULL(ЦеныНоменклатурыСрезПоследнихЗакупка.Цена, 0) КАК ЦенаЗакупочная,
    ЕСТЬNULL(ЦеныНоменклатурыСрезПоследнихРозница.Цена, 0) КАК ЦенаРозничная,
    ВЫРАЗИТЬ(ВЫБОР
    КОГДА ЦеныНоменклатурыСрезПоследнихЗакупка.Цена ЕСТЬ NULL
    ИЛИ ЦеныНоменклатурыСрезПоследнихЗакупка.Цена = 0
    ТОГДА 0
    ИНАЧЕ 100 * (ЕСТЬNULL(ЦеныНоменклатурыСрезПоследнихРозница.Цена, 0) — ЕСТЬNULL(ЦеныНоменклатурыСрезПоследнихЗакупка.Цена, 0)) / ЕСТЬNULL(ЦеныНоменклатурыСрезПоследнихЗакупка.Цена, 0)
    КОНЕЦ КАК ЧИСЛО(5, 2)) КАК ПроцентНаценки
    ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Закупка) КАК ЦеныНоменклатурыСрезПоследнихЗакупка
    ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &Розница) КАК ЦеныНоменклатурыСрезПоследнихРозница
    ПО ЦеныНоменклатурыСрезПоследнихЗакупка.Номенклатура = ЦеныНоменклатурыСрезПоследнихРозница.Номенклатура

    Это не правильно с точки зрения оптимизации запроса?

    Понимаю, что рассматривается тема «временные таблицы», но ведь на создание временных таблиц тратится серверная память и увеличивается время выполнения запроса.

    • Василий Ханевич


      (текст комментария доступен только участникам Мастер-группы)

      • s.trukhachev

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

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

      • marivgo

        Можно ли сказать, что если есть две таблицы с одинаковыми измерениями и разными ресурсами и нужно получить из них общую таблицу, где для каждого сочетания измерений нужны ресурсы обеих таблиц, то всегда будет эффективнее использовать объединение таблиц, а не полное соединение? Или это касается только случаев, когда эти таблицы являются вложенными запросами, а не физическими таблицами? Или же в общем случае и для физических таблиц рекомендация использовать объединение вместо соединения, когда возможны оба варианта, все-таки тоже верна?

        • Василий Ханевич


          (текст комментария доступен только участникам Мастер-группы)

Комментарии закрыты