Axapta 3.0 SP5, Dynamics Ax 4.0 SP2 (application version: 4.0.2501.347)
Доброго времени суток.
При выборе дат вблизи
'пограничных' значений лет (
1901, 2153-2154) обнаружились некоторые
'накладки' в реализации функционала формы
SysDateLookup.
Сценарий тестирования: вводим в поле с типом EDT
TransDate дату 31.12.2153, жмем кнопу вызовы lookup формы - кнопка перехода на следующий месяц недоступна (по сути календарь должен быть доступен до
31.12.2154), жмем
PageDown (ArrowRight, ArrowDown) и преодолеваем

это ограничение, наблюдаем корректные данные 2154 года, потом идут только названия месяцев 2155 года, далее пустые ячейки, и после этого по второму кругу календарь с начала времен (1901 года)
При просмотре кода некоторые фрагменты вызвали вопросы - в штатной lookup форме выбора дат
SysDateLookup объявлены 2
текстовые константы допустимого диапазона дат:
Forms\SysDateLookup\ClassDeclaration:
X++:
...
#define.maxDate('31-12-2153')
#define.minDate('01-01-1901')
...
и далее по тексту методов идет конвертация в даты через str2date() :
Forms\SysDateLookup\enableNextButton():
X++:
void enableNextButton()
{
if (year(monthShown) == year(str2date(#maxDate,123)) &&
mthofyr(monthShown) == mthofyr(str2date(#maxDate,123)))
...
}
Forms\SysDateLookup\enableNextButton():
X++:
void enablePrevButton()
{
if (year(monthShown) == year(str2date(#minDate,123)) &&
mthofyr(monthShown) == mthofyr(str2date(#minDate,123)))
...
}
Forms\SysDateLookup\drawMonth():
X++:
void drawMonth()
{
...
for (w = 1; w <= 6; w++)
{
...
if (drawingDate >= str2date(#maxDate, 123))
{
daysTable.setRowLabel(w,num2str(1,2,0,0,0));
}
...
}
...
}
первое что напрашивается - явное объявление макро-констант с типом
date и отказ от избыточных вызовов преобразований
str2date().
второй момент - верхняя граница диапазона дат
#maxDate задана не верно (31.12.2153): значение функции maxdate() = 31.12.
2154
Forms\SysDateLookup\ClassDeclaration:
X++:
...
#define.maxDate(31\12\2154)
#define.minDate(01\01\1901)
...
для предотвращения выхода за границы допустимого интервала дат при навигации по календарю можно добавить дополнительную проверку в метод nextMonth().
Forms\SysDateLookup\nextMonth():
X++:
void nextMonth(int keyPressed)
{
boolean doUnlock ;
// --> fix SysDateLookup code
boolean allowChange = ( keyPressed == #taskPageDown && buttonNextMonth.enabled() ) ||
( keyPressed == #taskPageUp && buttonPrevMonth.enabled() ) ;
;
if( !allowChange )
return ;
// <-- fix SysDateLookup code
doUnlock = element.lockWindowUpdate(true);
...
}
P.S. Сценарий тестировался на Axapta 3.0 SP5, Dynamics AX 4.0 SP2, но похоже что актуален и для Dynamics AX 2009 (объявление
#define.maxDate('31-12-2153') присутствует).