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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.04.2013, 09:51   #1  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Complex expressions in query range
Всем добрый день.
Так сложилось, что у нас не пользуются полем InventBatch.ExpDate, а вместо этого по каждой номенклатуре проставлено время жизни. Соответственно, необходимо узнать, у каких записей в батче истекает срок в течение следующих expDays дней. Никак не получается сделать фильтр, в котором нужно к дате из одной таблицы добавить число дней из другой. Программа работает, если сравнивать дату с датой. Но если к дате прибавить числовое значение, она преобразуется в число и условие работает неправильно.
X++:
    qbr = qbds.addRange(fieldnum(InventBatch, DataAreaId));
    s = strfmt("(%1 + %2.%3 < %4)", // (%1 < %4) - так работает
        fieldstr(InventBatch, ProdDate),
        qbdsInventTable.name(),
        fieldstr(InventTable, ShelfLife),
        queryValue(systemdateget() + expDays) // expDays = 30 дней, к примеру
    );
    qbr.value(s);
__________________
// no comments

Последний раз редактировалось dech; 18.04.2013 в 10:00.
Старый 18.04.2013, 11:59   #3  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
К сожалению, тема до конца не раскрыта. Топикстартер ушел в мапитераторы, избавившись от самого вычитания. Мне же позарез нужно сложить дату и число в рендже.
__________________
// no comments
Старый 18.04.2013, 12:12   #4  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Основная идея: вместо того чтобы складывать дату с числом и результат сравнивать со второй датой, находите разницу мужду датами и сравнивайте её с числом.
X++:
"(%4 - %1 > %2.%3)"
Старый 18.04.2013, 12:45   #5  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Да такая же фигня и происходит. Хоть сложение, хоть вычитание, условие не выполняется.
__________________
// no comments
Старый 18.04.2013, 13:06   #6  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Давайте, я приведу полный текст джобика.
Есть несколько дат, одна из них 22\3\2012, время жизни номенклатуры K206 - 60 дней. Т.е. одна запись с этой датой как раз не должна попадать в запрос, но выводится.
В дальнейшем планирую theDate превратить в systemdateget() + expDays, пока удобнее так на тестовых данных.
X++:
static void complexExpression(Args _args)
{
    Query                   query = new Query();
    QueryBuildDataSource    qbds;
    QueryBuildDataSource    qbdsInventTable;
    QueryBuildRange         qbr;
    QueryRun                qr;
    InventBatch             inventBatch;
    InventTable             inventTable;
    str                     s;
    date                    theDate = 22\3\2012 + 60;
    ;

    qbdsInventTable = query.addDataSource(tablenum(InventTable), tablestr(InventTable));
    qbdsInventTable.addSelectionField(fieldnum(InventTable, ShelfLife));
    qbdsInventTable.addRange(fieldnum(InventTable, ItemId)).value('K206');
    qbdsInventTable.addRange(fieldnum(InventTable, DataAreaId));

    qbds = qbdsInventTable.addDataSource(tablenum(InventBatch), tablestr(InventBatch));
    qbds.addSelectionField(fieldnum(InventBatch, ProdDate));
    qbds.joinMode(JoinMode::InnerJoin);
    qbds.addLink(fieldnum(InventTable, ItemId), fieldnum(InventBatch, ItemId));

    qbr = qbds.addRange(fieldnum(InventBatch, DataAreaId));
    s = strfmt('((%4 - %1) != %2.%3)',
        fieldstr(InventBatch, ProdDate),
        qbdsInventTable.name(),
        fieldstr(InventTable, ShelfLife),
        date2str(theDate, 213, 2, 4, 2, 4, 4)
    );
    info(s);
    qbr.value(s);

    qr = new QueryRun(query);
    while (qr.next())
    {
        inventBatch = qr.get(tablenum(InventBatch));
        inventTable = qr.get(tablenum(InventTable));
        info(strfmt("@SYS26868",
            queryValue(theDate - inventBatch.prodDate),
            inventTable.ShelfLife));
    }
}
__________________
// no comments

Последний раз редактировалось dech; 18.04.2013 в 13:09.
Старый 18.04.2013, 13:48   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
date2str(theDate, 213, 2, 4, 2, 4, 4) равносильно date2StrXpp(theDate)?
Старый 18.04.2013, 14:05   #8  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
date2str(theDate, 213, 2, 4, 2, 4, 4) равносильно date2StrXpp(theDate)?
Почти да Дело в том, что на забугорных серверах формат даты именно Месяц, День, Год. Также используются прямые слеши вместо обратных.
__________________
// no comments

Последний раз редактировалось dech; 18.04.2013 в 14:07.
Старый 18.04.2013, 16:13   #9  
abv2703 is offline
abv2703
Участник
 
92 / 22 (1) +++
Регистрация: 05.12.2003
Адрес: Санкт-Петербург, улица Бухарестсткая
Кхе, и шо показывает info(qbdsInventTable.toString())? Можно увидеть?
Старый 19.04.2013, 07:54   #10  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от abv2703 Посмотреть сообщение
Кхе, и шо показывает info(qbdsInventTable.toString())? Можно увидеть?
5 баксов
X++:
SELECT ShelfLife FROM InventTable
WHERE ((ItemId = N'K206'))
JOIN prodDate FROM InventBatch
WHERE InventTable.ItemId = InventBatch.itemId
AND ((((05/21/2012 - ProdDate) != InventTable.ShelfLife)))
__________________
// no comments
Старый 19.04.2013, 08:25   #11  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
А на SQL сервер что уходит? Посмотрите через трассировку запросов

Может быть для надёжности добавить имя таблицы к полю ProdDate в условии WHERE?
За это сообщение автора поблагодарили: dech (2).
Старый 19.04.2013, 08:46   #12  
abv2703 is offline
abv2703
Участник
 
92 / 22 (1) +++
Регистрация: 05.12.2003
Адрес: Санкт-Петербург, улица Бухарестсткая
Аха, теперь совсем просто: заглянуть в таблицу inventBatch
Старый 19.04.2013, 12:13   #13  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Спасибо S.Kuskov
Разобрался в чем дело. Проблема была в дате theDate, которую я уже молотком забивал в query range. Надо было сразу использовать date2strxpp().
А в SQL Trace было ((05/21)/2012)
__________________
// no comments
Старый 20.06.2013, 12:36   #14  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Снова такая же проблема возникла. Теперь же не могу понять в чем дело... Получается, будто условие в принципе не срабатывает и всегда возвращает TRUE.
X++:
    Query                   q = new Query();
    QueryRun                qr;
    QueryBuildDataSource    qbds;
    QueryBuildRange         qbr;
    int                     expDays = 30;
    int                     division = Dimensions::code2ArrayIdx(SysDimension::Division);

    InventTable                 it;
    InventSerialProperties   isp;
    date                        expDate;
    ;

    qbds = q.addDataSource(tablenum(InventTable), tablestr(InventTable));
    qbds.addRange(fieldid2ext(fieldnum(InventTable, Dimension), division)).value('FSM');

    qbds = qbds.addDataSource(tablenum(InventSum));
    qbds.addLink(fieldnum(InventTable, ItemId), fieldnum(InventSum, ItemId));
    qbds.addRange(fieldnum(InventSum, PhysicalInvent)).value(">0");
    qbds.addRange(fieldnum(InventSum, ItemId)).value("C250");

    qbds = qbds.addDataSource(tablenum(InventDim));
    qbds.addLink(fieldnum(InventSum, InventDimId), fieldnum(InventDim, InventDimId));

    qbds = qbds.addDataSource(tablenum(InventSerial));
    qbds.addLink(fieldnum(InventDim, InventSerialId), fieldnum(InventSerial, InventSerialId));

    qbds = qbds.addDataSource(tablenum(InventSerialProperties), tablestr(InventSerialProperties));
    qbds.addLink(fieldnum(InventSerial, InventSerialId), fieldnum(InventSerialProperties, InventSerialId));
    qbr = qbds.addRange(fieldnum(InventSerialProperties, DataAreaId));
    // Задаем такое условие: InventSerialProperties.StretchDate + InventTable.ShelfLife <= now() + expDays
    qbr.value(strfmt("(%1.%2 + %3.%4 <= %5)", // здесь условие срабатывает в любом случае
        tablestr(InventSerialProperties), 
        fieldstr(InventSerialProperties, StretchDate),
        tablestr(InventTable), 
        fieldstr(InventTable, ShelfLife),
        date2strxpp(systemdateget() + expDays)
    ));

    // Pulling data

    qr = new QueryRun(q);
    while (qr.next())
    {
        it = qr.get(tablenum(InventTable));
        isp = qr.get(tablenum(InventSerialProperties));
        expDate = isp.StretchDate + it.ShelfLife;
        info(date2strxpp(expDate) + " <= " + date2strxpp(systemdateget() + expDays));
    }
То же самое на SQL. Здесь, конечно все работает:
X++:
DECLARE @ExpDays INT

SET @ExpDays = 1

SELECT 
    ISum.ItemId
  , ISum.PhysicalInvent
  , InvD.ConfigId
  , InvD.InventColorId
  , InvD.WMSLocationId
  , InvD.InventBatchId
  , InvD.InventLocationId
  , InvD.WMSPalletId
  , InvD.AFCInventContainerId
  , InvD.InventSerialId
  , ISP.StretchDate
  , DATEADD(DD, InvT.SHELFLIFE, ISP.StretchDate) AS ExpirationDate

FROM InventTable InvT
INNER JOIN InventSum ISum
   ON ISum.DataAreaId = InvT.DataAreaId
  AND ISum.ItemId = InvT.ItemId
INNER JOIN InventDim InvD
   ON InvD.DataAreaId = ISum.DataAreaId
  AND InvD.InventDimId = ISum.InventDimId
INNER JOIN InventSerial ISer
   ON ISer.DataAreaId = InvD.DataAreaId
  AND ISer.InventSerialId = InvD.InventSerialId
INNER JOIN InventSerialProperties ISP
   ON ISP.DataAreaId = ISer.DataAreaId
  AND ISP.InventSerialId = ISer.InventSerialId
  
WHERE InvT.DataAreaId = 'dat'
  AND InvT.Dimension3_ = 'FSM'
  AND ISum.ItemId = 'C250'
  AND ISum.PhysicalInvent > 0
  AND ISP.StretchDate + InvT.ShelfLife <= GETDATE() + @ExpDays
__________________
// no comments

Последний раз редактировалось dech; 20.06.2013 в 13:16.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
ax-erp: How to Set the Query Range on a SSRS Report Blog bot DAX Blogs 0 18.10.2012 19:11
sumitax: AX Queries – Passing query range as parameter Blog bot DAX Blogs 0 29.06.2011 13:11
Advanced query range value expressions: поле таблицы - имя вcтроенной функции year(). ATimTim DAX: Программирование 12 27.03.2009 18:16
axaptafreak: Label for Query Range cannot be modified (still) Blog bot DAX Blogs 2 25.07.2007 10:09
Advanced query range value expressions dn DAX: Программирование 2 07.10.2003 15:38
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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