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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 17.06.2008, 14:51   #1  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
? Как подставить вычисляемое значение в Range у query
Задача сделать выпадающий список с таблицы рабочих смен.
Если смена открыта 17.06.2008 с 8:00 до 20:00 в сейчас время к примеру 14 часов.. то запрос выполнится.

А как быть если смена открыта 17.06.2008 23 часа до 18.06.2008 до 6 утра.
а сейчас время 2:00 утра, то запрос не выполнится.
Условие надо поправить так чтоб время открытой смены проверялось между двумя датами queryBuildDataSource.addRange(fieldnum(MilkShifts,StartTime)).value("<"+t);
queryBuildDataSource.addRange(fieldnum(MilkShifts,EndTime)).value(">" + t);

Как это сделать? Что т оне соображу.


X++:
static void lookupIDShift(FormStringControl _ctrl)
{   Query                          query=new Query();
    QueryBuildDataSource    queryBuildDataSource;
    QueryBuildRange         queryBuildRange;
    QueryRun                    qr;

    //Таблицы
    SysCompanyUserInfo      scUI;
    MilkGroupMaterialResponsibilityLine     mGMRLine;

    SysTableLookup          sysTableLookup = SysTableLookup::newParameters(tableNum(MilkShifts), _ctrl);


    Str                     t= time2str(timenow(),1,1), d=strfmt("%1", systemdateget()), IDgmt, saveText;
    Str   300               war, warNull;
    ;
 war="Вы не определены ни в одну группу материальной ответственности поэтому не можете создавать складские и производстенные журналы."+
     " Обратитесь к администратору системы или используйте форму [Управление запасами/ Настройка/ Смены/ Группы материальной ответственности]";

 warNull="Ни одна смена для групп материальной ответственности, в которой Вы входите, не является открытой на текущий момент."+
         " Отредактируйте Группы материальной ответственности или используйте периодическую операцию Закрытие смены";

    saveText = _ctrl.text();
    _ctrl.text(""); // Disable filter effects

    sysTableLookup.addLookupfield(fieldNum(MilkShifts,IDShift));
    sysTableLookup.addLookupfield(fieldNum(MilkShifts,StartTime));
    sysTableLookup.addLookupfield(fieldNum(MilkShifts,EndTime));
    sysTableLookup.addLookupfield(fieldNum(MilkShifts,StartDate));
    sysTableLookup.addLookupfield(fieldNum(MilkShifts,EndDate));
    sysTableLookup.addLookupfield(fieldNum(MilkShifts,Milk_IDGroupMaterialResponsibility));

    queryBuildDataSource=query.addDataSource(tablenum(MilkShifts));



    //Ищем сотрудника по пользовательским связям через текущего пользователя
    SELECT firstonly EmplId FROM scUI where scUI.UserId==curUserId();

    //Ищем ID группы материальной ответственности

    while select IDGroupMaterialResponsibility from mGMRLine
          where mGMRLine.EmplId==scUI.EmplId
    {
       IDgmt+=mGMRLine.IDGroupMaterialResponsibility+",";
    }
    IDgmt=substr(IDgmt,1,strlen(IDgmt)-1);

    if (IDgmt=="")  Box::warning( war, "Вы не состоите ни в одной группе материальной ответственности" );
    else {
     // Запрос возвращает номер текущих смен. Надо сравнить с тем есть ли у этой смены ИД группы мат отв.
 
   queryBuildDataSource.addRange(fieldnum(MilkShifts,StartTime)).value("<"+t);

   queryBuildDataSource.addRange(fieldnum(MilkShifts,EndTime)).value(">" +   t); 

   queryBuildDataSource.addRange(fieldnum(MilkShifts,StartDate)).value(".." + d ); 
   queryBuildDataSource.addRange(fieldnum(MilkShifts,EndDate)).value(d + ".."); 

   queryBuildDataSource.addRange(fieldnum(MilkShifts,StatusShift)).value(enum2str(StatusShift::Open)); 
   queryBuildDataSource.addRange(fieldnum(MilkShifts,Milk_IDGroupMaterialResponsibility)).value(IDgmt);// Список групп в которых учавствует пользователь

    qr= new QueryRun(query);
    If(qr.next()) {
      //    sysTableLookup.parmTmpBuffer(MilkShifts);
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
                   }
    else  Box::warning( warNull, "Необходимо открыть смену" );
         }
    _ctrl.text(saveText);
}
запрос в дебагере выглядит так
SELECT * FROM MilkShifts WHERE ((StartTime<53103)) AND ((EndTime>53103)) AND ((StartDate<={ts '2008-06-17 00:00:00.000'})) AND ((EndDate>={ts '2008-06-17 00:00:00.000'})) AND ((StatusShift = 0)) AND ((Milk_IdGroupmaterialResponsibility = N'Гр2'))
Старый 17.06.2008, 14:59   #2  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Вычисляемые поля аксапта не поддерживает

EDIT: пардон., не понял вопроса сразу...
Чтобы поставить условие на интервал нужно использовать метод
SysQuery::range(anytype _from, anytype _to)

, т.е.
X++:
...addRange(fieldnum(MilkShifts,StartDate)).value(SysQuery::range(date1, date2));
EDIT2: точно так же и для time

Последний раз редактировалось DSPIC; 17.06.2008 в 15:07.
Старый 17.06.2008, 15:18   #3  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Перейти на 5.0 - там UTCdatetime используется.

А если по теме - то видимо надо писать сложный фильтр такого плана:
(тек.время > время начала смены И тек.дата = дата начала смены) ИЛИ
(тек.время < время конца смены И тек.дата = дата конца смены) ИЛИ
(тек.дата > дата начала смены И тек.дата < дата конца смены) (это если смена больше суток)
Старый 17.06.2008, 15:30   #4  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
DSPIC
про использования интервала для даты это можно, но что делать со временем не понятно.
Поля StrartTime и EndTime определены как TimeHour24 или можно сними работать как с целыми числами (каждая единица секунда) 7200 =2ч
если StartTime =23:00: а EndTime = 6:00:00
а t = 2:00:00
то условие StartTime<t AND t< EndTime теряет всякий смысл.
23 > 2

Надо как кто привязать дату ко времени.
Если сделать так
X++:
   queryBuildDataSource.addRange(fieldnum(MilkShifts,StartTime)).value("<" + t +"-( StartDate -"+ d+" )*86400" ); 
//86400 - это сутки в секундах
т.е. в запросе бы получалось так
(mShifts.StartTime<(t+(d-mShifts.StartDate)*86400) && (t-(mShifts.EndDate-d)*86400)<mShifts.EndTime

t - текущее время
d - текущая дата

Если текущая дата = StartDate и EndDate то выражение (mShifts.EndDate-d)*86400) == 0
А если время начальное и конечное в разных датах то данное выражение имеет мысл.

Но как его завернуть в query ?
Старый 17.06.2008, 15:32   #5  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
kashperuk
Если бы можно было бы использовать ИЛИ в query.
Там только AND.
Старый 17.06.2008, 16:48   #7  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
Добавил условие
X++:
  sQuery=strfmt("(StartTime < (%1 + (StartDate - %2 )*86400)) AND ((%3 - (EndDate - %4 )*86400)< EndTime)",timenow(),date2num(systemdateget()),timenow(),date2num(systemdateget()));
  queryBuildDataSource.addRange(fieldnum(MilkShifts,recId)).value(squery);

SELECT * FROM MilkShifts WHERE (((StartTime < (60419 + (StartDate - 39614 )*86400)) AND ((60419 - (EndDate - 39614 )*86400)< EndTime))) AND ((StartDate<={ts '2008-06-17 00:00:00.000'})) AND ((EndDate>={ts '2008-06-17 00:00:00.000'})) AND ((StatusShift = 0)) AND ((Milk_IdGroupmaterialResponsibility = N'Гр2' OR Milk_IdGroupmaterialResponsibility = N'Гр3'))


Выдает: Ошибка:
Невозможно выбрать запись в Смены (MilkShifts).
База данных SQL обнаружила ошибку.

Где ошибка? не подскажете?

Последний раз редактировалось Poleax; 17.06.2008 в 16:55.
Старый 17.06.2008, 16:56   #8  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Почитайте вот это
http://www.axaptapedia.com/Expressions_in_query_ranges

Возможно, попробуйте поставить еще одни скопки вокруг всего выражения.
Но я, честно говоря, не помню, чтобы даже через расширенный фильтр оно позволяло вычисления вставлять в запрос.
Пишите лучше так, как я показал выше.
За это сообщение автора поблагодарили: jeky (2).
Старый 17.06.2008, 17:13   #9  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Перейти на 5.0 - там UTCdatetime используется.

А если по теме - то видимо надо писать сложный фильтр такого плана:
(тек.время > время начала смены И тек.дата = дата начала смены) ИЛИ
(тек.время < время конца смены И тек.дата = дата конца смены) ИЛИ
(тек.дата > дата начала смены И тек.дата < дата конца смены) (это если смена больше суток)
Как видишь запрос собрался, я его из отладки и поймал.
SELECT * FROM MilkShifts WHERE (((StartTime < (60419 + (StartDate - 39614 )*86400)) AND ((60419 - (EndDate - 39614 )*86400)< EndTime))) AND ((StartDate<={ts '2008-06-17 00:00:00.000'})) AND ((EndDate>={ts '2008-06-17 00:00:00.000'})) AND ((StatusShift = 0)) AND ((Milk_IdGroupmaterialResponsibility = N'Гр2' OR Milk_IdGroupmaterialResponsibility = N'Гр3'))

осталось разобраться с приведением типов.

На счет запроса
(тек.время > время начала смены И тек.дата = дата начала смены) ИЛИ
(тек.время < время конца смены И тек.дата = дата конца смены) ИЛИ
(тек.дата > дата начала смены И тек.дата < дата конца смены) (это если смена больше суток)
Тек. время преобразовать в целое число?
тек. дату тоже в целое? или оставить так как strfmt делает ? ('18:10:10' и 17.06.2008)
Старый 17.06.2008, 17:24   #10  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
Изменил условие запроса как советовал kashperuk
sQuery=strfmt("((%1>StartTime AND %2=StartDate) OR ( %1<EndTime AND %2=EndTime) OR (%2>StartDate AND %2<EndDate))",timenow(),date2num(systemdateget()));

queryBuildDataSource.addRange(fieldnum(MilkShifts,recId)).value(squery);


SELECT * FROM MilkShifts WHERE ((((62459>StartTime AND 39614=StartDate) OR ( 62459<EndTime AND 39614=EndTime) OR (39614>StartDate AND 39614<EndDate)))) AND ((StatusShift = 0)) AND ((Milk_IdGroupmaterialResponsibility = N'Гр2' OR Milk_IdGroupmaterialResponsibility = N'Гр3'))

Появляется ошибка:
Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 23.
Старый 17.06.2008, 17:33   #11  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
совет
1. каждое условие в свою пару скобок (((усл1) AND (усл2)) OR ((усл3) AND (усл4)))
2. вместо date2num использовать date2xppstr

Интересно, есть ли люди которые могут написать подобное условие с первого раза без ошибок...
Старый 17.06.2008, 17:34   #12  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Не почитал видимо внимательно ту статью, что я ссылку дал.
В запросе этом надо использовать X++ синтаксис, то есть

(((%1 > StartTime) && (%2 == StartDate) || ()....

Время преобразуй в число
А дату функцией date2StrXpp
За это сообщение автора поблагодарили: Poleax (1).
Старый 17.06.2008, 17:45   #13  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
sQuery=strfmt("(((%1>StartTime) && (%2==StartDate)) || ((%1<EndTime) && (%2==EndTime)) || ((%2>StartDate) && (%2<EndDate)))",timenow(),d);


SELECT * FROM MilkShifts WHERE (((((63797>StartTime) && (17.06.2008==StartDate)) || ((63797<EndTime) && (17.06.2008==EndTime)) || ((17.06.2008>StartDate) && (17.06.2008<EndDate))))) AND ((StatusShift = 0)) AND ((Milk_IdGroupmaterialResponsibility = N'Гр2' OR Milk_IdGroupmaterialResponsibility = N'Гр3'))

Ошибка таже самая
Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 32.
Старый 17.06.2008, 17:48   #14  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Дату неправильно преобразовал. Смотри советы выше про использование date2StrXpp
Старый 17.06.2008, 17:48   #15  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
kashperuk
как я понима от всех дополнительных
queryBuildDataSource.addRange(fieldnum(MilkShifts,StatusShift)).value(enum2str(StatusShift::Open));
надо избавляться и весь Where собирать в strfmt ?
чтоб небыло различий между AND и && в одной строке
Старый 17.06.2008, 17:58   #16  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Нет, не нужно избавляться от оставшихся. Ахапта сама раздуплит и те, и те
Они умная (иногда)
Старый 17.06.2008, 18:52   #17  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
kashperuk
Спасибо огромное, заработало.
и за date2StrXpp спасибо.
Теги
документация, ax2009

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
axaptafreak: Label for query range cannot be modified in AX 5.0 Blog bot DAX Blogs 0 30.08.2007 16:50
axaptafreak: Label for Query Range cannot be modified (still) Blog bot DAX Blogs 2 25.07.2007 10:09
Fred Shen: Date data type in Query Range Value Expression Blog bot DAX Blogs 0 28.10.2006 16:40
Автоматическая подстановка Range в Query Владимир Максимов DAX: Программирование 9 30.03.2004 16:48
Как вытащить информацию о Range из Query raz DAX: База знаний и проекты 1 26.03.2004 11:10

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

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

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