пятница, 20 июля 2007 г.

Система: макросы 3

Проект для урока [id:016]

Есть еще одна штука — макробиблиотека, macro library. Создается она и внешне выглядит как автономный макрос, но только внутри себя содержит несколько локальных макросов. Поясню.

Как обычно создай проект "Blog16" с двумя ветками для джобов и для макросов. Создай макробиблиотеку "BLG16_MacroLib" и там напиши: #define.ITEM_ID('Батарейка-R6') #globalmacro.SelectMyInventItem select * from %1 #IFNOT.EMPTY(%2) where %1.ItemId == %2 #ENDIF ; print %1.ItemName; #endmacro

Создай джоб "BLG16_Job", а в нем: static void BLG16_Job(Args _args) { InventTable inventTable; #SelectMyInventItem(inventTable, #ITEM_ID) #SelectMyInventItem(inventTable) pause; }

Запускай! Хе-хе, кури бамбук, товарищ. Ошибка компиляции "Макрос не существует". Пока чуть-чуть объясню, что вообще мы сделали.

Создать макробиблиотеку - все равно, что создать автономный макрос. Но: для последнего имя элемента являлось бы именем самого макроса. А для макробиблиотеки имя элемента = имя библиотеки (у нас, получается, библиотека называется «BLG16_MacroLib»). Библиотеку можно напичкать автономными макросами и макроконстантами. Я скромненько запихнул лишь одну константу с красивым узбекским именем «ITEM_ID» и один макрос «SelectMyInventItem». Как объявить макроконстанту уже знаешь. Объявление макроса же начинается с фразы «#localmacro» и длиться пока «#endmacro» не разлучит нас.

Разбираем макрос «SelectMyInventItem». В нем ожидается два параметра: %1 — имя табличной переменной, для которой будет выполняться выборка данных; %2 — необязательный идентификатор номенклатуры, которую нужно найти. Фраза «#IFNOT. EMPTY(%2)» говорит: если второй параметр был задан (он не пуст), то вставь здесь текст до «#ENDIF», т. е. строчку «where %1.ItemId == %2». И что получается: если я задаю второй параметр, то в запрос SELECT будет вставлено условие выборки по идентификатору номенклатуры (по полю ItemId). Иначе — ничего.

При компиляции строка "#SelectMyInventItem(inventTable, #ITEM_ID)" смениться на: select * from inventTable where inventTable.ItemId == 'Батарейка-R6' ; print inventTable.ItemName;

А строка "#SelectMyInventItem(inventTable)" станет: select * from inventTable ; print inventTable.ItemName;

Вернемся к ошибке. Если автономный макрос доступен сразу, то макробиблиотеку нужно подключить перед использованием. Это напоминает директиву "#include" в С++ или "using" из мира C#. Только здесь для подключения нужно поставить символ решетки и имя библиотеки. С учетом этого текст джоба должен выглядеть так: static void BLG16_Job(Args _args) { #BLG16_MacroLib InventTable inventTable; #SelectMyInventItem(inventTable, #ITEM_ID) #SelectMyInventItem(inventTable) pause; }

Результат для моей базы:

Комментариев нет: