15.04.2011, 16:20 | #1 |
Участник
|
Преобразование datasource и query в табличный курсор
Приветствую!
Есть метод, который обрабатывает набор данных из таблицы. Сейчас сделано так, что набор данных передается в метод параметром - табличным курсором, в виде X++: public static boolean SetCheckStorno(CustPackingSlipTrans _trans) { // Обработка... } Потребовалось запускать этот метод для обработки записей, выводящихся на гриде, то есть с учетом установленных фильтров. Вопрос: можно ли как-то преобразовать query датасорса в табличный курсор? Если нет, то как посоветуете решать такую задачу - обработку данных с грида в независимом от грида методе? |
|
15.04.2011, 16:29 | #2 |
MCP
|
Можно пробежаться QueryRun по Query датасорса формы и вызывать в цикле этот метод, т.е. если источник данных под гридом на форме называется CustPackingSlipTrans то метод будет выглядеть так:
X++: void calc() { Query query; QueryRun qr; CustPackingSlipTrans custPackingSlipTransLocal; ; query = CustPackingSlipTrans_DS.query(); // query вашего датасорса qr = new QueryRun(query); while (qr.next()) { custPackingSlipTransLocal = qr.get(tableNum(custPackingSlipTrans)); // курсор с записью из грида element.SetCheckStorno(custPackingSlipTransLocal ); // вызов вашего метода } } Последний раз редактировалось kornix; 15.04.2011 в 16:35. |
|
15.04.2011, 17:11 | #3 |
Участник
|
Спасибо за совет, но метод обрабатывает записи в зависимости друг от друга, то есть должен получать их сразу пакетом... Хм, может, мне описанным образом пробегаться по записям, в нужных случаях (а я их знаю) делать нужный Select и передавать его в метод?
Как скажется на быстродействии, если вместо одного большого Select'а делать много маленьких? |
|
15.04.2011, 17:15 | #4 |
MCP
|
Цитата:
в нужных случаях (а я их знаю) делать нужный Select и передавать его в метод?
Цитата:
Как скажется на быстродействии, если вместо одного большого Select'а делать много маленьких?
|
|
15.04.2011, 17:24 | #5 |
Участник
|
Цитата:
Может быть, идеологически правильно было бы переделать метод, чтобы он принимал QueryRun, а не табличный курсор, и работал уже с ним? |
|
15.04.2011, 17:25 | #6 |
северный Будда
|
Тут уже много раз об этом писалось
Вот из последних - DataSource на форме, 4-е по порядку сообщение
__________________
С уважением, Вячеслав Последний раз редактировалось pitersky; 15.04.2011 в 17:32. |
|
15.04.2011, 17:32 | #7 |
MCP
|
Цитата:
|
|
15.04.2011, 18:19 | #8 |
Участник
|
Спасибо за ответы!
Я думал, что QeuryRun это по сути и есть табличная переменная - а вот поди ж ты, никак не вытащить в явном виде, только по одной записи... Цитата:
Сообщение от pitersky
Тут уже много раз об этом писалось
Вот из последних - DataSource на форме, 4-е по порядку сообщение Я пробовал Table1_ds.cursor() - он возвращает одну запись. Пробовал целиком Table1 - возвращается вся таблица, без фильтров. Цитата:
Сообщение от kornix
Если метод такой хитрый - возможно проще его переделать. По работе с датасорсами есть хорошая ветка. Что передавать на вход этому методу - вам видней, но если он работает с курсором и как-то перебирает в нем записи, наверно удобнее передать ему что-то другое
Что ж, наверное, так и буду делать: не пытаться передать табличную переменную в метод, а передавать QueryRun, или иным способом из метода получать доступ к DS или QueryRun, как описано в тех ветках. Жаль; мне казалось, что табличная переменная - это удобно. |
|
15.04.2011, 18:26 | #9 |
северный Будда
|
Geo, таблица тут вообще ни при чём. Выделенность - свойство датасоурса.
__________________
С уважением, Вячеслав |
|
15.04.2011, 18:37 | #10 |
Участник
|
Так мне выделенность и не нужна, мне фильтры нужны. А целиком Table1 я пробовал на всякий случай.
Думал, есть что-нибудь вроде table_ds.tableVariable() или queryRun.tableVariable() |
|
18.04.2011, 14:08 | #11 |
MCP
|
Честно говоря я никак не могу сообразить: что нужно получить в итоге?
Но если нужен фильтр - это однозначно Query датасорса. Если вам нужен фильтр и метод обрабатывает данные каким-то хитрым способом, в зависимости от наложенного фильтра - можно использовать в качестве параметра query. P.S.: QueryRun в качестве входного параметра использовать не желательно, т.к. обычно приходится добавлять условия в Query и получится такая картина: где-то был сформирован query, вы где-то от него сделали queryRun, потом передали его в метод, в методе опять получили от него query дополнили условия и т.п. Последний раз редактировалось kornix; 18.04.2011 в 14:11. |
|
18.04.2011, 14:21 | #12 |
MCTS
|
Цитата:
Обрабатывать стоит именно явно выделенные (промаркированные) пользователем записи, и каждую запись передавать в метод.
__________________
Dynamics AX Experience |
|
18.04.2011, 15:16 | #13 |
Участник
|
Похоже Вы пришли из 1С. Там очень любят пользоваться "ТаблицамиЗначений". В AX другой подход.
Если Вы пытаетесь сопоставить какие-то проводки, сделайте на форме кнопку, которая будет вызывать класс, выполняющийся на сервере. В этом классе вызывайте свой метод и передавайте в него просто критерии сопоставления (полученные из Args). Например, по такому-то то клиенту, за такой-то период. Накапливать данные во временных таблицах и "бегать" по ним - это крайний случай. Обычно достаточно выбора записей для обновления в определенном порядке (с заданным order by). После отработки класса обновите данные на форме. |
|
18.04.2011, 19:25 | #14 |
Участник
|
тоже не очень понимаю что нужно.
Geo, может сформулируете на человеческом языке исходную задачу? Query - запрос QueryRun - результаты, которые SQL-сервер отдает в ответ на Query QueryRun - позволяет обратится к текущей полученной позиции (одна запись, если таблица одна, или по одной записи на каждую таблицу в запросе). QueryRun.get() - метод, который возвращает данные в табличную переменную табличная переменная - хранит данные из одной записи таблицы внимание! если табличная переменная получена в результате select, то к ней можно применить next. типичный пример работы с query X++: void job1(Args args) { MyTable myTable; Query q = new Query(queryStr(myAOTQuery); // внутри что-то вроде select * from myTable; QueryRun qr = new QueryRun(q); while( qr.next() ) // в первый проход запрос отправляется на SQL-сервер { myTable = qr.get(myTable.TableId); ///.... } } myTable_ds.query() - запрос, который создал программист в AOT myTable_ds.queryRun() - результаты, которые выводятся в форму. Будьте внимательны с позиционированием и next. myTable_ds.queryRun().Query() - запрос, который действует в данный момент для данного экземпляра формы. Может отличаться от первоначального, если пользователь задаст фильтры, сортировку и т.п. Цитата:
Цитата:
в следующем выражении LedgerTrans ltr; переменная ltr является табличной в вашем понимании? надо отметить, что в Аксапте query и select-написанный-в-коде никогда не пересекаются. и никогда друг в друга не преобразуются. это два совершенно разных инструмента. Query никогда не преобразуется в select, а select никогда не преобразуется в Query. нет. это сильно устаревший и унаследованный от старых версий механизм, от которого никак не могут отказаться. в "табличных переменных" и в select'ах не работают пользовательские фильтры с запятыми, восклицательными знаками и прочими символами. кроме того, select нельзя динамически модифицировать. фильтры из Query не работают в select. |
|
|
За это сообщение автора поблагодарили: Geo (1). |
18.04.2011, 19:48 | #15 |
Участник
|
Что-то вы не правильное делаете
Используйте формы (и, соответственно, датасорты) для отображения данных Для обработки используйте классы Если в качестве входных параметров вам нужны данные, которые выбираются на форме, то можно использовать временную таблицу для их передачи (как например на форме InventTransRegister) Обратите внимание на то, что она инициализируется на сервере. Ваше решение с queryRun неверно с точки зрения бест практисес, так как экземпляр queryRun скорее всего будет на клиенте и будет генерить запросы к серверу. В итоге это может привести к тормозам |
|
|
За это сообщение автора поблагодарили: Geo (0). |
19.04.2011, 00:13 | #16 |
Участник
|
Большое спасибо за советы.
По постановке задачи, мне нужно из формы Отборочных накладных продажи запускать обработку, которая постарается за (какое-то) последнее время автоматически проставить признак сторно в сторнированную/сторнирующую строки накладных (добавлен такой нами) и выдаст предупреждения в тех случаях, когда сделать этого (автоматически) не сможет. Желание использовать фильтр грида (обрабатывать только те строки Отборочных, которые ему удовлетворяют) вызвано тем, что за Отборочные отвечают разные люди. Сооответственно, пользователю не нужно видеть предупреждения по "не его" Отборочным, да и проставлять сторно по "чужим" не следовало бы, наверное. Поэтому мне не хватило бы только критерия даты. Еще могут потребоваться, как минимум, номенклатура и код создавшего запись пользователя; а вообще там можно предположить разные фильтры. Потому я и хочу брать в обработку только те записи, которые пользователь сам для себя отфильтровал для работы, с произвольными критериями. Цитата:
Цитата:
Что вы называете табличной переменной?
в следующем выражении LedgerTrans ltr; переменная ltr является табличной в вашем понимании? Select ltr Where ltr.transDate == xx\xx\xxxх; , то уж точно. Цитата:
надо отметить, что в Аксапте query и select-написанный-в-коде никогда не пересекаются. и никогда друг в друга не преобразуются. это два совершенно разных инструмента. Query никогда не преобразуется в select, а select никогда не преобразуется в Query.
Обозвал только табличную переменную табличным курсором (думал, что это синонимы ) |
|
19.04.2011, 00:18 | #17 |
Участник
|
Цитата:
Сообщение от CDR
Обрабатывать записи, выводящиеся в грид - не совсем правильно, т.к. в общем случае пользователь может и не видеть ВСЕХ отфильтрованных записей, которые выводятся в грид. Более того, аксапта может и не выбрать из БД все отфильтрованные записи для отображения на форме (например, условиям фильтра удовлетворяют 100 записей, на форме отображаются 15 записей, а в курсор из базы выбраны только 30 записей).
Обрабатывать стоит именно явно выделенные (промаркированные) пользователем записи, и каждую запись передавать в метод. |
|
19.04.2011, 00:41 | #18 |
Участник
|
Цитата:
queryRun - это и есть результаты, которые SQL-сервер отдает в ответ на Query. |
|
19.04.2011, 01:01 | #19 |
Участник
|
Цитата:
грид живет на клиенте. данные живут на сервере. со всеми вытекающими последствиями для трафика и производительности вам уже об этом говорили. =============== по поводу "выделенных строк" см axaptapedia: Tutorial Form MultiSelectCheckBox но обратите внимание, что "выделенные строки" и "отфильтрованные строки" - разные вещи. |
|
19.04.2011, 10:09 | #20 |
северный Будда
|
Цитата:
И кстати говоря - не стал бы я так уж хаять механизм селектов. Достаточно много есть задач, где нужна жёсткая выборка с простейшим суммированием, типа X++: while select sum(Qty) from MyTable group by ItemId {...}
__________________
С уважением, Вячеслав Последний раз редактировалось pitersky; 19.04.2011 в 10:14. |
|
Теги |
grid, query, датасорс (datasource), табличный курсор, фильтр |
|
|