15.06.2015, 16:26 | #1 |
Участник
|
Как дважды подсоединить одну и туже таблицу
натыкался, а как надо - не найду. Подскажите.
Требуется при перемещении определить и склад откуда и склад куда. То есть InventDim присоединяется дважды. X++: newQbds = SubQbds.addDataSource(tableNum(INVENTDIM),'Dim1'); newQbds.fetchMode(QueryFetchMode::One2One); newQbds.addLink(fieldNum(INVENTDIM, InventDimId), fieldNum(INVENTJOURNALTRANS, ToInventDimID)); newQbds.joinMode(JoinMode::InnerJoin); newQbds.orderMode(OrderMode::GroupBy); qbr =newQbds.addRange(fieldNum(INVENTDIM, InventLocationId)); qbr.value(strFmt('%1 != '+storesPR+' ',fieldstr(INVENTDIM,InventLocationId))) newQbds = SubQbds.addDataSource(tableNum(INVENTDIM),'Dim2'); newQbds.fetchMode(QueryFetchMode::One2One); newQbds.addLink(fieldNum(INVENTDIM, InventDimId), fieldNum(INVENTJOURNALTRANS, ToInventDimID)); newQbds.joinMode(JoinMode::InnerJoin); newQbds.orderMode(OrderMode::GroupBy); qbr =newQbds.addRange(fieldNum(INVENTDIM, InventLocationId)); qbr.value(strFmt('%1 != '+storesPR+' ',fieldstr(INVENTDIM,InventLocationId))) Последний раз редактировалось mazzy; 15.06.2015 в 18:00. |
|
15.06.2015, 16:29 | #2 |
Гость
|
Посмотрите форму InventJournalTransfer там нечто похожее
|
|
|
За это сообщение автора поблагодарили: trudel (1). |
15.06.2015, 17:18 | #3 |
Участник
|
Просто заведите РАЗНЫЕ переменные.
И не экономьте на буквах в названиях переменных. Давайте им, по возможности, такие имена, по которым будет понятно, что именно записано в этих переменных. Ну, хотя бы Вам самому будет понятно X++: QueryBuildDataSource qbdsInventDimFrom; QueryBuildDataSource qbdsInventDimTo; QueryBuildRange qbrInventLocationFrom; QueryBuildRange qbrInventLocationTo; (...) //---------------- From qbdsInventDimFrom = SubQbds.addDataSource(tableNum(INVENTDIM),'Dim1'); qbdsInventDimFrom.fetchMode(QueryFetchMode::One2One); qbdsInventDimFrom.addLink(fieldNum(INVENTDIM, InventDimId), fieldNum(INVENTJOURNALTRANS, InventDimID)); // from - это поле InventJournalTrans.InventDimId qbdsInventDimFrom.joinMode(JoinMode::InnerJoin); qbdsInventDimFrom.orderMode(OrderMode::GroupBy); qbrInventLocationFrom = qbdsInventDimFrom.addRange(fieldNum(INVENTDIM, InventLocationId)); //--------------- To qbdsInventDimTo = SubQbds.addDataSource(tableNum(INVENTDIM),'Dim2'); qbdsInventDimTo.fetchMode(QueryFetchMode::One2One); qbdsInventDimTo.addLink(fieldNum(INVENTDIM, InventDimId), fieldNum(INVENTJOURNALTRANS, ToInventDimID)); // to - это поле InventJournalTrans.ToInventDimId qbdsInventDimTo.joinMode(JoinMode::InnerJoin); qbdsInventDimTo.orderMode(OrderMode::GroupBy); qbrInventLocationTo = qbdsInventDimTo.addRange(fieldNum(INVENTDIM, InventLocationId)); //--------------- Value qbrInventLocationFrom.value(global::queryNotValue(storesPR)); qbrInventLocationTo.value(global::queryNotValue(storesPR));
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: mazzy (2), trudel (1). |
15.06.2015, 17:57 | #4 |
Участник
|
просто создайте нужный вам Query в AOT, а в коде напишите
X++: Query q = new Query(querystr(mySuperQuery)); sysQuery::findOrCreateRange(q.dataSourceTable(tablenum(myTable),2),fieldnum(myTable, myField), 1).value(myRange); напишете так - вам же легче будет. и следующие после вас специалисты вам спасибо скажут. а вот это эклектика какая-то Цитата:
X++: qbr.value(strFmt('%1 != %2 ',fieldstr(INVENTDIM,InventLocationId),storesPR)) |
|
|
За это сообщение автора поблагодарили: trudel (1). |
16.06.2015, 07:38 | #5 |
Участник
|
Цитата:
P.S.: По поводу strFmt согласен. trudel, в вашем первоначальном коде addLink делается дважды по одному и тому же полю ToInventDimID (опечатка?), если исправить это и корректно задать текст фильтра, то ваш вариант должен работать. Последний раз редактировалось S.Kuskov; 16.06.2015 в 07:43. |
|
|
За это сообщение автора поблагодарили: mazzy (6). |
16.06.2015, 09:17 | #6 |
Участник
|
Немного не по теме, но...
Я не понимаю, какой смысл писать Global::queryNotValue(...)? Если уж хочется указать класс, то проще сразу писать SysQuery::valueNot(..)? Короче и на один вложенный вызов меньше. А так смысл Global теряется совсем. |
|
16.06.2015, 11:24 | #7 |
Участник
|
Цитата:
Работа с Query - это довольно часто выполняемая операция. Как следствие, удобнее вынести эту обработку в общую "библиотеку" пользовательских функций Global, о которой "все знают", чем в специализированный класс SysQuery о котором еще надо "вспомнить" На всякий случай напомню, что статические методы класса Global можно вызывать и без указания имени класса. Как системную функцию. Т.е. можно просто написать queryNotValue(...) Это уже лично я пишу имя класса, чтобы не вспоминать точное название метода, а посмотреть в выпадающем списке после ввода двоеточий. Мне так удобнее Ну, и еще появляется возможность внести дополнительные параметры и обработки, не трогая класс SysQuery. Например, добавить второй параметр по аналогии с методом global::queryRangeConcat(), чтобы добавлять отрицание к уже существующему условию. Но это так, идет скорее дополнением (бонусом), чем причиной...
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
16.06.2015, 16:03 | #8 |
Участник
|
Цитата:
Когда туда начинают сливать все подряд (ну а что, кому-нибудь пригодится же!), Global превращается не пойми во что с кучей непонятного и зачастую дублирующего друг друга функционала. В итоге каждый раз начинаем искать то что нам подойдет: Цитата:
Мне кажется намного удобнее, когда вспомогательные функции именно для работы с запросами собраны в одном классе SysQuery, что в итоге значительно сужает область поиска. И другие такие примеры тоже есть, даже среди системных классов, например, DateUtil для utcdatetime или CLRInterop для работы с .NET. А есть еще, например, WinAPI/WinAPIServer А почему его нельзя трогать? |
|
|
За это сообщение автора поблагодарили: Raven Melancholic (2). |
16.06.2015, 17:22 | #9 |
Участник
|
Цитата:
Хотя согласен с makbeth что global часто превращается в помойку. |
|
16.06.2015, 18:03 | #10 |
Участник
|
Цитата:
Сообщение от makbeth
Проблема выноса подобных функций в Global в том, что Global в итоге превращается в помойку, где можно что-то очень долго искать, и... в конце концов действительно найти.
(...) Когда туда начинают сливать все подряд (ну а что, кому-нибудь пригодится же!), Global превращается не пойми во что с кучей непонятного и зачастую дублирующего друг друга функционала. В итоге каждый раз начинаем искать то что нам подойдет: Проблему дублирования кода и "превращение в помойку" заменой одного класса на другой не исправишь... Цитата:
Цитата:
Сомнительно... Помнить все классы просто не реально. Как правило, это кончается созданием личной библиотеки наиболее часто используемых "функций". Т.е. некой альтернативы класса Global, куда собираются "свои" статические методы. Цитата:
Кстати, в Ax2009 классы DateTimeUtil и CLRInterop являются системными и изменить их невозможно. Создавать отдельные классы для расширения их функциональности или все-таки методы Global? Можно, конечно, только если работаешь с классом Global, то логично и изменения вносить в класс Global...
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
17.06.2015, 12:22 | #11 |
Участник
|
А ВОТ по теме еще помогите
inventDim1 = queryRunSub.get(tableNum('Dim1')); как теперь получить таблицу именно InventDim которая Dim1 ? |
|
17.06.2015, 12:27 | #12 |
Участник
|
|
|