![]() |
#1 |
Участник
|
axaptapedia: Dialog macro
Источник: http://www.axaptapedia.com/Dialog_macro
============== Summary: <div>== Abstracts == I often need a quick dialog to check or moify some data. Sometimes the customer doesn't know exactly what select critera he or she needs, so the dialog needs a lot of criteria fields (from .. to). What I have to do is creating a dialog object with up to 10 dialog fields - or more. This is very hard, because I have to repeat the ist of variables several times: 1. declare dialog fields 2. declare working fields 3. create dialog fields objects, and add them to the dialog 4. restore last saved values 5. set values to the dialog fields 6. after prompting and running the dialog: save values 7. move dialog fields to the working fields. Especially if you need more variables, you can easily make some mistakes. So I decided to create a macro (using [[Abstract macro]]) to do the hard work. == Example == I have to check some invoices - depending on customer groups, customer or invoice accounts, invoice date and invoice id. static void CheckInvoices(Args _args) { CustInvoiceTable custInvoiceTable; #define.DialogMacroId("CheckInvoice") // = fromCustGroupId) && // long version (! toCustGroupId || custInvoiceTable.CustGroup
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
![]() |
#2 |
Ищущий знания...
|
что то я не понял в чем тут прелесть использования макроса?
гораздо нагляднее и проще вывести на диалог query, где пользователь спокойно может указать диапазон через "..". Более того, в query пользователь сможет, при желании, добавить ещё и свое поле с условием для выборки. Вот такой код, ИМХО, проще для понимания и поддержания: 1. Создаем класс для нашего отчета\функции и наследуем его от RunBase. 2. Перекрываем методы: QueryRun - указываем свой queryRun, который определили в ClassDeclaration; ShowQueryValues - возвращаем true; Pack; UnPack; InitParmDefault. 3. Создаем метод InitQuery в котором пишем запрос для нашего диалога: X++: Query query = new Query(); QueryBuildDataSource qbds; ; qbds = query.addDataSource(tableNum(CustInvoiceTable)); qbds.addRange(fieldNum(CustInvoiceTable, CustGroupId)); qbds.addRange(fieldNum(CustInvoiceTable, CustAccount)); qbds.addRange(fieldNum(CustInvoiceTable, InvoiceAccount)); qbds.addRange(fieldNum(CustInvoiceTable, InvoiceDate)); qbds.addRange(fieldNum(CustInvoiceTable, InvoiceId)); queryRun = new QueryRun(query); // queryRun объявлен в ClassDeclarartion класса и все, при выполнении нашего отчета\функции появиться диалог, в котором пользователь может указать хоть диапазон, хоть одно значение, хоть несколько значений через запятую, хоть вообще добавить свое поле и указать для него значение. потом в Run будет простой перебор X++: while(queryRun.next()) ![]()
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#3 |
Участник
|
На сколько я понял, автор попытался с помощью макросов сделать своеобразный конструктор диалогов для запроса у пользователя параметров, которые потом можно использовать в условии where запроса.
Также согласен с вами, что использование QueryRun предпочтительнее. В свою очередь могу поделиться собстенным инструментом для запроса у пользователя каких-либо параметров. Использую его, когда нужно создать "на лету" простейший диалог, который не может быть связан с каким-либо источником данных. X++: static container InputBox(container _conFields, caption _caption = '') { Dialog dlg = new Dialog(); container ret = conNull(); int n = conlen(_conFields); int i; List listFields = new list(Types::Class); ListEnumerator enumerator; ; for (i = 1; i <= n; i += 3) { listFields.addEnd( dlg.addFieldValue( conpeek(_conFields, i), conpeek(_conFields, i + 1), conpeek(_conFields, i + 2))); } dlg.caption(_caption); if (dlg.run()) { enumerator = listFields.getEnumerator(); while (enumerator.moveNext()) { ret += enumerator.current().value(); } } return ret; } Пример использования статической функции InputBox X++: static void JobTestInputBox(Args _args) { ItemId ItemId; fromDate fromDate; toDate toDate; container con; ; // Тройки параметров аналогичны параметрам метода DialogRunbase.addFieldValue(...) con = InputBox( [typeid(ItemId), ItemId, '', typeid(fromDate), fromDate, '', typeid(toDate), toDate, ''], 'ТЕСТ'); if (con == conNull()) // Пользователь нажал кнопку "Отмена" { info('Операция прервана пользователем'); return; } [ItemId, fromDate, toDate] = con; info(strfmt('ItemId: %1', ItemId)); info(strfmt('fromDate: %1', fromDate)); info(strfmt('toDate: %1', toDate)); } |
|
![]() |
#4 |
Ищущий знания...
|
Цитата:
Вот Вы к вопросу подошли куда более профессионально, создав свою статическую функцию! Ваш код легко читается, и при поддержке его другим программистом никаких трудностей не возникнет, все достаточно прозрачно и понятно.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
![]() |
#5 |
MCT
|
Это еще цветочки, я работал на проекте, где было жесткое требование в части запросов, что если запрос используется более одного раза, то записывать его макросом. Интересно было было отлаживать такие вещи
![]() И этот человек ушел потом на повышение ![]()
__________________
Axapta book for developer |
|
![]() |
#6 |
Ищущий знания...
|
Цитата:
![]()
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: MikeR (1). |
|
![]() |
||||
Тема | Ответов | |||
axaptapedia: RunBaseBatch | 0 | |||
axaptapedia: RunBaseBatch | 0 | |||
axaptapedia: Macro | 1 | |||
axaptapedia: Adding only one Dimension in Dialog | 1 | |||
Kashperuk Ivan: 3 Dialog extensions | 4 |
|