|  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 | 
| Участник | |
|  |