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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.05.2011, 11:29   #1  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
как правильно построить фильтр
Есть таблица, в которой для каждого сотрудника есть несколько строк с разницей в датах.
Весь период разбит на части по датам типа нашал работать - ушёл в отпуск(последн день перед отпуском)
нач отпуска - конец отпуска

ФИО1 - прочие данные - начал работать - ушёл в отпуск(последн день перед отпуском)
ФИО1 - прочие данные - перв день отпуска - последн день отпуска
ФИО1 - прочие данные - перв день после отпуска - последн день перед отпуском
....и т.д.

надо показать только корректные данные на выбранный день. Т.е. для каждого сотрудника будет только одна запись

classDeclaration:
QueryBuildRange rangeTermination;

init:
rangeTermination = this.query().dataSourceTable(tableNum(MyTable)).addRange(fieldNum(mlm_EmployeesTable, begin_date));

executeQuery:
if(firstOpen == True)
{//в перв раз данные на сегодня
rangeTermination.value("<=" + date2strxpp(SystemDateGet()) + "&& mlm_EmployeesTable.finish_date>= " + date2strxpp(SystemDateGet()));
}
else
{//TerminationDate.valueStr() дата выбранная на форме
rangeTermination.value("<=" + TerminationDate.valueStr() + "&& (mlm_EmployeesTable.finish_date>= " + TerminationDate.valueStr());
}

игнорирует фильтр и показывает все строчки для каждого сотрудника
что и где я не права? Спасибо
Старый 05.05.2011, 11:46   #2  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,506 / 428 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
__________________
С уважением,
Вячеслав
Старый 15.05.2011, 12:46   #3  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Цитата:
Сообщение от pitersky Посмотреть сообщение
напишите this.query().dataSourceTable(tableNum(MyTable)).toString() после наложения фильтра. Так вы увидите, какой запрос на самом деле уходит на сервер
pitersky а где это? в каком методе?
Старый 15.05.2011, 12:57   #4  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
а где это? в каком методе?
Можно сразу же там где вы настраиваете фильтр.
Метод toString() класса QueryBuildDataSource просто возвращает строку, содержащую текст SQL запроса. Далее вы можете его присвоить какой-нибудь переменной, чтобы посмотреть её значение в дебагере, или просто вывести в инфолог.
X++:
info(this.query().dataSourceTable(tableNum(MyTable)).toString());
За это сообщение автора поблагодарили: timaluhs (1).
Старый 15.05.2011, 13:28   #5  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
добавила info
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Старый 15.05.2011, 13:43   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
Только там ещё порядка десятка полей-фильтров и моё поле там не фигурирует вообще
Вы исправили ошибки, на которые вам указали участники обсуждения? Приведите ваш вариант кода, уже после исправлений.
Старый 05.05.2011, 11:54   #7  
samolalex is offline
samolalex
Участник
Аватар для samolalex
Самостоятельные клиенты AX
 
259 / 107 (4) +++++
Регистрация: 18.06.2010
Адрес: Москва
Значения фильтров с интервалом дат должны иметь формат (пример):
Цитата:
"01.01.2011..01.02.2011"
Таким образом, вам необходимо привести ваш фильтр к виду:
X++:
rangeTermination.value(strfmt("%1..%2", StartDate, EndDate));
Также в Axapta 3 есть метод класса SysQuery под названием Range(), который служит для ввода интервалов значений в фильтр:
X++:
rangeTermination.value(SysQuery::range(StartDate, EndDate));
__________________
С уважением, Александр.
Старый 05.05.2011, 11:58   #8  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,506 / 428 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
А причём тут интервал дат? Надо отобрать строки, в которых первая дата меньше заданной, а вторая больше. Тут надо 2 Range накладывать на разные поля вообще-то.
Или я чего-то не понял...
__________________
С уважением,
Вячеслав
За это сообщение автора поблагодарили: Ivanhoe (1).
Старый 05.05.2011, 12:00   #9  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2156 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Обратите внимание, что у автора range ставится на поле begin_date, а в самом фильтре еще и finish_date участвует. Почему было не сделать два range - по одному на каждое поле??
__________________
Ivanhoe as is..
Старый 05.05.2011, 12:00   #10  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Если не заморачиваться с возможным пустым значением полей, то, в данном случае, надо просто создать два отдельных Range на поле, содержащее начало диапазона и на поле, содержащее конец диапазона.

Два Range, созданные по разным полям автоматически объединяются по "И", что, в данном случае и требуется

X++:
// init:
QueryBuildDataSource qbds;

qbds = this.query().dataSourceTable(tableNum(MyTable));
rangeBegin = qbds.addRange(fieldNum(mlm_EmployeesTable, begin_date));
rangeEnd = qbds.addRange(fieldNum(mlm_EmployeesTable, finish_date));
X++:
// executeQuery:

if(firstOpen == True)
{
    rangeBegin.value(global::QueryRange(dateNull(), systemDateGet()))
    rangeEnd.value(global::QueryRange(systemDateGet(), dateNull()))
}
else
{
    rangeBegin.value(global::QueryRange(dateNull(), TerminationDate.value()))
    rangeEnd.value(global::QueryRange(TerminationDate.value(), dateNull()))
}

Если же значения полей могут быть пустыми (есть дата начала, но нет даты конца или наоброт), то все значительно сложнее.
За это сообщение автора поблагодарили: timaluhs (1).
Старый 05.05.2011, 12:10   #11  
pitersky is offline
pitersky
северный Будда
Аватар для pitersky
Ex AND Project
Соотечественники
 
1,506 / 428 (18) +++++++
Регистрация: 26.09.2007
Адрес: Солнечная система
Согласен с Владимиром.
Единственное - не вижу необходимости в переменной firstOpen. По-моему, вполне достаточно внутри executeQuery получать TerminationDate.value(), а затем сравнивать его с dateNull(). Это тем более справедливо, если надо будет открывать форму с установленной заранее датой
__________________
С уважением,
Вячеслав

Последний раз редактировалось pitersky; 05.05.2011 в 12:12.
Старый 19.05.2011, 20:57   #12  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Честно говоря, в первый раз слышу про фиктивные условия. Вроде как, если строка условия начинается с открывающейся круглой скобки, то аксапта всегда переключается в режим расширенного синтаксиса и интерпретирует условие "как есть", а не как пользовательский фильтр отдельно взятого поля.

http://www.axaptapedia.com/Expressions_in_query_ranges
Цитата:
To specify the range value itself, certain rules must be followed:
  • The entire expression must be enclosed within single-quotes, not double-quotes
  • The entire expression must be enclosed in parenthesis (brackets)
  • Each sub-expression must be enclosed in its own set of parenthesis
  • For fields in the current table, simply the field name can be used
  • For fields in other tables, a prefix of the relevant datasource name must be added. This is not always the same as the table name.
  • String values should be surrounded by double-quotes, and wrapped in a call to queryValue()
  • Enum values should be specified by their integer value
  • Date values should be formatted using Date2StrXpp()
  • Blank string like ‘ ’ will not work as expected, use sysquery::valueEmptyString().
Старый 22.05.2011, 12:28   #13  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Navision
закон Мэрфи опять сработал
почему-то если rangeStart - фильтр по одному полю
rangeStart = qbds.addRange(fieldnum(MyTBL, STARTDATE));
rangeStart.value(strfmt('%1..%2',FromDate.valueStr(),ToDate.valueStr()));
то работает и даты как положено воспринимает

SELECT * FROM MyTBL WHERE ... AND ((StartDate>={ts '2011-01-01 00:00:00.000'} AND StartDate<={ts '2011-05-22 00:00:00.000'})) AND .....

а если
str rangeDate = strfmt("(((STARTDATE>=%1) and (STARTDATE<=%2)) or ((ENDDATE>=%1) and (ENDDATE<=%2)))", FromDate.valueStr(), ToDate.valueStr());
rangeDates = qbds.addRange(fieldNum(MyTBL ,RecId));
rangeDates.value(rangeDate); - фильтр по RecID

то даты имеют вид другой
SELECT * FROM MyTBL WHERE ... AND (((((STARTDATE>=01/01/2011) and (STARTDATE<=22/05/2011)) or ((ENDDATE>=01/01/2011) and (ENDDATE<=22/05/2011)))))
ещё ругается что какой-то скобки не хватает.

[Date values should be formatted using Date2StrXpp() ]

пыталась вместо FromDate.valueStr() - date2strxpp(FromDate) ругается
Argument '_date' ia incompatible with required type.
Старый 22.05.2011, 12:46   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
[Date values should be formatted using Date2StrXpp() ]

пыталась вместо FromDate.valueStr() - date2strxpp(FromDate) ругается
Argument '_date' ia incompatible with required type.
Аргумент функции date2strxpp должен иметь тип дата. Попробуйте чтото вроде
X++:
date2strxpp(FromDate.DateValue())
Старый 22.05.2011, 13:04   #15  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
поставила
date2strxpp(FromDate.DateValue())
теперь SQL вообще какой-то кривой

(((((STARTDATE>=01\01\2011) and (STARTDATE<=22\05\2011)) or ((ENDDATE>=01\01\2011) and (ENDDATE<=22\05\2011)))))
Старый 22.05.2011, 19:49   #16  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
теперь SQL вообще какой-то кривой
Что именно вам не нравится? Если вы про пару лишних внешних скобок, то это нормаьлно

Ещё. Вместо AND и OR используйте && и || соответственно.
Старый 23.05.2011, 12:23   #17  
nix0root is offline
nix0root
Участник
 
67 / 16 (1) ++
Регистрация: 17.03.2009
Адрес: МО
К примеру.

X++:
            qbrEmployDate.value(   '(EmplTable.PayEmploymentDate_RU != '+date2StrXpp(datenull())+')'
                                  +'&&'
                                  +'(EmplTable.PayEmploymentDate_RU <= '+date2StrXpp(systemdateget())+')'
                               );
            qbrResignDate.value(   '(EmplTable.PayResignedDate_RU !='+date2StrXpp(datenull())+')'
                                  +'&&'
                                  +'(EmplTable.PayResignedDate_RU < '+date2StrXpp(systemdateget())+')');
__________________
В подводной охоте главное вдох ...
Старый 23.05.2011, 16:28   #18  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Ага. Можно и через display-метод. Только сдаётся мне, что display-метод может вызываться чаще чем ExecuteQuery.
Старый 24.05.2011, 09:08   #19  
timaluhs is offline
timaluhs
newborn in DAX
Аватар для timaluhs
 
102 / 10 (1) +
Регистрация: 16.12.2010
Адрес: Израиль
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Ага. Можно и через display-метод. Только сдаётся мне, что display-метод может вызываться чаще чем ExecuteQuery.
А почему чаще? и чем это может быть плохо или хорошо? где подводные камни расставлены?
Старый 24.05.2011, 09:17   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от timaluhs Посмотреть сообщение
А почему чаще?
Потому что executeQuery вызывается только в случае изменения параметров запроса. Именно в этот момент число выбранных записей может измениться. Например когда вы накладываете новый фильтр или убираете старый.
display-метод вызывается всякий раз, когда есть необходимость перерисовки содержимого окна. Например вы свернули и развернули окно.
Цитата:
Сообщение от timaluhs Посмотреть сообщение
и чем это может быть плохо или хорошо?
Это просто буде чуть больше нагружать систему. Т.е. это уже вопрос оптимизации.
Теги
query, querybuildrange, range, фильтр

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как правильно хранить статичный набор начальных данных в классах? mazzy DAX: Программирование 58 14.04.2011 12:10
Статистика по каждому коду номенклатуры. Как правильно построить Query? dynamax DAX: Программирование 17 14.10.2009 11:27
ERP-BLOG: Axapta, фильтр по сетке Blog bot DAX Blogs 26 05.02.2009 15:56
Исполнить сформированный фильтр radya DAX: Программирование 14 26.07.2007 20:47
Как правильно построить Query Bukovka DAX: Программирование 0 25.03.2004 11:55

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

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

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