Вступление: Скриптинг в QlikView
С третьего номера я решил добавить в Альманах новый раздел, который будет освещать интересные приемы в скрипте QlikView при загрузке приложения. При разработке скрипта есть не менее интересные и полезные «фишки». Некоторые из них мы рассмотрим в этой статье.
Пример первый: Как узнать, сколько свободного места осталось на жестком диске
Рассмотрим один из способов работы со скриптом с использованием возможностей PowerShell.
Сначала нам потребуется несколько переменных (это путь до временного каталога, имя временного файла и переменная, в которую запишем размер свободного места на жестком диске).
1 2 3 |
LET vTempPath = `C:\QlikView`; LET vLogFile = `$(vTempPath)disk_space_log.csv`; LET vFreeSpace =; |
Перед собственно командой для PowerShell удостоверимся, на всякий случай, что временного файла нет. Для этого выполним его удаление.
НА ЗАМЕТКУ! Даже если файла уже нет, то никакой ошибки не произойдет.
Само же удаление выполним через стандартную командную строку.
1 |
EXECUTE cmd /c DEL /Q "$(vLogFile)"; |
Далее запускаем тот самый скрипт, который с помощью PowerShell вернёт нам размер свободного места на жестком диске.
1 2 3 |
EXECUTE powershell -command Get-WmiObject win32_logicaldisk , -filter "drivetype=3" |select SystemName, DeviceID, Size, Freespace |ConvertTo-Csv |Select -Skip 1 |Out-File "$(vLogFile)"; |
НА ЗАМЕТКУ! Не забудьте в настройках пользователя включить опцию Script (меню Settings\ User Preferences, вкладка «Security»:Allow Database, Write and Execute Statements).
А теперь обработаем полученный результат.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
IF not IsNull(QvdCreateTime( $(vLogFile) )) THEN , SET ErrorMode = 0; disk_space: LOAD Freespace FROM `$(vLogFile)` (txt, unicode, embedded labels, delimiter is `,`, msq) WHERE DeviceID = `C:`; SET ErrorMode = 1; IF RangeSum(NoOfRows(`disk_space`))>0 THEN LET vFreeSpace = Round(Num(Peek(`Freespace`,0,`disk_space`))/1024/1024/1024,1); ELSE TRACE Не удалось узнать остаток свободного места на жестком диске; END IF SET ErrorMode = 0; DROP TABLE disk_space; SET ErrorMode = 1; ELSE TRACE Не удалось узнать остаток свободного места на жестком диске; END IF |
Понятно, что мы можем заменить константу строку C:
на переменную, которая будет содержать нужный нам диск, на котором мы хотим узнать свободное место. Само свободное место в моем примере вычисляется в гигабайтах, поэтому оно ещё делится на 1024³.
НА ЗАМЕТКУ! Вместо команд TRACE можно написать свои обработчики ошибок.
Пример второй: Как узнать, какие сервисы запущены и, каковы их статусы
Опять воспользуемся готовой возможностью, используя PowerShell.
Сначала определим две переменные. Это путь до временного каталога и имя временного файла.
1 2 |
LET vTempPath = `C:\QlikView`; LET vLogFile = `$(vTempPath)services.csv`; |
Опять же выполним удаление временного файла, чтобы не взять из него старую, предыдущую информацию.
1 |
EXECUTE cmd /c DEL /Q "$(vLogFile)"; |
Ну, и теперь запускаем скрипт с помощью PowerShell:
1 2 |
EXECUTE powershell -command get-service |select Status, Name |ConvertTo-Csv |Select -Skip 1 |Out-File "$(vLogFile)"; |
И загрузка полученного результата для анализа.
1 2 3 4 5 6 7 8 9 10 11 12 |
IF not IsNull(QvdCreateTime(`$(vLogFile)`)) THEN SET ErrorMode =0; Services: LOAD Name as ServiceName, Status as ServiceStatus FROM `$(vLogFile)` (txt, unicode, embedded labels, delimiter is `,`, msq); SET ErrorMode =1; IF RangeSum(NoOfRows(`Services`))=0 THEN TRACE Не удалось узнать список сервисов и их статусы; END IF END IF |
Получили для дальнейшего анализа вот такую таблицу: «Services» (пример А).
Пример А
Пример третий: Как, имея список названий городов или адресов, найти их GPS координаты
Если в вашем приложении есть справочник каких-либо адресов или даже просто список названий городов, и вам хотелось бы показать их на карте, но нет привязки к GPS координатам, в этом случае выручит данный скрипт.
Сначала добавим в начало скрипта вот такую процедуру:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
SUB GetGEO(GetGEO.Address) SET GetGEO.Found =; SET GetGEO.AddressLine =; SET GetGEO.Pos =; SET ErrorMode =0; GetGEO: REPLACE LOAD @1:255 as Line FROM [http://geocode-maps.yandex.ru/1.x/?geocode=$(GetGEO.Address)&results=1] (fix, utf8); SET ErrorMode =1; IF RangeSum(NoOfRows(`GetGEO`))>0 THEN tmp: LOAD Line, IF( Index(Line,`<metaDataProperty`) AND IsNull(Peek(`Blok`)), `M`, IF( Index(Line,`<featureMember`) AND Peek(`Blok`)<>`END`, `F`, IF( Index(Line,`</featureMember`), `END`, Peek(`Blok`) ))) as Blok, IF( Peek(`Blok`)=`M`, TextBetween(Line,`<found>`,`</`) ) as Found, IF( Peek(`Blok`)=`F`, TextBetween(Line,`<AddressLine>`,`</`) ) as AddressLine, IF( Peek(`Blok`)=`F`, TextBetween(Line,`<pos>`,`</`) ) as Pos RESIDENT GetGEO; DROP TABLE GetGEO; GEO_Result: LOAD MaxString(Found) as Found, MaxString(AddressLine) as AddressLine, MaxString(Pos) as Pos RESIDENT tmp; DROP TABLE tmp; LET GetGEO.Found = Peek(`Found`,0,`GEO_Result`); LET GetGEO.AddressLine = Peek(`AddressLine`,0,`GEO_Result`); LET GetGEO.Pos = Peek(`Pos`,0,`GEO_Result`); DROP TABLE GEO_Result; END IF SET ErrorMode =0; DROP TABLE GetGEO; SET ErrorMode =1; SET GetGEO.Address =; END SUB |
И предположим у нас уже есть в макете загруженная таблица, в одном из полей которой хранятся адреса и/или названия городов. Для примера просто создам список, используя INLINE:
1 2 3 4 5 6 7 8 9 10 11 12 |
[Example-2]: LOAD * INLINE [ CityAddress `Тюмень г.` `Москва г.` `Казань г.` `Волгоград г.` `Красноярск г.` `Новосибирск г.` `Норильск г.` `Владивосток г.` ]; |
Вот, что мы получим (пример Б):
Пример (Б)
Продолжаем…
А теперь сам скрипт использования процедуры GetGEO.
Для каждого уникального значения адреса вызовем процедуру поиска GPS-координат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
FOR n=1 TO FieldValueCount(`CityAddress`) LET Addr = FieldValue(`CityAddress`,$(n)); CALL GetGEO(`$(Addr)`); AddressListGEO: LOAD `$(Addr)` as CityAddress, `$(GetGEO.Found)` as GEO_Found, `$(GetGEO.AddressLine)` as GEO_Address, SubField(`$(GetGEO.Pos)`,` `,1) as GEO_Langitude, SubField(`$(GetGEO.Pos)`,` `,-1) as GEO_Latitude AUTOGENERATE 1; NEXT n; |
После чего очищаем временные переменные и присоединяем найденный результат к исходной таблице:
1 2 3 4 5 6 7 8 9 |
SET n =; SET Addr =; SET GetGEO.Found =; SET GetGEO.AddressLine =; SET GetGEO.Pos =; LEFT JOIN ([Example-2▐) LOAD * RESIDENT AddressListGEO; DROP TABLE AddressListGEO; |
Замечу, что когда адрес или город однозначно определяется процедурой поиска, то в возвращаемой GetGEO.Found будет 1, а если адрес не полный или не совсем точен, то система выдаст в переменную GetGEO.Found количество похожих адресов. Этот факт можно использовать, чтобы точно понимать корректный адрес или надо его уточнить подробнее.
НА ЗАМЕТКУ! Небольшое ограничение: в бесплатной версии «API Яндекс.Карт» можно делать не более 25000 запросов к геокодеру в сутки.
Ну, а теперь, полученные GPS-координаты легко отобразить на карте (пример В).
Пример (В)
Коллеги, на этом сегодня все! До новых встреч в эфире!
Класс, очень полезно! Подскажите, пожалуйста, что значит значек евро в переменной и чем он отличается от значка доллара? И второй вопрос, можно ли к модели добавлять внешние процедуры, что бы не копировать каждый раз код процедуры для каждой модели. Спасибо)
В данном случае — при копировании текста просто забыли сделать замену. Всё где «евро», конечно, замените на «доллар». А на счет второго вопроса — можно. В клике любой кусок кода — можно сохранить в отдельный файл с расширением qvs, и далее динамически «встраивать» его через команду $(must_include=$(PathLib)Library.qvs); Таким образом — создаются пакеты с часто используемыми процедурами и функциями, а так же с настройками и с коннектами к базам.
Спасибо еще раз!