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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.09.2013, 18:37   #1  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Проверить переменную на null
Здравствуйте!

Есть класс, в котором есть метод, который может принимать на вход переменную anytype, а может и не принимать (значение по умолчанию null).
X++:
void myMethod(anytype _var = null)
{
    ....
}
Как бы мне проверить, что переменную в метод не передавали, т.е. она равна null?

вариант:
X++:
if (_var == null)
выдаст: "Ошибка времени выполнения: Неправильные типы аргументов операции сравнения."

Из того, что смог сделать, спасло только:
X++:
if (strfmt("%1", typeof(_var)) == "")
Ничего другого в голову не приходит (видимо вечер сказывается...), а это как-то некрасиво, на мой взгляд. Может можно как-то лучше написать?


PS: Извиняйте, если уже обсуждалось. Я искал, но не нашел.
Старый 24.09.2013, 18:56   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
prmIsDefault

или попробовать if (_var) (если пустая строка тоже катит, например)
За это сообщение автора поблагодарили: mazzy (2), PMS (1).
Старый 24.09.2013, 19:31   #3  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
prmIsDefault не помог в данной ситуации, всегда возвращает 0 (вне зависимости от того, передали что-нибудь или нет).

А вот с
X++:
if (_var)
получилось!

Спасибо большое!
Почему-то изначально отверг этот вариант (пробовал, но не заработал, видимо в силу каких-то других причин). Вечер, все-таки...
За это сообщение автора поблагодарили: mazzy (2).
Старый 24.09.2013, 20:02   #4  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Как мне кажется, единственное решение именно через typeOf(). Возможно, в комбинации с prmIsDefault(). Причем, значение typeOf(null) = 44, несмотря на то, что Types имеет значения от 0 до 17.

X++:
static client void Job_test(Args _args)
{
    void test(anytype _var = null)
    {
        if (prmIsDefault(_var))
            info('default parameters');
        else
            info('not default parameters');
            
        if (_var)
            info('exist value');
        else
            info('not exists value');

        if (typeOf(_var))
            info(strFmt('exist type \"%1\" typesNum = %2', typeOf(_var), int2str(typeOf(_var))));
        else
            info('not exists type');

    }
    ;

    warning('without parameters');
    test();
    info('');
    
    warning('set null');
    test(null);
    info('');
    
    warning('set empty string');
    test('');
    info('');
    
    warning('set value');
    test(1);
    info('');

    return;
}
PS: Хотя, скорее всего, анализ значения NULL и не нужен. Обычно подобные задачи возникают когда нет достаточно ясного понимания того, что же именно надо сделать. Как правило, в процессе реализации выясняется, что все это не очень-то и нужно...
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: PMS (1).
Старый 24.09.2013, 23:48   #5  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Причем, значение typeOf(null) = 44, несмотря на то, что Types имеет значения от 0 до 17.
"Штатный" диапазон перечисления Types не мешает полям типа RecId/RefRecId/createdTransactionId/modifiedTransactionId иметь в SqlDictionary базовый тип со значением 49, а вовсе не Types::Int64 см. Программное воссоздание записей SqlDictionary для определенной таблицы
За это сообщение автора поблагодарили: belugin (5), PMS (1).
Старый 25.09.2013, 09:56   #6  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Владимир, спасибо большое за подробнейший ответ!
Это мне напомнило, почему вчера не заработал вариант:
X++:
if (_var)
Он не работает с пустой строкой. (голова под вечер уже плохо соображала )

Видимо, все-таки, правильная проверка:
X++:
if (typeOf(_var) == 44)

Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
PS: Хотя, скорее всего, анализ значения NULL и не нужен. Обычно подобные задачи возникают когда нет достаточно ясного понимания того, что же именно надо сделать. Как правило, в процессе реализации выясняется, что все это не очень-то и нужно...
Ну, тут нужно, так как дело в том, что нужно написать метод, в который может передаваться несколько параметров, а может и не передаваться (заранее это не известно):
X++:
void myMethod(anytype _var1 = null, anytype _var2 = null, anytype _var3 = null, anytype _var4 = null  ..)
{
В самом методе надо знать сколько же именно параметров было передано (это для вызова заранее неизвестного метода COM-объекта). Т.е. если я вызову метод COM объекта с 4-мя параметрами, а на вход его нужно передать максимум 1, то, сами понимаете, вылетит exception.
Старый 25.09.2013, 10:32   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,427 / 1771 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от PMS Посмотреть сообщение
prmIsDefault не помог в данной ситуации, всегда возвращает 0 (вне зависимости от того, передали что-нибудь или нет).
Странно. У меня на AX2009 prmIsDefault сработал
X++:
static void job_test_prmIsDefault_anytype(Args _args)
{
    void myMethod(anytype _var = null)
    {
        ;

        info(int2str(prmIsDefault(_var)));
    }
    ;
    
    myMethod();
    myMethod(NULL);
    myMethod(1);
}

Последний раз редактировалось S.Kuskov; 25.09.2013 в 10:45.
Старый 25.09.2013, 10:51   #8  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Странно. У меня на AX2009 prmIsDefault сработал
Да, это у меня на AX4.0 тоже работает. Но попробуйте передать через цепочку вызовов и это перестает работать:
X++:
static void job_test_prmIsDefault_anytype(Args _args)
{
    void myMethod2(anytype _var = null)
    {
        ;

        info(int2str(prmIsDefault(_var)));
    }
    
    void myMethod(anytype _var = null)
    {
        ;

        myMethod2(_var);
    }
    ;
    
    myMethod();
    myMethod(NULL);
    myMethod(1);
}
PS: извините, что заранее не написал, что в добавок во всему еще существует цепочка вызовов.
Старый 25.09.2013, 10:55   #9  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Потому, что в первый метод вы всегда передаете значение

X++:
static void job_test_prmIsDefault_anytype(Args _args)
{
    void myMethod2(anytype _var = null)
    {
        ;

        info(int2str(prmIsDefault(_var)));
    }
    
    void myMethod(anytype _var = null)
    {
        ;
        if (prmisDefault(_var))
        {
            myMethod2();
        }
        else
        {
            myMethod2(_var);
        }
    }
    ;
    
    myMethod();
    myMethod(NULL);
    myMethod(1);
}
Старый 25.09.2013, 10:57   #10  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от PMS Посмотреть сообщение
Видимо, все-таки, правильная проверка:
X++:
if (typeOf(_var) == 44)
Можно не хардкодить константу
X++:
if (typeOf(_var) == typeOf(null))
Старый 25.09.2013, 11:02   #11  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,427 / 1771 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Ещё стоит отметить, что prmisDefault это единственный способ отличить пропуск параметра от передачи параметра совпадающего со значением по умолчанию.
Старый 25.09.2013, 11:05   #12  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от belugin Посмотреть сообщение
Можно не хардкодить константу
X++:
if (typeOf(_var) == typeOf(null))
Полностью с Вами согласен!
Спасибо!
Старый 25.09.2013, 11:07   #13  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Ещё стоит отметить, что prmisDefault это единственный способ отличить пропуск параметра от передачи параметра совпадающего со значением по умолчанию.
Да, для одного вызова именно так. Но, к сожалению, при цепочке вызовов эта информация теряется, и остается расчитывать на null.
Старый 25.09.2013, 11:09   #14  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2922 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от PMS Посмотреть сообщение
Да, для одного вызова именно так. Но, к сожалению, при цепочке вызовов эта информация теряется, и остается расчитывать на null.
Ее можно передавать (см мой фикс вашего джоба), но это геморройно
Старый 25.09.2013, 11:55   #15  
PMS is offline
PMS
Участник
 
54 / 29 (1) +++
Регистрация: 25.02.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от belugin Посмотреть сообщение
Ее можно передавать (см мой фикс вашего джоба), но это геморройно
Да, это уже слишком ))
Старый 25.09.2013, 12:18   #16  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Если отойти от джобов и использовать классы, то видно, что один и тот же параметр передаётся через несколько методов. Обычно из этого следует, что нужно изменить его на поле класса и инициализировать его через конструктор или set-метод. Задача сведётся к проверке anytype-переменной на значение null. Если это не ваш случай, тогда слушайте, что говорит вам belugin.
__________________
// no comments
Старый 26.09.2013, 14:18   #17  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,651 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от PMS Посмотреть сообщение
Ну, тут нужно, так как дело в том, что нужно написать метод, в который может передаваться несколько параметров, а может и не передаваться (заранее это не известно):
X++:
void myMethod(anytype _var1 = null, anytype _var2 = null, anytype _var3 = null, anytype _var4 = null  ..)
{
В самом методе надо знать сколько же именно параметров было передано (это для вызова заранее неизвестного метода COM-объекта). Т.е. если я вызову метод COM объекта с 4-мя параметрами, а на вход его нужно передать максимум 1, то, сами понимаете, вылетит exception.

Задача передачи не определенного количества параметров решается через передачу одного параметра-контейнера (Container). Сколько элементов в контейнере, столько и параметров. Разные элементы одного и того же контейнера могут иметь разные типы

Можно вместо контейнера использовать объект STRUCT, если требуется знать имя параметра. Объект Struct также позволяет записывать разные типы данных в разные элементы структуры. По сути, Struct - это программная симуляция одной записи временной таблицы. Ну, или использовать 2 контейнера: Один с именами, другой со значениями.

Хотя и это все не есть "правильные" решения. Если Вы пытаетесь сделать "обвязку" методов COM-объекта, то и надо делать отдельный метод класса Axapta под каждый конкретный метод конкретного Com-объекта. Посмотрите, для примера, классы CCADO... или семейство классов SysExcel...
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
sashanazarov: Value cannot be null. Parameter name: x Blog bot DAX Blogs 0 30.11.2012 16:11
Real Data Type - No of decimals Yprit DAX: Программирование 10 30.03.2009 12:17
C# and AX Development: Using the COM Business Connector in C#, the easy way (AX/Axapta) Blog bot DAX Blogs 0 15.12.2007 20:35
Ошибка SQL в модуле "Расчеты с персоналом" Карбофос DAX: Функционал 5 02.08.2002 12:44
Ошибка SQL в модуле "Расчеты с персоналом" Карбофос DAX: Программирование 0 31.07.2002 17:20
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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