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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.06.2017, 18:27   #21  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
уже хорошо.
но можно лучше.

SysQuery::findOrCreateDataSource(query добавляет в корень.
и не задает связь, насколько я помню.

создайте ВЕСЬ запрос в АОТ. избавьте себя от необходимости манипулировать с датасорсами.
в коде устанавливайте только range.value.

даю маячок - в АОТ можно создать ДВА запроса. один для InventLocationType::Standard, другой для прочих типов.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 18:33   #22  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
и еще. в запросе у вас сейчас для InventLocationTo, InventLocationFrom не указан тип связь.
По умолчанию тип связи к InventTransferTable будет Innerjoin.

и насколько я понимаю, в запросе не указано свойство groupby.

это точно то, что вы хотите?

и если будете постить еще варианты, то пожалуйста, всегда добавляйте результаты q.datasourceno(1).tosting().
очень помогает разобраться с запросами.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 18:46   #23  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Query я подправил. Сейчас без InventTable работает, а вот с ней висит на подсчете количества
X++:
query = new Query(querystr(myQuery));
    SysQuery::findOrCreateRange(query.dataSourceTable(tableNum(InventTransferTable)), fieldnum(InventTransferTable, ReceiveDate)).value(strfmt('%1..%2', 20\05\2017, toDay()));
    SysQuery::findOrCreateRange(query.dataSourceTable(tableNum(InventTransferTable)), fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received));
    SysQuery::findOrCreateRange(query.dataSourceTable(tableNum(InventTransferTable)), fieldnum(InventTransferTable, InventLocationIdFrom)).value('242');

    if (inventLocationType != InventLocationType::Standard)
    {
        qbrDataAreaId = SysQuery::findOrCreateRange(query.dataSourceTable(tableNum(InventLocation), 2), fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 = %4) || (%2.%3 = %4))',
            'InventLocationTo',
            'InventLocationFrom',
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    s = query.datasourceno(1).toString();

    info(s);

    queryRun = new QueryRun(query);

    iRowCountTmp = SysQuery::countLoops(queryRun);
Без InventTable
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId AND ((((InventLocationTo.InventLocationType = 3) || (InventLocationFrom.InventLocationType = 3))))

С InventTable
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId AND ((((InventLocationTo.InventLocationType = 3) || (InventLocationFrom.InventLocationType = 3)))) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId
Вложения
Тип файла: xpo myQuery.xpo (3.8 Кб, 382 просмотров)
Старый 19.06.2017, 18:52   #24  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
В общем, код должен выглядеть примерно так:

X++:
Query query = new Query(querystr(myQuery));
QueryBuildDataSource qbdsItt = query.datasourcetable(tableNum(InventTransferTable)); // никаких Create! только читаем
QueryBuildDataSource qbdsIlTo = query.datasourcetable(tableNum(InventLocation),1); // первый по порядку. Или query.datasource("InventLocationTo") позволяет получить датасорс по имени
QueryBuildDataSource qbdsIlFrom = query.datasourcetable(tableNum(InventLocation),2); // второй по порядку. Или query.datasource

Debug::assert(qbdsItt);
Debug::assert(qbdsIlTo);
Debug::assert(qbdsIlFrom);

    qbdsItt.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(SysQuery::range(fromDate, toDate));
    qbdsItt.addRange(fieldnum(InventTransferTable, TransferStatus)).value(SysQuery::value(InventTransferStatus::Received)); // может быть, лучше сразу задать в запросе в АОТ
    qbdsItt.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value(inventLocationId);

    if (inventLocationType != InventLocationType::Standard)
    {
        SysQuery::findOrCreateRange(qbdsIlTo, fieldNum(InventLocation, DataAreaId))
            .value(strFmt('((%1.%3 = %4) || (%2.%3 = %4))',
                qbdsIlTo.name(),
                qbdsIlFrom.name(),
                fieldStr(InventLocation, InventLocationType),
                any2int(inventLocationType)));
    }

    //info(qbdsItt.ToString());

    queryRun = new QueryRun(query);

    rowCount = SysQuery::countLoops(queryRun);
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 19.06.2017 в 18:59.
Старый 19.06.2017, 18:56   #25  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Да, насчет количества строк.
Цитата:
Сообщение от smailik Посмотреть сообщение
При запуске висит на подсчете количества строк.
у меня нет под рукой акс4, но насколько я понимаю из текстового файла с запросом, вы не задали Relation между датасорсами.
вот там и происходило декартово произведение.

без InventTable в запросе получается три несвязанные таблицы, насколько я понимаю.
как раз для понимания и нужен результат q.datasource().tostring().
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 19:11   #26  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Сейчас код выглядит так.
X++:
query = new Query(querystr(myQuery));

    qbdsItt = query.datasourcetable(tableNum(InventTransferTable));
    qbdsItt.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(SysQuery::range(20\05\2017, toDay()));
    qbdsItt.addRange(fieldnum(InventTransferTable, TransferStatus)).value(SysQuery::value(InventTransferStatus::Received)); // может быть, лучше сразу задать в запросе в АОТ
                                    // нет так как это параметр который передается с формы, он может быть и не указан так же как и склад и диапазон дат
    qbdsItt.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value('242');

    qbdsIlTo = query.datasourcetable(tableNum(InventLocation),1); 
    qbdsIlFrom = query.datasourcetable(tableNum(InventLocation),2);

    if (inventLocationType != InventLocationType::Standard)
    {
        qbrDataAreaId = qbdsIlTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 = %4) || (%2.%3 = %4))',
            qbdsIlTo.name(),
            qbdsIlFrom.name(),
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    s = query.datasourceno(1).toString();

    info(s);

    queryRun = new QueryRun(query);

    iRowCountTmp = SysQuery::countLoops(queryRun);
В Query перепроверил все relation. Сейчас все есть. Вот только не понимаю почему в текстовом запросе нет упоминания InventTransferLine?
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) AND ((InventLocationIdFrom = N'242')) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId AND ((((InventLocationTo.InventLocationType = 3) || (InventLocationFrom.InventLocationType = 3)))) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId
За это сообщение автора поблагодарили: mazzy (2).
Старый 19.06.2017, 19:12   #27  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от smailik Посмотреть сообщение
Без InventTable
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId AND ((((InventLocationTo.InventLocationType = 3) || (InventLocationFrom.InventLocationType = 3))))
Ага. связь есть.
Ага. интересно.

А можно попросить вас выкинуть из проекта все, не относящееся к вопросу.
в частности ReceiveDate, TransferStatus. оставьте только то, что относится к вопросу с ИЛИ.

должно остаться так:
Цитата:
Сообщение от smailik Посмотреть сообщение
Без InventTable
SELECT * FROM InventTransferTable WHERE JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE ((((InventLocationTo.InventLocationType = 3) || (InventLocationFrom.InventLocationType = 3))))

насколько я понимаю, ситуация вот в чем:
1. в запросе используется одна и та же таблица два раза (СкладОткуда, СкладКуда)
2. нужно добавить сложное ИЛИ-условие со ссылками на эти две таблицы.
3. как в ИЛИ условие добавить информацию, что это разные таблицы?

Сейчас видно, что в тексте запроса отображается два одинаковых имя, хотя запрос составлен совершенно корректно.

вроде, это где-то уже обсуждалось.

==========
smailik, Logger уже спрашивал. а можете показать текст SQL-запроса, который показывает сам SQL?
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: smailik (1).
Старый 19.06.2017, 19:17   #28  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от smailik Посмотреть сообщение
Вот только не понимаю почему в текстовом запросе нет упоминания InventTransferLine?
аксапта не гарантирует, что query будет выполнен одним SQL-запросом.
очень часто аксапта разбивает выполнение Query на несколько SQL-запросов.

разбитие зависит от временных таблиц, кэшируемых таблиц, сложных запросов с невложенными связями, existJoin.
https://msdn.microsoft.com/en-us/library/bb314836.aspx

вполне вероятно, что аксапта разбила запрос на несколько.
поэтому вам и советовали вытянуть в цепочку.

сейчас предлагаю на этом не зацикливаться.
проблема в том, что у вас две таблицы с одинаковым именем, нужно указать текстовое условие в скобках для обеих.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 19:23   #29  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
1. Да 2. Да 3. Да
X++:
query = new Query(querystr(myQuery));
    qbdsItt = query.datasourcetable(tableNum(InventTransferTable));
    qbdsIlFrom = query.datasourcetable(tableNum(InventLocation), 1);
    qbdsIlTo = query.datasourcetable(tableNum(InventLocation), 2);

    if (inventLocationType != InventLocationType::Standard)
    {
        qbrDataAreaId = qbdsIlTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))',
            qbdsIlTo.name(),
            qbdsIlFrom.name(),
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    s = query.datasourceno(1).toString();
    info(s);

    queryRun = new QueryRun(query);
    iRowCountTmp = SysQuery::countLoops(queryRun);
Какой запрос на SQL показать не смогу. У меня нет туда доступа

SELECT * FROM InventTransferTable JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId AND ((((InventLocationTo.InventLocationType == 8) || (InventLocationFrom.InventLocationType == 8))))
Старый 19.06.2017, 19:33   #30  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
опять у вас 8 появилось. видимо это модификация ваша какая-то.
не суть.
вопрос понятен. вполне правомерен.

если ответа не дадут, попробую из дома посмотреть на акс2012 через часик-два.
что-то подобное уже было.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 19:35   #31  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
8 это если вдруг заработает, то с этим типом складов раз два и кончились, т.е счетчик посчитается быстрее
Старый 19.06.2017, 19:41   #32  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Вопрос пока еду: а зачем вам делать сложное условие именно на приджойненных таблицах? У вас же оба поля складОткуда и складКуда в шапке есть.

Да, на них может не быть индексов... но очень вероятно что индексы нужны и пользователям для поиска.

И это соображение не отменяет исходного вопроса про сложное условие
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 19:49   #33  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Не понял вопроса. Я ведь фильтрую по типу складов Откуда/Куда. Или же Вы предлагаете строить query без них и в while (queryRun.next()) обрабатывать значения?
Старый 19.06.2017, 20:01   #34  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Да. Дурсть спросил. Извините.
Щас до компа доберусь.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 20:08   #35  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
1) в запросах надо использовать == http://www.axaptapedia.com/Expressions_in_query_ranges
2) нельзя ли попробовать исходный запрос добавив :
- fetchmode one to one для invent table
- addselection field maxof(tableid)
Старый 19.06.2017, 20:09   #36  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Ларчик у меня открылся вот как. Изначально почитав http://www.axaptapedia.com/Expressions_in_query_ranges я использовал ExistsJoin. Потом спасибо S.Kuskov тип связи изменился на InnerJoin. И тогда встал вопрос, а почему структура query до сих пор такая? Почему бы не поднять InventLocation выше? Поднял и все заработало. Код который бил показан он тестовый и поэтому упрошенный. Сейчас рабочий код выглядит так
X++:
qbds = query.addDataSource(tablenum(InventTransferTable));

    qbds.orderMode(OrderMode::GroupBy);
    qbds.addSortField(fieldnum(InventTransferTable, TransferId));
    qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdTo));
    qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdFrom));
    qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdTransit));
    qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdLater));
    qbds.addSortField(fieldnum(InventTransferTable, ReceiveDate));
    qbds.addSortField(fieldnum(InventTransferTable, TransferStatus));

    qbds.addSortField(fieldnum(InventTransferTable, InventLocationIdLater));

    if (fromDate && toDate)//Дата
    {
       qbds.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(strfmt('%1..%2', fromDate, toDate));
    }

    if (receivedOnly)
    {
        qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received));
    }
    else
    {
        qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Shipped));
        qbds.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received));
    }

    if (inventLocationId_From)//Отправлено Откуда
    {
        qbds.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value(inventLocationId_From);
    }

    if (inventLocationId_To)//Отправлено Куда
    {
        qbds.addRange(fieldnum(InventTransferTable, InventLocationIdTo)).value(inventLocationId_To);
    }
    
    if (inventLocationType != InventLocationType::Standard)
    {
        qbdsInventLocationFrom = qbds.addDataSource(tablenum(InventLocation));
        qbdsInventLocationFrom.addLink(fieldNum(InventTransferTable, InventLocationIdFrom), fieldNum(InventLocation, InventLocationId));
        qbdsInventLocationFrom.joinMode(JoinMode::InnerJoin);
        qbdsInventLocationFrom.fetchMode(QueryFetchMode::One2One);

        qbdsInventLocationTo = qbds.addDataSource(tableNum(InventLocation));
        qbdsInventLocationTo.addLink(fieldNum(InventTransferTable, InventLocationIdTo), fieldNum(InventLocation, InventLocationId));
        qbdsInventLocationTo.joinMode(JoinMode::InnerJoin);
        qbdsInventLocationTo.fetchMode(QueryFetchMode::One2One);

        qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))',
            qbdsInventLocationFrom.name(),
            qbdsInventLocationTo.name(),
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    qbds1 = qbds.addDataSource(tablenum(InventTransferLine));
    qbds1.addLink(fieldnum(InventTransferTable, TransferId), fieldnum(InventTransferLine , TransferId));
    qbds1.joinMode(JoinMode::InnerJoin);
    qbds1.orderMode(OrderMode::GROUPBY);
    qbds1.fetchMode(QueryFetchMode::One2One);
    qbds1.addSortField(fieldnum(InventTransferLine, ItemId));
    qbds1.addSortField(fieldnum(InventTransferLine, Out_ItemId));
    qbds1.addSortField(fieldnum(InventTransferLine, QtyTransfer));

    qbds2 = qbds1.addDataSource(tableNum(InventSum));
    qbds2.addLink(fieldnum(InventTransferLine, ItemId), fieldNum(InventSum, ItemId));
    qbds2.joinMode(joinMode::InnerJoin);
    qbds2.orderMode(OrderMode::GROUPBY);
    qbds2.fetchMode(QueryFetchMode::One2One);
    qbds2.addSortField(fieldnum(InventSum, ItemId));
    qbds2.addSelectionField(fieldnum(InventSum, ReservPhysical), SelectionField::SUM);
    qbds2.addSelectionField(fieldnum(InventSum, PostedQty), SelectionField::SUM);
    qbds2.addSelectionField(fieldnum(InventSum, Received), SelectionField::SUM);
    qbds2.addSelectionField(fieldnum(InventSum, Deducted), SelectionField::SUM);
    qbds2.addSelectionField(fieldnum(InventSum, Registered), SelectionField::SUM);
    qbds2.addSelectionField(fieldnum(InventSum, Picked), SelectionField::SUM);

    qbds2.addRange(fieldnum(InventSum, Closed)).value(SysQuery::value(NoYes::No));

    qbds2.addRange(fieldNum(InventSum, PhysicalInvent)).value("> 0");

    queryRun = new QueryRun(query);
За это сообщение автора поблагодарили: mazzy (2).
Старый 19.06.2017, 20:32   #37  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от smailik Посмотреть сообщение
Код который бил показан он тестовый и поэтому упрошенный.
это понятно и нормально.

про код тоже понятно.
но проблема то не решена. в скобках у вас по прежнему названия датасорсов, а в самом тексте запроса используются названия таблиц.

аксапта не проверяет синтаксис внутри скобок. поэтому и не выдает ошибки.
но с точки зрения SQL запрос будет синтаксически неверным.

Цитата:
Сообщение от smailik Посмотреть сообщение
X++:
        qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))',
            qbdsInventLocationFrom.name(),
            qbdsInventLocationTo.name(),
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }
вы точно сейчас получаете ожидаемый результат?
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 20:43   #38  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
При генерации SQL, насколько я знаю, query использует имена источников данных, а не таблиц. просто если их явно не указывать, они генерируются автоматически
За это сообщение автора поблагодарили: mazzy (2).
Старый 19.06.2017, 21:23   #39  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Сейчас при изменении InventLocationType результат меняется. Сделал визуальную проверку выводимым данных. Фильтр накладывается верно.
За это сообщение автора поблагодарили: mazzy (2).
Старый 19.06.2017, 21:25   #40  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от mazzy Посмотреть сообщение
3. как в ИЛИ условие добавить информацию, что это разные таблицы?
в общем, интересно.
акс2012 выдает результат toString() немного в другом виде. с алиасами (именами датасорсов).

вот код и запрос в акс2012.
QueryRun нужен только для того, чтобы отправить запрос на SQL.

X++:
static void Job2(Args _args)
{
    QueryRun             qr;
    Query                q = new Query(queryStr(Query2));
    QueryBuildDataSource qbdsITT = q.dataSourceTable(tableNum(inventTransferTable));
    QueryBuildDataSource qbdsILfrom = q.dataSourceTable(tableNum(InventLocation), 1);
    QueryBuildDataSource qbdsILto = q.dataSourceTable(tableNum(InventLocation), 2);
    QueryBuildRange      qbr = SysQuery::findOrCreateRange(qbdsILfrom, fieldNum(InventLocation, DataAreaId));
    ;
    Debug::assert(qbr != null);
    Debug::assert(qbdsILfrom != null);
    Debug::assert(qbdsILto != null);
        
    qbr.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))',
        qbdsIlTo.name(),
        qbdsIlFrom.name(),
        fieldStr(InventLocation, InventLocationType),
        3));
    
    qr = new QueryRun(q);
    qr.next();

    info(q.dataSourceNo(1).toString());
}
результат в инфологе:
X++:
SELECT * FROM InventTransferTable(InventTransferTable_1) JOIN * FROM InventLocation(InventLocation_1) ON InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId AND 0 = InventLocation.InventLocationType AND ((((InventLocation_2.InventLocationType == 3) || (InventLocation_1.InventLocationType == 3)))) JOIN * FROM InventLocation(InventLocation_2) ON InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId AND 0 = InventLocation.InventLocationType
запрос в SQL (без forceLiteral для чистоты эксперимента)
X++:
declare @p1 int
set @p1=1074248408
declare @p2 int
set @p2=180888571
declare @p5 int
set @p5=16
declare @p6 int
set @p6=1
declare @p7 int
set @p7=0
exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 bigint,@P2 nvarchar(5),@P3 bigint,@P4 nvarchar(5),@P5 int,@P6 int,@P7 int,@P8 bigint,@P9 nvarchar(5),@P10 int',N'SELECT T1.TRANSFERID,T1.INVENTLOCATIONIDFROM,T1.INVENTLOCATIONIDTO,T1.TRANSFERSTATUS,T1.SHIPDATE,T1.RECEIVEDATE,T1.FROMADDRESSNAME,T1.TOADDRESSNAME,T1.AUTORESERVATION,T1.DLVMODEID,T1.DLVTERMID,T1.FREIGHTZONEID,T1.FREIGHTSLIPTYPE,T1.FROMCONTACTPERSON,T1.INVENTLOCATIONIDTRANSIT,T1.ATPINCLPLANNEDORDERS,T1.ATPTIMEFENCE,T1.DELIVERYDATECONTROLTYPE,T1.TOCONTACTPERSON,T1.ATPAPPLYSUPPLYTIMEFENCE,T1.ATPAPPLYDEMANDTIMEFENCE,T1.ATPBACKWARDDEMANDTIMEFENCE,T1.ATPBACKWARDSUPPLYTIMEFENCE,T1.FROMPOSTALADDRESS,T1.TOPOSTALADDRESS,T1.STATPROCID,T1.PORT,T1.TRANSPORT,T1.TRANSACTIONCODE,T1.TRANSFERTYPE_IN,T1.TRPACKINGSLIPAUTONUMBERING_LT,T1.INVENTPROFILETYPE_RU,T1.INVENTPROFILEID_RU,T1.INVENTPROFILEUSERELATED_RU,T1.DRIVERCONTACT_RU,T1.TRANSPORTINVOICETYPE_RU,T1.CARGODESCRIPTION_RU,T1.CARGOPACKING_RU,T1.RETAILREPLENISHREFTABLEID,T1.RETAILREPLENISHREFRECID,T1.RETAILRETAILSTATUSTYPE,T1.CARRIERCODE_RU,T1.CARRIERTYPE_RU,T1.CURRENCYCODE_RU,T1.DELIVERYDATE_RU,T1.DRIVER_RU,T1.DRIVERNAME_RU,T1.DRIVINGLICENSENUM_RU,T1.INTRASTATFULFILLMENTDATE_HU,T1.INTRASTATSPECMOVE_CZ,T1.INVENTPROFILEIDTO_RU,T1.LADINGPOSTALADDRESS_RU,T1.LICENSECARDNUM_RU,T1.LICENSECARDREGNUM_RU,T1.LICENSECARDSERIES_RU,T1.LICENSECARDTYPE_RU,T1.PARTYACCOUNTNUM_RU,T1.PARTYAGREEMENTHEADEREXT_RU,T1.PDSOVERRIDEFEFO,T1.PRICEGROUPID_RU,T1.TRANSFERTYPE_RU,T1.TRANSPORTATIONDOCUMENT,T1.TRANSPORTATIONPAYER_RU,T1.TRANSPORTATIONPAYERTYPE_RU,T1.TRANSPORTATIONTYPE_RU,T1.UNLADINGPOSTALADDRESS_RU,T1.VEHICLEMODEL_RU,T1.VEHICLEPLATENUM_RU,T1.WAYBILLNUM_RU,T1.SHOULDPOSTEXPENSEAMTTOINVENTORY_IN,T1.CREATEDDATETIME,T1.RECVERSION,T1.PARTITION,T1.RECID,T2.INVENTLOCATIONID,T2.NAME,T2.MANUAL,T2.EMPTYPALLETLOCATION,T2.MAXPICKINGROUTEVOLUME,T2.PICKINGLINETIME,T2.MAXPICKINGROUTETIME,T2.WMSLOCATIONIDDEFAULTRECEIPT,T2.WMSLOCATIONIDDEFAULTISSUE,T2.INVENTLOCATIONIDREQMAIN,T2.REQREFILL,T2.INVENTLOCATIONTYPE,T2.INVENTLOCATIONIDQUARANTINE,T2.INVENTLOCATIONLEVEL,T2.REQCALENDARID,T2.WMSAISLENAMEACTIVE,T2.WMSRACKNAMEACTIVE,T2.WMSRACKFORMAT,T2.WMSLEVELNAMEACTIVE,T2.WMSLEVELFORMAT,T2.WMSPOSITIONNAMEACTIVE,T2.WMSPOSITIONFORMAT,T2.USEWMSORDERS,T2.INVENTLOCATIONIDTRANSIT,T2.VENDACCOUNT,T2.BRANCHNUMBER,T2.INVENTSITEID,T2.INVENTCOUNTINGGROUP_BR,T2.CUSTACCOUNT_BR,T2.INVENTPROFILETYPE_RU,T2.INVENTPROFILEID_RU,T2.INVENTLOCATIONIDGOODSINROUTE_RU,T2.WMSLOCATIONIDGOODSINROUTE_RU,T2.ACTIVITYTYPE_RU,T2.NUMBERSEQUENCEGROUP_RU,T2.RETAILWEIGHTEX1,T2.FSHSTORE,T2.RBODEFAULTWMSPALLETID,T2.RBODEFAULTWMSLOCATIONID,T2.RBODEFAULTINVENTPROFILEID_RU,T2.ALLOWLABORSTANDARDS,T2.ALLOWMARKINGRESERVATIONREMOVAL,T2.CONSOLIDATESHIPATRTW,T2.CUSTACCOUNT_HU,T2.CYCLECOUNTALLOWPALLETMOVE,T2.DECREMENTLOADLINE,T2.DEFAULTKANBANFINISHEDGOODSLOCATION,T2.DEFAULTPRODUCTIONFINISHGOODSLOCATION,T2.DEFAULTSHIPMAINTENANCELOC,T2.DEFAULTSTATUSID,T2.PRINTBOLBEFORESHIPCONFIRM,T2.PRODRESERVEONLYWHSE,T2.REMOVEINVENTBLOCKINGONSTATUSCHANGE,T2.RESERVEATLOADPOST,T2.RETAILINVENTNEGFINANCIAL,T2.RETAILINVENTNEGPHYSICAL,T2.RETAILWMSLOCATIONIDDEFAULTRETURN,T2.RETAILWMSPALLETIDDEFAULTRETURN,T2.UNIQUECHECKDIGITS,T2.VENDACCOUNTCUSTOM_RU,T2.WAREHOUSEAUTORELEASERESERVATION,T2.WHSENABLED,T2.DEFAULTCONTAINERTYPECODE,T2.DEFAULTPRODUCTIONINPUTLOCATION,T2.DEFAULTRETURNCREDITONLYLOCATION,T2.WHSRAWMATERIALPOLICY,T2.MODIFIEDDATETIME,T2.DEL_MODIFIEDTIME,T2.MODIFIEDBY,T2.CREATEDDATETIME,T2.DEL_CREATEDTIME,T2.CREATEDBY,T2.RECVERSION,T2.PARTITION,T2.RECID,T3.INVENTLOCATIONID,T3.NAME,T3.MANUAL,T3.EMPTYPALLETLOCATION,T3.MAXPICKINGROUTEVOLUME,T3.PICKINGLINETIME,T3.MAXPICKINGROUTETIME,T3.WMSLOCATIONIDDEFAULTRECEIPT,T3.WMSLOCATIONIDDEFAULTISSUE,T3.INVENTLOCATIONIDREQMAIN,T3.REQREFILL,T3.INVENTLOCATIONTYPE,T3.INVENTLOCATIONIDQUARANTINE,T3.INVENTLOCATIONLEVEL,T3.REQCALENDARID,T3.WMSAISLENAMEACTIVE,T3.WMSRACKNAMEACTIVE,T3.WMSRACKFORMAT,T3.WMSLEVELNAMEACTIVE,T3.WMSLEVELFORMAT,T3.WMSPOSITIONNAMEACTIVE,T3.WMSPOSITIONFORMAT,T3.USEWMSORDERS,T3.INVENTLOCATIONIDTRANSIT,T3.VENDACCOUNT,T3.BRANCHNUMBER,T3.INVENTSITEID,T3.INVENTCOUNTINGGROUP_BR,T3.CUSTACCOUNT_BR,T3.INVENTPROFILETYPE_RU,T3.INVENTPROFILEID_RU,T3.INVENTLOCATIONIDGOODSINROUTE_RU,T3.WMSLOCATIONIDGOODSINROUTE_RU,T3.ACTIVITYTYPE_RU,T3.NUMBERSEQUENCEGROUP_RU,T3.RETAILWEIGHTEX1,T3.FSHSTORE,T3.RBODEFAULTWMSPALLETID,T3.RBODEFAULTWMSLOCATIONID,T3.RBODEFAULTINVENTPROFILEID_RU,T3.ALLOWLABORSTANDARDS,T3.ALLOWMARKINGRESERVATIONREMOVAL,T3.CONSOLIDATESHIPATRTW,T3.CUSTACCOUNT_HU,T3.CYCLECOUNTALLOWPALLETMOVE,T3.DECREMENTLOADLINE,T3.DEFAULTKANBANFINISHEDGOODSLOCATION,T3.DEFAULTPRODUCTIONFINISHGOODSLOCATION,T3.DEFAULTSHIPMAINTENANCELOC,T3.DEFAULTSTATUSID,T3.PRINTBOLBEFORESHIPCONFIRM,T3.PRODRESERVEONLYWHSE,T3.REMOVEINVENTBLOCKINGONSTATUSCHANGE,T3.RESERVEATLOADPOST,T3.RETAILINVENTNEGFINANCIAL,T3.RETAILINVENTNEGPHYSICAL,T3.RETAILWMSLOCATIONIDDEFAULTRETURN,T3.RETAILWMSPALLETIDDEFAULTRETURN,T3.UNIQUECHECKDIGITS,T3.VENDACCOUNTCUSTOM_RU,T3.WAREHOUSEAUTORELEASERESERVATION,T3.WHSENABLED,T3.DEFAULTCONTAINERTYPECODE,T3.DEFAULTPRODUCTIONINPUTLOCATION,T3.DEFAULTRETURNCREDITONLYLOCATION,T3.WHSRAWMATERIALPOLICY,T3.MODIFIEDDATETIME,T3.DEL_MODIFIEDTIME,T3.MODIFIEDBY,T3.CREATEDDATETIME,T3.DEL_CREATEDTIME,T3.CREATEDBY,T3.RECVERSION,T3.PARTITION,T3.RECID FROM INVENTTRANSFERTABLE T1 CROSS JOIN INVENTLOCATION T2 CROSS JOIN INVENTLOCATION T3 WHERE ((T1.PARTITION=@P1) AND (T1.DATAAREAID=@P2)) AND (((T2.PARTITION=@P3) AND (T2.DATAAREAID=@P4)) AND (((T3.INVENTLOCATIONTYPE=@P5) OR (T2.INVENTLOCATIONTYPE=@P6)) AND ((T2.INVENTLOCATIONTYPE=@P7) AND (T1.INVENTLOCATIONIDFROM=T2.INVENTLOCATIONID)))) AND (((T3.PARTITION=@P8) AND (T3.DATAAREAID=@P9)) AND ((T3.INVENTLOCATIONTYPE=@P10) AND (T1.INVENTLOCATIONIDFROM=T3.INVENTLOCATIONID))) ORDER BY T1.TRANSFERID',@p5 output,@p6 output,@p7 output,5637144576,N'ceu',5637144576,N'ceu',3,3,0,5637144576,N'ceu',0
select @p1, @p2, @p5, @p6, @p7
как видите, на SQL все уходит с алиасами, которые аксапта генерит сама.
эти алиасы нельзя узнать в x++

насколько я помню, названий датасорсов всегда было достаточно, чтобы аксапта корректно разобралась. и где-то вроде даже было обсуждение на эту тему. Но в упор не помню в какой версии это появилось.

smailik, если у вас, после применения qbds.name() результат совпадает с ожидаемым, значит и в акс4 правило наименований датасорсов тоже работало.
Вложения
Тип файла: xpo Query.xpo (2.5 Кб, 211 просмотров)
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 19.06.2017 в 21:37.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Query для HcmPosition (запрос по таблице, соссылкой на себя же) Music DAX: Программирование 9 07.07.2016 14:54
emeadaxsupport: Microsoft Dynamics AX general performance analysis scripts page 5 Blog bot DAX Blogs 0 01.09.2014 14:11
Вложенный запрос SQL с помощью великого Query user_ax DAX: Программирование 9 07.10.2013 14:00
like запрос с использованием query Vadik Shiryakoff DAX: Программирование 7 13.03.2006 12:05

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:44.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.