Технология ассоциативного анализа, реализованная в Qlikview и Qlik Sense, привлекает все больше специалистов, и не только из сферы ИТ. Кому-то приходится не раз вспоминать уроки информатики, чтобы составить программу загрузки и обработки данных.
Да-да, вот и пригодилась школьная программа )). Хорошо если все проходит гладко, а если нет? Ладно, если есть сообщение об ошибке, а если ни ошибки и ни результата? И время поджимает. Что делать? Выход один — приступить к отладке приложения.
Рассмотрим способы, облегчающие отладку приложений в Qlikview.
1. Отладка приложений: Журналирование
Создали новый файл?
Включим опцию «Создание файла журнала» из свойств документа, и каждый процесс загрузки будет сопровождаться выводом полезной информации в текстовый файл с именем приложения и расширением log.
Установим флажок на опции «Отметка времени в имени журнала» и получим отдельный лог-файл на каждый запуск скрипта с отметкой времени в имени файла.
Файл журнала, сформированный в процессе загрузки данных, будет содержать более ценную информацию, чем та, что отображается в прогрессе выполнения скрипта.
2. Отладка приложений: Трассировка
Не устраивает информативность окна прогресса выполнения скрипта?
Нет ничего проще, чем использование оператора TRACE, который позволяет выводить сообщения в окно выполнения скрипта и в файл журнала. Причем в журнал выводятся как
сам оператор, так и результат вывода сообщения.
Очень удобно использовать TRACE при тестировании и отладке «длинных» скриптов. При этом текстовая строка может формироваться в переменной. Используя оператор When и переменную, мы сможем управлять трассировкой — либо включить, либо выключить.
Режим отладки | Оператор |
Трассировка включена | Set vDebug=1 |
Трассировка выключена | Set vDebug=0 |
Работает это очень просто- в начале скрипта произвольной переменной устанавливается значение, например:
Далее по тексту программы назначаем точки вывода информации и прописываем оператор TRACE следующим образом:
when vDebug = 1 TRACE Трассировка включена, vDebug=$(vDebug);
Следовательно, если условие оператора When выполняется, то будет отработан оператор, следующий за ним, то есть TRACE.
Установив значение переменной vDebug в ноль, мы отключим вывод всех отладочных сообщений. Удобно? Думаю, что да.
3. Отладка приложений: Отладчик
Но еще интереснее будет изучение работы скрипта через стандартный инструмент отладки, который вызывается только из режима редактирования скрипта.
Сложностей этот режим не вызывает и хорошо описан в справке программы.
Во многих случаях отладчик сможет помочь. Но следует отметить некоторую «скупость» в предоставлении информации разработчику.
Отследить ход выполнения скрипта и изменение переменных — вот, пожалуй, и все. В остальном — свобода творчества )).
4. Отладка приложений: Сохранение таблиц в текстовом формате
Редкий скрипт обходится без работы с табличными данными, а уж тем более в Qlikview. И просмотр промежуточных результатов порой просто необходим.
Оператор STORE выгружает данные не только в QVD-формат, но и в обычный текстовый файл, доступный для просмотра любым текстовым или табличным редактором (Excel, Calc). При желании его можно будет загрузить в учетную систему или другую базу данных.
Например:
// Генерируем набор тестовых данных tmp1: Load ‘ID_’ & Num(RecNo(),’00’) As %ID, Date(MakeDate(2016)+Ceil(30*Rand())) As Дата Autogenerate 30; // В режиме отладки сохраняем в текстовом формате when vDebug = 1 Store tmp1 Into tmp1.csv(txt,delimiter is ‘;’) ; |
when vDebug = 1 Trace Сохранение таблицы в $(QvWorkPath)\tmp1.csv
В режиме трассировки мы сможем ознакомиться с содержимым промежуточной таблицы.
Выгрузкой отладочных таблиц также можно управлять, как и режимом трассировки, с помощью оператора When.
5. Отладка приложений: Сохранение переменных в текстовый файл
Работа с переменными в Qlikview — очень обширная и интересная тема. Если в процессе отладки скриптов понадобится отслеживать переменные, то кроме отладчика еще можно использовать очень простой способ — выгружать переменные в текстовый или qvd-файл для дальнейшего использования в проекте.
Например, следующий код сформирует текстовый файл с именем переменной и ее значением:
vars: LOAD * INLINE [ Variable_name, Variable_value vDebug, $(vDebug) ]; Store * from vars Into vars.txt (txt, delimiter is ‘;’ ); |
Чтобы вывести несколько переменных нам понадобится прописать каждую в отдельную строку. Количество строк неограниченно.
6. Отладка приложений: Обработка ошибок
Ну, и раз уже речь зашла о переменных, нельзя не упомянуть о системных переменных обработки ошибок (ErrorMode, ScriptError, ScriptErrorDetails, ScriptErrorCount, ScriptErrorList).
Подробное описание можно найти в документации. Я лишь рекомендую в скриптах загрузки и обработки данных, которые обычно запускаются по расписанию без участия пользователя, всегда использовать режим ErrorMode = 0. В этом случае при возникновении ошибки в ходе исполнения скрипта работа программы будет продолжена, а в журнале появится запись об ошибке.
Кстати, журналы с результатами исполнения скриптов тоже могут быть загружены в отдельное приложение Qlikview для контроля, что тоже можно отнести к одному из приемов отладки приложений.
Например, следующий код загрузит из журнала только строчки с сообщением об ошибке и указанием имени лог-файла и времени возникновения ошибки:
LOAD FileName() As [Файл], [@1:19] As [Время], [@25:n] as [Текст] FROM [тест.qvw.log] (fix, utf8, no labels) Where WildMatch([@25:n],’*Ошибка*’) ; |
Как это можно использовать в панели администратора корпоративной системы бизнес-аналитики, думаю, вопросов не возникнет.
Как видите, все очень просто.
Заключение
И напоследок, немножко в копилку знаний.
Не стоит усложнять себе и коллегам жизнь. Пишите комментарии там, где это необходимо. Это намного облегчает работу по анализу кода в дальнейшем, в первую очередь, самому себе.
Да-да, посмотрите на свои n-летние творения эпохи начала трудовой деятельности. Все понятно? Вот-вот ))
Это замечание в целом, а что касательно предмета этой статьи и QlikView еще один момент.
Структурируйте код, делите его на процедуры, процедуры разносите на вкладки и в крайней правой пишите команды вызова процедур. В этом случае вам не придется комментировать массу строк, чтобы отладить один фрагмент. Достаточно закомментировать только вызовы процедур, как показано на рисунке.
Вот вроде бы и все. У каждого мастера свои секреты, предлагаю дополнить перечисленные выше приемы в комментариях.
Ну, а что касается способов отладки в Qlik Sense — пусть это будет для вас домашним заданием.
Всем удачи, весны и до новых встреч!
Не совсем в тему отладки, но тоже про контроль ошибок, хотел бы добавить следующее.
На практике одна из самых существенных зон риска — нарушение целостности данных при операции LEFT JOIN на основной таблице фактов. Это может произойти том в случае, если в присоединяемой таблице комбинация значений в ключевых полях (общих для обоих таблиц) НЕ является уникальной. Последствия — замножение (дублирование) строк транзакций, что может привести к некорректным и даже удивительным результатам вычислений агрегированных показателей в чартах. В подавляющем большинстве случаев это нежелательное (или даже недопустимое) явление.
В своей практике я практически всегда встраиваю проверку, что количество строк данных в основной таблице не изменилось после LEFT JOIN. А если вдруг это произошло, скрипт должен аварийно прерываться, и обновление приложения тут же завершаться с выдачей ошибки. Вот такой типовой код использую:
/* Проверка корректности присоединения — первоначальное количество строк в таблице */
LET vTable_InitialNoOfRows = NoOfRows(‘Остатки’);
Left Join ([Остатки])
LOAD
[%Магазин Товар Поставка ID],
/* присоединяемые поля */
[Магазин ID]
Resident
[STARLINK]
;
/* Проверка корректности присоединения — сверка с первоначальным значением */
LET vTable_CurrentNoOfRows = NoOfRows(‘Остатки’);
IF vTable_InitialNoOfRows vTable_CurrentNoOfRows then
TRACE Зафиксировано нарушение целостности данных: vTable_CurrentNoOfRows=$(vTable_CurrentNoOfRows)/vTable_InitialNoOfRows=$(vTable_InitialNoOfRows), выполнение скрипта прекращено;
/* генерация ошибки скрипта путем вызова несуществующей процедуры */
CALL ThrowException(‘Ошибка: нарушение целостности’);
ENDIF
LET vTable_InitialNoOfRows = Null();
LET vTable_CurrentNoOfRows = Null();
Вторая существенная зона риска (опять же из своей практики) — случаи, когда система-источник в ответ на SQL-запрос посылаемый Кликом (с помощью стейтмента SELECT или SQL) возвращает НОЛЬ строк и никаких сообщений об ошибках. SAP Connector иногда ведет себя таким образом.
Клик в таком случае радостно «обнулит» имеющийся QVD, далее пойдет цепочка обновлений приложений, и счастливый пользователь, открыв приложение, увидит абсолютно пустые отчеты. Совершенно реальная ситуация, между прочим.
Чтобы этого не происходило, нужно встроить следующую простую проверку, и аварийное завершение в случае если она неуспешна:
LET vNumberOfrows = NoOfRows(‘ZRT_V01’);
IF NoOfRows(‘ZRT_V01’)>0 then
TRACE vNumberOfrows = $(vNumberOfrows);
TRACE Store ZRT_V01.QVD;
Store * from [ZRT_V01] into [$(vWayTransactionalData)ZRT_V01ZRT_V01_$(vLoadYear)$(vLoadtMonthSrt).QVD] (qvd);
ELSE
TRACE vNumberOfrows = $(vNumberOfrows);
CALL ThrowException(‘Error: 0 records’);
ENDIF