25 июля 2012 г.

Многократно используемые и расширяемые выражения в QlikView

Всем привет.
Сегодня я хотел бы немного поговорить о выражениях (Expressions), которые мы так часто пишем “с нуля”, переписываем, анализируем и т.д. и т.п. А точнее, хотелось бы поговорить о том, как можно хоть немного облегчить нашу жизнь при работе с диаграммами (Charts) и, в частности, с выражениями, прописанными в этих самых диаграммах. Очень часто (практически на любом более или менее насыщенном диаграммами QlikView приложении) встречается такая ситуация, когда одно и то же выражение многократно повторяется во множестве различных объектов QlikView документа. Причем, чаще всего это самое выражение многократно скопировано и размножено по всей этой куче объектов. И вот, в один прекрасный момент, мы понимаем, что нам необходимо что-то поменять в этом “уникальном” выражении. В таком случае, нас неизбежно ожидает не очень сложная, но очень неприятная работа по изменению большого количества объектов, так называемая “Monkey Job”. Конечно, отчасти нас спасет встроенный Обозреватель Выражений (Expression Overview). Его можно вызвать при нажатии комбинации Ctrl+Alt+E, но и при работе с ним хватает “удобств”. Поэтому в какой-то момент неизбежно возникает мысль о том, как бы все этого избежать и упростить себе, да и другим коллегам (кто в дальнейшем будет поддерживать ваше приложение) жизнь. Я сейчас не хочу углубляться в подробности того, как это можно сделать, т.к. на днях я натолкнулся (что и подтолкнуло меня к написанию сегодняшнего поста) на замечательную статью нашего украинского коллеги Дмитрия Гудкова. Кстати, о Дмитрии я уже упоминал на страницах своего блога, когда рассказывал об одной интересной его разработке. Так вот Дмитрий достаточно подробно описывает возможности использования переменных для обхода вышеописанной мною ситуации, а также приводит ряд примеров и обходных путей при работе с такими переменными. Поэтому для начала прошу обратиться к статье Дмитрия, а затем вернуться сюда для продолжения разговора Улыбка. Кстати, Дмитрий пишет на английском, поэтому если все-таки у кого-то возникнут дополнительные вопросы, то спрашивайте, не стесняйтесь. Я буду рад помочь и разъяснить… Ознакомились? А теперь прошу, что называется, “под кат”…
В своей статье Дмитрий рассказывает об одной интересной проблеме при работе с переменными. А точнее при работе с параметризованными переменными или, как я их иногда называю, переменными-функциями. Дело в том, что, передавая строку-параметр в переменную, мы не можем в чистом виде использовать запятые в таких строках. По той простой причине, что QlikView воспринимает запятую как разделитель между параметрами, а не как часть содержимого одного параметра. И в итоге, мы не получаем нужного нам результата. Дмитрий приводит достаточно наглядные примеры, отражающую эту ситуацию. Более того, в своей статье наш коллега предлагает достаточно оригинальный обходной путь, помогающий-таки достигнуть желаемого и “обмануть” QlikView. Он рассказывает про возможности использования подмножеств и операций с ними (пересечение, объединение и т.д.) в Set Analysis’е. На мой взгляд, данный путь, конечно же, имеет место быть. Однако он достаточно громоздок и серьезно усложняет как само выражение, так и его понимание, особенно для новичков. Да и использовать мы его можем в очень ограниченных ситуациях – при параметризации Set Analysis’а. Я хотел бы немного дополнить Дмитрия и посоветовать использовать более универсальный, на мой взгляд, подход для обработки запятых в параметрах переменных. Подход, как и все гениальное – прост как 5 копеек Улыбка
Для простоты возьмем примеры из статьи Дмитрия, где он использует вот такое вот определение для переменной:
LET ePrevAmount = sum ( {<Year={"=only(Year)-1"}, $1 >} Amount)
Данная переменная предполагает расчет суммы по полю Amount за предыдущий год (относительно текущего значения выбранного года). А также имеет один дополнительный параметр, который может использоваться для более детального ограничения калькуляции при использовании Set Analysis’а. Так вот Дмитрий как раз и описывает различные ситуации использования подмножеств в качестве передаваемого параметра… Например вот так:
$(ePrevAmount( Type={Income} >*< Aggregated={Yes} >*< CostCenter={NY} ))
В этом случае мы получим тот же результат, что и при использовании выражения вида:
sum ( {<Year={"=only(Year)-1"}, Type={Income}, Aggregated={Yes}, CostCenter={NY} >} Amount)
То есть, помимо ограничения по году, мы хотим дополнительно ограничить калькуляцию по полю Type (со значением Income), полю Aggreated (значение Yes) и по полю CostCenter – NY. В данном примере, как раз используется пересечение подмножеств для реализации условия И (AND) по разным полям.
Другой пример отражает ситуацию, когда нам необходимо ограничить калькуляцию по нескольким значениям одного и того же поля, например вот так:
sum ( {<Year={"=only(Year)-1"}, City={NY’, ‘Boston’, ‘Chicago’} >} Amount)
Т.е. в качестве параметра нам необходимо передать строку вида:
City={‘NY’, ‘Boston’, ‘Chicago’}
Но так как в чистом виде мы, как уже говорили, не можем использовать запятые, то автор предлагает следующий обходной вариант:
$(ePrevAmount( City={NY} >+< City={Boston} >+< City={Chicago} ))
То есть использовать объединение подмножеств для реализации условия ИЛИ (OR) по нескольким значениям одного и того же поля. Тем самым достигнув поставленной цели и получив необходимую калькуляцию.
Все замечательно и все работает, но как-то не радует глаз… почему вместо City={‘NY’, ‘Boston’, ‘Chicago’} мы вынуждено писать более громоздкое: City={NY} >+< City={Boston} >+< City={Chicago} и, на мой взгляд, менее привычное и менее читабельное… Да, мы не можем использовать запятые, так давайте заменим их на что-то другое – такое же простое и легко воспринимаемое, например, точка с запятой (;). Почему нет? Кто нам мешает?
Да никто! Это я почтальон Печкин…
А если серьезно, то все что нам необходимо сделать, перед тем как использовать точку с запятой в строке параметра (и чтобы она правильно воспринималась QlikView) это немного изменить первоначальное определение нашей переменной. Помните, как оно выглядело? Вот так:
LET ePrevAmount = sum ( {<Year={"=only(Year)-1"}, $1 >} Amount)
А теперь давайте немного “поиграем” с передаваемым параметром, прежде чем его отдать переменной:
LET ePrevAmount = sum ( {<Year={"=only(Year)-1"}, $(=Replace('$1', ';', ',')) >} Amount)
Что мы сделали? А ничего архисложного мы и не сделали Улыбка, только лишь добавили предварительную обработку для нашего параметра. Теперь перед тем как строка параметр “уйдет” в переменную, в ней автоматически будут заменяться все точки с запятой (;) на запятые (,). И теперь вместо:
$(ePrevAmount( Type={Income} >*< Aggregated={Yes} >*< CostCenter={NY} ))
Мы с легкостью можем писать вот так:
$(ePrevAmount( Type={Income}; Aggregated={Yes}; CostCenter={NY} ))
или вот так:
$(ePrevAmount( City={'NY';'Boston';'Chicago'} ))
взамен вот этому:
$(ePrevAmount( City={NY} >+< City={Boston} >+< City={Chicago} ))
Вот и весь подход! Просто и со вкусом Улыбка.
У кого будут идеи/рекомендации как еще можно упростить нашу жизнь в описанной ситуации – прошу обозначить сие в комментариях Улыбка.
Спасибо за внимание.


7 комментариев:

  1. Отличное решение, мне нравится :)

    ОтветитьУдалить
  2. Отлично!
    QlikView не перестает удивлять.
    Спасибо за блог.

    ОтветитьУдалить
  3. Алексеев Владимир1 августа 2012 г. в 21:43

    Отличная статья у Дмитрия и изящное дополнение от Анатолия. Взял на заметку. Спасибо.

    ОтветитьУдалить
  4. Привет, скажите, можно ли написать пост о вынрузке данных из олап кубов, особенности и примеры скрипта, какие то ограничения есть по объему данных может?

    ОтветитьУдалить
  5. привет) Можно подробнее вот тут:
    "или вот так:
    $(ePrevAmount( City={'NY';'Boston';'Chicago'} ))
    взамен вот этому:
    $(ePrevAmount( City={NY} >+< City={Boston} >+< City={Chicago} ))"

    Написав так:
    $(ePrevAmount( City={'NY';'Boston';'Chicago'} ))
    мы получим (при замене запятыми) условие И (AND),
    а судя по начальному варианту хотели получить ИЛИ (OR):
    $(ePrevAmount( City={NY} >+< City={Boston} >+< City={Chicago} ))"

    ОтветитьУдалить
  6. Юлия, вы не совсем правы....
    когда у нас есть, например, вот такое выражение: sum({) Value) мы получим сумму по всем 3м городам, т.е. условие ИЛИ (или Нью-Йорк, или Бостон, или Чикаго). Как, собственно, и в длинной конструкции с использованием подмножеств: <...> + <...>

    ОтветитьУдалить