AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.06.2015, 16:26   #1  
trudel is offline
trudel
Участник
 
52 / 10 (1) +
Регистрация: 17.04.2015
Как дважды подсоединить одну и туже таблицу
натыкался, а как надо - не найду. Подскажите.
Требуется при перемещении определить и склад откуда и склад куда. То есть 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)))
Мне надо как-то исправить, чтобы InventDim правильно понимался, чтобы условие накладывалось на Dim1 и на Dim2.

Последний раз редактировалось mazzy; 15.06.2015 в 18:00.
Старый 15.06.2015, 16:29   #2  
axm2013
Гость
 
n/a
Посмотрите форму InventJournalTransfer там нечто похожее
За это сообщение автора поблагодарили: trudel (1).
Старый 15.06.2015, 17:18   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 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  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
просто создайте нужный вам Query в AOT, а в коде напишите

X++:
Query q = new Query(querystr(mySuperQuery));
sysQuery::findOrCreateRange(q.dataSourceTable(tablenum(myTable),2),fieldnum(myTable, myField), 1).value(myRange);
обратите внимание на циферки 2,1. Это occurrence - номер по порядке в датасорсе и в таблице.

напишете так - вам же легче будет.
и следующие после вас специалисты вам спасибо скажут.

а вот это эклектика какая-то

Цитата:
Сообщение от trudel Посмотреть сообщение
X++:
qbr.value(strFmt('%1 != '+storesPR+' ',fieldstr(INVENTDIM,InventLocationId)))
могли бы и аккуратнее написать, единообразно
X++:
qbr.value(strFmt('%1 != %2 ',fieldstr(INVENTDIM,InventLocationId),storesPR))
За это сообщение автора поблагодарили: trudel (1).
Старый 16.06.2015, 07:38   #5  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от mazzy Посмотреть сообщение
а вот это эклектика какая-то ...
могли бы и аккуратнее написать, единообразно
X++:
qbr.value(strFmt('%1 != %2 ',fieldstr(INVENTDIM,InventLocationId),storesPR))
Это что попытка использовать выражения в фильтре? Тогда не хватает внешних круглых скобок. Но в данном случае выражения здесь не нужны, корректный вариант подсказал Владимир Максимов global::queryNotValue. Вот если бы нужно было задать условие типа: склад отправитель не равен складу получателю, то тогда без выражений было бы не обойтись.

P.S.: По поводу strFmt согласен.

trudel, в вашем первоначальном коде addLink делается дважды по одному и тому же полю ToInventDimID (опечатка?), если исправить это и корректно задать текст фильтра, то ваш вариант должен работать.

Последний раз редактировалось S.Kuskov; 16.06.2015 в 07:43.
За это сообщение автора поблагодарили: mazzy (6).
Старый 16.06.2015, 09:17   #6  
makbeth is offline
makbeth
Участник
Аватар для makbeth
КОРУС Консалтинг
 
43 / 52 (2) ++++
Регистрация: 15.05.2007
Адрес: Санкт-Петербург
Немного не по теме, но...
Я не понимаю, какой смысл писать Global::queryNotValue(...)? Если уж хочется указать класс, то проще сразу писать SysQuery::valueNot(..)? Короче и на один вложенный вызов меньше. А так смысл Global теряется совсем.
Старый 16.06.2015, 11:24   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от makbeth Посмотреть сообщение
Немного не по теме, но...
Я не понимаю, какой смысл писать Global::queryNotValue(...)? Если уж хочется указать класс, то проще сразу писать SysQuery::valueNot(..)? Короче и на один вложенный вызов меньше. А так смысл Global теряется совсем.
Как я понимаю, это скорее вопрос удобства.

Работа с Query - это довольно часто выполняемая операция. Как следствие, удобнее вынести эту обработку в общую "библиотеку" пользовательских функций Global, о которой "все знают", чем в специализированный класс SysQuery о котором еще надо "вспомнить"

На всякий случай напомню, что статические методы класса Global можно вызывать и без указания имени класса. Как системную функцию. Т.е. можно просто написать

queryNotValue(...)

Это уже лично я пишу имя класса, чтобы не вспоминать точное название метода, а посмотреть в выпадающем списке после ввода двоеточий. Мне так удобнее

Ну, и еще появляется возможность внести дополнительные параметры и обработки, не трогая класс SysQuery. Например, добавить второй параметр по аналогии с методом global::queryRangeConcat(), чтобы добавлять отрицание к уже существующему условию. Но это так, идет скорее дополнением (бонусом), чем причиной...
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 16.06.2015, 16:03   #8  
makbeth is offline
makbeth
Участник
Аватар для makbeth
КОРУС Консалтинг
 
43 / 52 (2) ++++
Регистрация: 15.05.2007
Адрес: Санкт-Петербург
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Работа с Query - это довольно часто выполняемая операция. Как следствие, удобнее вынести эту обработку в общую "библиотеку" пользовательских функций Global, о которой "все знают", чем в специализированный класс SysQuery о котором еще надо "вспомнить"
Проблема выноса подобных функций в Global в том, что Global в итоге превращается в помойку, где можно что-то очень долго искать, и... в конце концов действительно найти. ИМХО, Global - это место для расширения множества функций ядра, таких, как, например, расширения базовых функций работы со строками. Т.е. то, что не привязано к тому или иному специфическому функционалу.
Когда туда начинают сливать все подряд (ну а что, кому-нибудь пригодится же!), Global превращается не пойми во что с кучей непонятного и зачастую дублирующего друг друга функционала.
В итоге каждый раз начинаем искать то что нам подойдет:
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Это уже лично я пишу имя класса, чтобы не вспоминать точное название метода, а посмотреть в выпадающем списке после ввода двоеточий.


Мне кажется намного удобнее, когда вспомогательные функции именно для работы с запросами собраны в одном классе SysQuery, что в итоге значительно сужает область поиска. И другие такие примеры тоже есть, даже среди системных классов, например, DateUtil для utcdatetime или CLRInterop для работы с .NET. А есть еще, например, WinAPI/WinAPIServer

Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Ну, и еще появляется возможность внести дополнительные параметры и обработки, не трогая класс SysQuery. Например, добавить второй параметр по аналогии с методом global::queryRangeConcat(), чтобы добавлять отрицание к уже существующему условию.
А почему его нельзя трогать?
За это сообщение автора поблагодарили: Raven Melancholic (2).
Старый 16.06.2015, 18:03   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от makbeth Посмотреть сообщение
Проблема выноса подобных функций в Global в том, что Global в итоге превращается в помойку, где можно что-то очень долго искать, и... в конце концов действительно найти.
(...)
Когда туда начинают сливать все подряд (ну а что, кому-нибудь пригодится же!), Global превращается не пойми во что с кучей непонятного и зачастую дублирующего друг друга функционала.
В итоге каждый раз начинаем искать то что нам подойдет:
Если в этой цитате заменить "Global" на "SysQuery" что-нибудь изменится? "Чисто (...) там, где не мусорят" (с)

Проблему дублирования кода и "превращение в помойку" заменой одного класса на другой не исправишь...

Цитата:
Сообщение от makbeth Посмотреть сообщение
ИМХО, Global - это место для расширения множества функций ядра, таких, как, например, расширения базовых функций работы со строками. Т.е. то, что не привязано к тому или иному специфическому функционалу.
Было бы желание... Кто мешает создать класс с именем, например "strFunction" или "sysFunction" и напихать именно в него все статические метода по работе со строками?

Цитата:
Сообщение от makbeth Посмотреть сообщение
Мне кажется намного удобнее, когда вспомогательные функции именно для работы с запросами собраны в одном классе SysQuery,
Как я уже говорил, вопрос удобства при частом использовании. Т.е. банально, вопрос личных предпочтений

Цитата:
Сообщение от makbeth Посмотреть сообщение
что в итоге значительно сужает область поиска.
Сомнительно... Помнить все классы просто не реально. Как правило, это кончается созданием личной библиотеки наиболее часто используемых "функций". Т.е. некой альтернативы класса Global, куда собираются "свои" статические методы.

Цитата:
Сообщение от makbeth Посмотреть сообщение
И другие такие примеры тоже есть, даже среди системных классов, например, DateUtil для utcdatetime или CLRInterop для работы с .NET. А есть еще, например, WinAPI/WinAPIServer
Гм... Сделайте поиск в классе Global по ключевым словам "DateTimeUtil", "CLRInterop", "WinAPI". Результат может Вас удивить

Кстати, в Ax2009 классы DateTimeUtil и CLRInterop являются системными и изменить их невозможно. Создавать отдельные классы для расширения их функциональности или все-таки методы Global?

Цитата:
Сообщение от makbeth Посмотреть сообщение
А почему его нельзя трогать?
Можно, конечно, только если работаешь с классом Global, то логично и изменения вносить в класс Global...
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.06.2015, 12:22   #10  
trudel is offline
trudel
Участник
 
52 / 10 (1) +
Регистрация: 17.04.2015
А ВОТ по теме еще помогите

inventDim1 = queryRunSub.get(tableNum('Dim1'));

как теперь получить таблицу именно InventDim которая Dim1 ?
Старый 16.06.2015, 17:22   #11  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Это уже лично я пишу имя класса, чтобы не вспоминать точное название метода, а посмотреть в выпадающем списке после ввода двоеточий. Мне так удобнее
AxAssist очень помогает не вспоминать точное имя без добавления global::
Хотя согласен с makbeth что global часто превращается в помойку.
Теги
query, querybuildrange, queryvalue

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
QUERY - как присоединить одну таблицу к запросу несколько раз? Music DAX: Программирование 5 03.04.2015 12:11
Динамическое изменение прав доступа на одну таблицу DreamCreator DAX: Программирование 7 15.07.2009 16:31
Два DataSource на одну временную таблицу mou DAX: Программирование 4 22.03.2008 11:00
Разные права на одну таблицу coja DAX: Администрирование 3 24.03.2005 07:26
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:34.