24.11.2005, 13:24 | #1 |
Участник
|
Проверка на передачу пустого параметра в макрос
Добрый день. Необходимо в зависимости от того, нужно или нет фильтровать проводки по складу, изменять запрос по проводкам. Возьмем самый простейший пример:
static void Job1(Args _args) { #macrolib.InventABC InventTrans inventTrans; InventDim inventDim; InventLocationId location = 'Ск2'; ; while select inventTrans { print inventTrans.ItemId; } pause; } Решила реализовать данную задачу с использованием макроса, который будет подставлять в запрос либо Join с таблицей InventDim, либо ничего. Написанный макрос выглядит следующим образом: /* %1 InventTrans, CustInvoiceTrans...*/ /* %2 InventLocationId */ #localmacro.InventABCDim #ifnot.empty(%2) join tableId from InventDim index hint DimIdIdx where (InventDim.InventDimId == %1.InventDimId) && (InventDim.InventLocationID == %2) #endif #endmacro Но он не в полной мере меня устраивает. Если вызвать макрос с обеими заполненными параметрами, то печатаются все проводки по данному складу, все ок. Если второй параметр не указывать - печатает все проводки. Если в качестве второго параметра задать пустую строку, то, естественно, выводятся все проводки, у которых склад не задан. Мне же в этом случае необходимо, как и в случае с незаданным параметром "%2", выводить все проводки. Есть ли в макросах, наряду с проверкой #ifnot.empty(%2) возможность проверки, что параметр передан, но он пустой (в случае строки) либо нулевой (в случае числа)? Не хочется в коде плодить лишние условия, ветки, дублировать запрос и т.д. Хотелось бы реализовать все красиво и одной строкой вида: while select inventTrans #InventABCDim(inventTrans, location) только не получается как-то сделать обработку условия, что переменная location - пустая (склад не указан). Возможно, решение совсем простое, только я его не вижу... Может, кто-то знает, как это реализовать? |
|
24.11.2005, 14:04 | #2 |
Moderator
|
Макросы в тройке были оставлены для совместимости с предыдущими версиями. В новых версиях от них обещают отказаться. (Тебе бы этого не знать, Лен) Может ну их эти макросы?
Одной строкой конечно красиво, но подумай о тех кто возможно будет поднимать это на новую версию
__________________
С уважением, kvan. |
|
24.11.2005, 14:42 | #3 |
Участник
|
Просто мне придется делать это в десятках мест и в нескольких классах, вот из-за чего и кажется, что все эти повторы, проверки и разветвления будут выглядеть весьма убого в лучшем случае.:-( Макрос казался все-таки более изящным выходом и универсальным. Ладно, спасибо, Антон, буду искать другой вариант. :-)
|
|
24.11.2005, 15:06 | #4 |
Moderator
|
А двумя заходами не получиться?
Что то типа: while select inventTrans where inventTrans.InventLocationId // Invent location is not empty #InventABCDim(inventTrans, location) { // Do something } и while select inventTrans where !inventTrans.InventLocationId // Invent location is empty { // Do something }
__________________
С уважением, kvan. |
|
24.11.2005, 16:08 | #5 |
Участник
|
Получится, но при этом придется продублировать весь метод. Для примера:
Classes/CustVendTransStatistics/calc Там запрос встречается четыре раза, и каждый раз придется его "размножать" на два:-( |
|
24.11.2005, 16:18 | #6 |
Moderator
|
Так как похоже что макросом тебе не извернуться, я бы попробывал и "размножение на два" и дополнительные проверки.
И оставил бы то что работает быстрее
__________________
С уважением, kvan. |
|
24.11.2005, 16:43 | #7 |
Участник
|
да, душа тянется к совершенству, а приходиться жить в реальном мире...
|
|
24.11.2005, 16:50 | #8 |
Moderator
|
лучшее враг хорошего ...
__________________
С уважением, kvan. |
|
24.11.2005, 16:50 | #9 |
Участник
|
приходится
|
|
24.11.2005, 17:08 | #10 |
Участник
|
А почему не хотите попробовать Query ?
Кроме того в приведенном примере можно написать так ... where (InventDim.InventDimId == %1.InventDimId) && ((InventDim.InventLocationID == %2 && %2) || !%2) |
|
24.11.2005, 17:35 | #11 |
Moderator
|
Цитата:
Сообщение от vey
Есть ли в макросах, наряду с проверкой #ifnot.empty(%2) возможность проверки, что параметр передан, но он пустой (в случае строки) либо нулевой (в случае числа)?
__________________
Андрей. |
|
24.11.2005, 17:50 | #12 |
Участник
|
X++: ((InventDim.InventLocationID == %2 && %2) || !%2) X++: (InventDim.InventLocationID == %2 || !%2) |
|
24.11.2005, 23:28 | #13 |
Участник
|
Цитата:
Сообщение от vey
Решила реализовать данную задачу с использованием макроса, который будет подставлять в запрос либо Join с таблицей InventDim, либо ничего. Написанный макрос выглядит следующим образом:
Полностью согласен с belugin Если вы все же решили использовать макросы, то пользуйтесь стандартными макросами для подстановки в запрос InventDimJoin InventDimSelect Во-первых, вы ничего не забудете Во-вторых, порядок полей в where у вас всегда будет одинаковым. Что благотворно скажется на производительности. |
|
25.11.2005, 09:20 | #14 |
Участник
|
Цитата:
Сообщение от kvan
Макросы в тройке были оставлены для совместимости с предыдущими версиями. В новых версиях от них обещают отказаться.
__________________
Axapta v.3.0 sp5 kr2 |
|
25.11.2005, 11:27 | #15 |
Moderator
|
Да, мне тоже интересно, зачем отказываться от достаточно популярного и практичного механизма макросов?
__________________
Андрей. |
|
25.11.2005, 12:01 | #16 |
Участник
|
Про макросы было написано в Best Practice, по-моему.
Макросы чертовски неудобная штука. Именно из-за макрософ приходится делать глобальную компиляцию. Сейчас их рекомендуется использовать только для констант. |
|
25.11.2005, 12:10 | #17 |
Участник
|
>>Именно из-за макрософ приходится делать глобальную компиляцию
можешь пояснить? |
|
25.11.2005, 12:54 | #18 |
Участник
|
Синтаксический контроль позволяет выявить все объекты, которые затронутся при изменении любого заданного объекта.
Кроме случаев, когда используются макросы. Поскольку макросы - надсинтаксическая конструкция. Для того, чтобы гарантировать, что все объекты компилируются правильно при изменении макроса приходится компилировать все объекты. Кроме того, компиляцию приходится делать многопроходной. Сразу отвечу на вопрос - а можно ли заставить синтаксический анализатор учитывать макросы? Ответ - нет. Поскольку есть условные макросы и могут быть макросы в макросах. (Вспомни, как организована компиляция C и C++ в инструментальных средах - на основании информации об использовании ФАЙЛОВ, а не объектов) Если макросов нет, то при изменении любого объекта достаточно перекомпилировать объекты, интерфейсно связанные с данным объектом. |
|
25.11.2005, 17:45 | #19 |
Участник
|
если макросы есть достаточно перекомпилировать объекты, которые используют макрос - разве не так?
|
|
11.04.2013, 03:11 | #20 |
Участник
|
В теме обсуждения, абстрагируясь от макросов, стоит задача написать универсальный запрос в одну конструкцию, которая бы корректно учитывала значения параметров из условий запроса. Это есть прямая необходимость при построении конструкции запроса использовать логику более высшего уровня, чем предлагает X++ в аспекте работы с данными like SQL. Т.е., очевидно, что тут необходимо конструировать структуру запроса программно. Если уж необходимость в таких "умных" запросах возникает часто, то прямой путь - абстрагировать логику.
Бла-бла-бла Короче, по моему мнению надо делать метод без макросов (м.б. и статический), который в зависимости от переданных параметров возвращает курсор(ы). Далее по ним бежать next-ом. Что-то типа: X++: cursor = getMySmartCursor(inventTrans, location); do { if (cursor) ... ..... next cursor; } while (cursor); Как актуален и свеж мой комментарий в 2013 году. 8 лет я готовился к этому... |
|