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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 30.03.2016, 17:43   #1  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
Работа с Query.
Добрый день.
Я только начинаю тесно работать с MS DynamicsAX, просьба помочь разобраться с одним вопросом.
Есть диалог, с кнопкой "Выбрать", внутри должно быть 2 поля.
Но проблема в том, что при данном коде отображается только одно из полей, в зависимости от того, какой queryRun возвращается.
Объявил 2 QueryRun'а:
X++:
class ... extends RunBase

{
...
    QueryRun                    queryrun1, queryrun2;
...
}
Объявил 2 query, привязал 2 датасурса:
X++:
void initQuery()
{
    query query1 = new query();
    query query2 = new query();
    QueryBuildDataSource    qbds1, qbds2;
    ;

    qbds1= query1.addDataSource(tableNum(Table1));
    qbds2= query2.addDataSource(tablenum(Table2));

    queryrun1 = new queryRun(query1);
    queryrun2 = new queryRun(query2);
}
Далее есть метод, где данные обрабатываются и выводятся в ёксель:
X++:
void printSheet1()
{
...
    EDT    edt1, edt2;
    Table1    table1;
    Table2    table2;
...
    ;
    while (queryrun1.next())
    {
        table1 = queryrun1.get(tablenum(Table1));
        edt1 = Table1.Field1;

        while (queryrun2.next())
        {
            table2 = queryrun2.get(tableNum(Table2));
            edt2 = Table2.Field2;
            ....
        }
        queryrun2.reset();
    }
    queryrun1.reset();
}
Но всё упирается в следующий метод.
Если возвращаем queryrun1, то но форме будет только поле с Table1. И, соответственно, перебор будет по указанным значениям из Table1 и всем значениям из Table2. И наоборот.
X++:
public QueryRun queryRun()
{
    return queryrun1;
    //return queryrun2;
}
Может можно как-то всё проще реализовать или подскажите выход из сложившейся ситуации, какие могут быть варианты?
Старый 30.03.2016, 17:57   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
А включить Table1 и Table2 в один Query нельзя?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: Alucardkds (1).
Старый 30.03.2016, 18:19   #3  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
А включить Table1 и Table2 в один Query нельзя?
Можно, только я тогда никак не могу сообразить, каким образом организовать метод PrintSheet с перебором 2-мя while'ами.
Если я делал подобным образом, через один query, то у меня получалось, что если я беру одно значение из Table1 и несколько значений из Table2, то всё хорошо обрабатывается. А обратная ситуация - на выходе получаются не совсем корректный данные.
Просто приведённый выше код работает, как ни странно, осталось только вывести на форму диалога второе поле.

Последний раз редактировалось Alucardkds; 30.03.2016 в 18:31.
Старый 30.03.2016, 18:52   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Alucardkds Посмотреть сообщение
Далее есть метод, где данные обрабатываются и выводятся в ёксель:
X++:
void printSheet1()
{
...
    EDT    edt1, edt2;
    Table1    table1;
    Table2    table2;
...
    ;
    while (queryrun1.next())
    {
        table1 = queryrun1.get(tablenum(Table1));
        edt1 = Table1.Field1;

        while (queryrun2.next())
        {
            table2 = queryrun2.get(tableNum(Table2));
            edt2 = Table2.Field2;
            ....
        }
        queryrun2.reset();
    }
    queryrun1.reset();
}
два вложенных цикла дают в результате FULL JOIN.
Вы точно этого хотите получить в результате?

если да, то попробуйте выкрутиться при помощи двух последовательных queryRun.prompt()

но почему-то мне кажется, что вам нужно пересмотреть постановку задачи.
За это сообщение автора поблагодарили: Alucardkds (1).
Старый 30.03.2016, 18:56   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Alucardkds Посмотреть сообщение
Я только начинаю тесно работать с MS DynamicsAX
И еще. Здесь народ знает другие языки. И очень многие знают SQL.

Напишите что вы хотите реализовать на том языке, который вам удобен.
Или напишите SQL-запрос, который вы хотите реализовать в Аксапте.

Так будет проще.
За это сообщение автора поблагодарили: Alucardkds (1).
Старый 31.03.2016, 09:33   #6  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
Доброе утро.
Вариант с queryRun.prompt() помог решить проблему. Корректно отдельно заполняются оба query.

Цитата:
Напишите что вы хотите реализовать на том языке, который вам удобен.
Или напишите SQL-запрос, который вы хотите реализовать в Аксапте.
Первоначально была ситуация следующая:
Есть отчёт, где входящими значениями являются:
1. Начальная дата.
2. Конечная дата.
3. Подразделение работников. (Данные из Table1, что представляет из себя справочник подразделений специализированных рабочих).
4. Рабочее подразделение. (Данные из Table2, что представляет из себя справочник всех подразделений, используемых в системе, в том числе данные из Table1 есть в Table2).
И это были обыкновенные диалоговые поля с однозначным выбором, то есть 1 поле = 1 значение.

Пришёл запрос, что необходимо строить отчёт не по 1 значению, а по нескольким подразделениям, например,
1) 3 значения из Table1 и 1 значение из Table2 или
2) 2 значение из Table1 и 2 значения из Table2 (притом должны быть выведены значения по 4-м пар значений: 1-1, 1-2, 2-1, 2-2, где первое число в паре - введённое значение из Table1, а второе - из Table2).
И на эту задачу я придумал то решение, что описал в 1-м сообщении.
Но столкнувшись с проблемой решил здесь спросить совета, а вдруг я по незнанию упустил какой-то более простой и правильный вариант решения данной задачки.
Старый 31.03.2016, 11:45   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
3. Подразделение работников. (Table1)
4. Рабочее подразделение (Table2)
У Вас эти две таблицы никак не связаны между собой? Тот код, что Вы привели - именно так и работает. Т.е. на каждую запись Table1 в отчет выводятся ВСЕ записи Table2? Или все-таки между таблицами есть связь?

Т.е. Ваш отчет работает вот так

X++:
while select table1
{
    while select table2
    {
        (...)
    }
}
Или вот так

X++:
while select Table1
    join Table2
    where Table1.FieldId == Table2.FieldId
{
    (...)
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 31.03.2016, 12:03   #8  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
Цитата:
У Вас эти две таблицы никак не связаны между собой? Тот код, что Вы привели - именно так и работает. Т.е. на каждую запись Table1 в отчет выводятся ВСЕ записи Table2? Или все-таки между таблицами есть связь?
Да, эти таблицы связаны. В обеих таблицах есть поле DepartmentId и при создании записи в Table1 могут быть созданы только те, по которым есть записи в Table2.

И моя идея реализации работает по 1-ому варианту, да.
Но если есть что-то более оптимальное - с радостью выслушаю совет..

Последний раз редактировалось Alucardkds; 31.03.2016 в 12:15.
Старый 31.03.2016, 13:09   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Alucardkds Посмотреть сообщение
Да, эти таблицы связаны. В обеих таблицах есть поле DepartmentId и при создании записи в Table1 могут быть созданы только те, по которым есть записи в Table2.

И моя идея реализации работает по 1-ому варианту, да.
Но если есть что-то более оптимальное - с радостью выслушаю совет..
X++:
void initQuery()
{
    query query1 = new query();
   QueryBuildDataSource    qbds1, qbds2;
    ;

    qbds1= query1.addDataSource(tableNum(Table1));
    qbds2= qbds1.addDataSource(tablenum(Table2));

    // Если есть явно прописанные Relation на таблицах или в EDT
    //qbds2.relation(true);
    // Если нет, то указать объединение явно
    qbds2.addLink(fieldnum(Table1, DepartmentId), fieldnum(Table2, DepartmentId))

    // Явное указание полей, которые будут отображены в форме диалога
    qbds1.addRange(fieldnum(Table1, Field1));
    qbds2.addRange(fieldnum(Table2, Field1));

    queryrun1 = new queryRun(query1);
}
X++:
void printSheet1()
{
...
    EDT    edt1, edt2;
    Table1    table1;
    Table2    table2;
...
    ;
    while (queryrun1.next())
    {
        table1 = queryrun1.get(tablenum(Table1));
        table2 = queryrun1.get(tableNum(Table2));

        edt1 = Table1.Field1;
        edt2 = Table2.Field2;
        (...)
  }
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: mazzy (2), Alucardkds (1).
Старый 31.03.2016, 14:29   #10  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
Странно, но с предложенным вариантом ничего не хочет выводить.
Все whil'ы успешно пропускает как будто не сформировал query.
Хотя в initQuery заходит и даже успешно запросы делает в датасурс.
Старый 31.03.2016, 15:05   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
1. В методе queryRun() указан сформированный в initQuery() запрос?
2. В методах pack/unpack не выполняется сохранение/восстановление ранее выполненного запроса
3. Вы правильно определили условия объединения таблиц? Может их надо объединять не по DepartmentId?
4. Ну, и проверьте, какой же запрос реально выполняется

X++:
void printSheet1()
{
   (...)
   ;

   //debug
   // псевдо-скрипт выполняемого запроса
   info(queryrun1.query().dataSourceNo(1).toString());

   while (queryrun1.next())
   {
       (...)
   }
}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: Alucardkds (1).
Старый 31.03.2016, 17:46   #12  
Alucardkds is offline
Alucardkds
Участник
 
8 / 10 (1) +
Регистрация: 04.10.2014
1. В QueryRun всё в порядке.
2. Query у меня пока никак не сохраняется этими методами, не дошёл до этого.
Пункты 3. и 4.:
Изменил немного код и всё пошло как надо:
X++:
void initQuery()
{
    query query1 = new query();
   QueryBuildDataSource    qbds1, qbds2;
    ;

    qbds1= query1.addDataSource(tableNum(Table1));
    qbds1.firstfast(false);
    qbds2= qbds1.addDataSource(tablenum(Table2));
    qbds2.firstFast(false);

    //Убрал объединение
    //qbds2.addLink(fieldnum(Table1, DepartmentId), fieldnum(Table2, DepartmentId))

    // Явное указание полей, которые будут отображены в форме диалога
    qbds1.addRange(fieldnum(Table1, Field1));
    qbds2.addRange(fieldnum(Table2, Field1));

    queryrun1 = new queryRun(query1);
}
Спасибо огромное. (:
Старый 19.01.2017, 12:54   #13  
AR® is offline
AR®
Участник
 
30 / 15 (1) ++
Регистрация: 07.09.2012
Всё это хорошо, пока в объемлющем qbds (qbds1 в вышеприведённом примере) нет группировок.

Если же их добавить, то вложенная таблица (qbds2 / Table2 в вышеприведённом примере) просто перестанет выбираться: при вызове table2 = queryrun1.get(tableNum(Table2)) не будет заполняться table2.

Я знаю один выход из такого положения, но он слишком антилиберальный.
Если кто-то знает другие, буду благодарен за описание в данной теме.
Старый 19.01.2017, 13:12   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от AR® Посмотреть сообщение
Всё это хорошо, пока в объемлющем qbds (qbds1 в вышеприведённом примере) нет группировок.

Если же их добавить, то вложенная таблица (qbds2 / Table2 в вышеприведённом примере) просто перестанет выбираться.
Это потому что в таком случае произойдёт сначала соединение, а уже потом группировка. И если никакие поля вложенной таблицы не участвуют в группировке, то они и не выберутся.

Если вы хотите получить запрос где таблица сначала группируется, а потом к результату группировки джойнится вложенная таблица, то нужно использовать промежуточный View для группировки и уже этот View соединять с вложенной таблицей.

Проясните запрос

Последний раз редактировалось S.Kuskov; 19.01.2017 в 13:15.
Старый 19.01.2017, 13:24   #15  
AR® is offline
AR®
Участник
 
30 / 15 (1) ++
Регистрация: 07.09.2012
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
нужно использовать промежуточный View для группировки и уже этот View соединять с вложенной таблицей.
В приведённой теме речь о select'ах в коде - там это так.

А с qbds в query ничего не получится. Поля в разделе Group By в дизайне вьюхи будут проигнорированы, а qbds.addGroupByField(viewName, viewField) приведёт к тому, что вложенная таблица не будет выбираться.

Так в Ax2009.
Подчеркну, что речь идёт о несвязанных таблицах (ни через их Relation, ни через qbds2.addLink() ) , когда надо поучить декартово произведение двух выборок "всё на всё".

Последний раз редактировалось AR®; 19.01.2017 в 13:31.
Старый 19.01.2017, 13:31   #16  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от AR® Посмотреть сообщение
с qbds в query ничего не получится. Поля в разделе Group By в дизайне вьюхи будут проигнорированы
Почему вы так решили? Вы пробовали создать представление на основании запроса, содержащего группировку?

Цитата:
Сообщение от AR® Посмотреть сообщение
Подчеркну, что речь идёт о несвязанных таблицах (ни через их Relation, ни через qbds2.addLink() ) , когда надо поучить декартово произведение двух выборок "всё на всё".
Да какая разница. Наличие или отсутствие relation не меняет принципа соединения таблиц, а влияет только на последующую фильтрацию результата соединения.

Последний раз редактировалось S.Kuskov; 19.01.2017 в 13:35.
Старый 19.01.2017, 13:39   #17  
AR® is offline
AR®
Участник
 
30 / 15 (1) ++
Регистрация: 07.09.2012
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Почему вы так решили? Вы пробовали создать представление на основании запроса, содержащего группировку?
Я попробовал создать view на постоянной таблице и добавил требуемые поля (2 штуки) в Group By, они же оставлены как собственно поля view.
Группировки нет.
Старый 19.01.2017, 14:06   #18  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от AR® Посмотреть сообщение
Я попробовал создать view на постоянной таблице и добавил требуемые поля (2 штуки) в Group By, они же оставлены как собственно поля view.
Группировки нет.
https://msdn.microsoft.com/en-us/library/bb314551.aspx
Цитата:
Do not specify a field in the Group By element. A view does not use the field information in the Group By element.

Note: If you want to group the records in a view, replace the view data source with a query that has the specified group by information.
https://msdn.microsoft.com/en-us/lib...(v=ax.50).aspx
https://msdn.microsoft.com/en-us/lib...(v=ax.50).aspx
За это сообщение автора поблагодарили: AR® (1).
Старый 19.01.2017, 15:08   #19  
AR® is offline
AR®
Участник
 
30 / 15 (1) ++
Регистрация: 07.09.2012
Во-первых, спасибо за ссылки.
Во-вторых, получилось обойтись без вьюх и "индивидуальных" query для них.
Для этого необходимо и достаточно для вложенной таблицы (которую группировать вообще-то было не нужно) сделать qbds.addGroupByField() по всем полям её первичного ключа. Недостаток такого решения в том, что вызовом queryRun.get() нельзя получить поля, не включённые в группировку.
Старый 19.01.2017, 16:41   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от AR® Посмотреть сообщение
получилось обойтись без вьюх и "индивидуальных" query для них.
Для этого необходимо и достаточно для вложенной таблицы (которую группировать вообще-то было не нужно) сделать qbds.addGroupByField() по всем полям её первичного ключа. Недостаток такого решения в том, что вызовом queryRun.get() нельзя получить поля, не включённые в группировку.
Достаточно включить в группировку только нужные поля, ключевые без необходимости включать не обязательно. Связь всё равно сработает ведь она будет осуществлена до группировки
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
если никакие поля вложенной таблицы не участвуют в группировке, то они и не выберутся
Теги
query, queryrun

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
dynamicsaxhints: Query datasource FirstOnly property Blog bot DAX Blogs 0 22.03.2016 09:11
emeadaxsupport: Microsoft Dynamics AX general performance analysis scripts page 5 Blog bot DAX Blogs 0 01.09.2014 14:11
AIF: OData Query Service Blog bot DAX Blogs 0 24.08.2011 09:11
jinx: Dynamics AX – Query-Ranges und Filtereinstellungen des Benutzers Blog bot DAX auf Deutsch 0 04.02.2010 00:05
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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