AXForum  
Zurück   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Kennwort vergessen?
Registrieren Forum Rules Hilfe Benutzerliste Heutige Beiträge Suchen

 
 
Themen-Optionen Thema durchsuchen Ansicht
Alt 20.08.2004, 15:53   #1  
monk ist offline
monk
Участник
 
67 / 12 (1) ++
Registriert seit: 14.10.2002
Проверка на RecId
Привет.
Возник следующий вопрос:

Есть код:
Table1 table1 = Table1::find(_Key);

далее проверка, которую можно выполнить двумя способами
;
if (table1)
{
.....
}

и

if(table1.recId)
{
...
}

Является ли первый способ корректным?
Alt 20.08.2004, 16:09   #2  
mazzy ist offline
mazzy
Участник
Benutzerbild von mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29.472 / 4494 (208) ++++++++++
Registriert seit: 29.11.2001
Ort: Москва
Blog-Einträge: 10
в первом, насколько я понимаю, способе происходит неявное преобразование типов.
при преобразовании Common -> Int, Аксапта самостоятельно подставляет recID.

Поэтому, сейчас технически работают оба способа.
Рекомендуется использовать второй.

(Рекомендацию видел где-то в презентациях, где точно уже не помню)
Alt 20.08.2004, 16:32   #3  
Maxim Gorbunov ist offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2.483 / 646 (26) +++++++
Registriert seit: 27.11.2001
Ort: Dubai, UAE
Только не Common в int, а Common в boolean.

Во втором случае тоже преобразовние: int в boolean

Чтобы быть уверенным на 110%, пишите
if (table1.RecId != 0) {
...
}
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Alt 20.08.2004, 16:51   #4  
mazzy ist offline
mazzy
Участник
Benutzerbild von mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29.472 / 4494 (208) ++++++++++
Registriert seit: 29.11.2001
Ort: Москва
Blog-Einträge: 10
Zitat:
Изначально опубликовано Maxim Gorbunov
Только не Common в int, а Common в boolean.
Да, согласен. Спасибо.
Alt 22.08.2004, 06:32   #5  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Категорически не соглашусь с "мэтрами" :

1. Правила по преобразованию примитивных типов к логическому выражению в условиях, которые X++ унаследовал от C/C++ никто и никогда отменять не будет. Чётко и ясно сказано что нулевое значение аргумента воспринимается компилятором как false, а ненулевое - true, сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код.
if ( a )... всегда было и будет предпочтительнее чем if ( a != 0 ) так же как и
if ( !( a < b ) ) выглядит запутаннее и непонятнее, чем if ( a >= b )
(кстати в практике программирования на 1С встречал следующий код:
Если НЕ(ОсталосьСписать>0) Тогда
Прервать;
КонецЕсли;
долго смеялся )

2. То же самое касается и преобразования Common в boolean.
if ( tbl ) выглядит гораздо проще и интуитивно понятнее чем if ( tbl.RecId )
Чем обоснованы рекомендации предпочитать tbl.RecId мне непонятно, ведь если когда нибудь правило преобразования Common в boolean хотя бы слегка изменят, половина кода аксапты станет неработоспособной, посему его никогда не изменят.
В общем я предпочитаю if ( table1 )

Хотя в принципе всё это вопрос вкуса и относится к той же теме что и вопрос о том звёздочками или плюсиками лучше помечать блоки комментариев в коде.
Alt 23.08.2004, 09:52   #6  
Wamr ist offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1.737 / 868 (32) +++++++
Registriert seit: 15.01.2002
Ort: Москва
Blog-Einträge: 7
Проверка If(table) более интеллектуальна, чем проверка If(table.RecID).
Например, после агрегации и ограничения списка выбираемых полей возможна ситуация, когда RecId = 0, но If(table) = true

Для проверки после find, действительно, нет разницы как проверять наличие результата.
Alt 23.08.2004, 10:14   #7  
Ser ist offline
Ser
NavAx
 
99 / 14 (1) ++
Registriert seit: 04.03.2002
Ort: Москва
уже довольно давно правил такой код на форме накладных:
PHP-Code:
FactureEditLinesCust_RU.enabled(CustInvoiceJour.RecId);
FactureCust_RU.enabled(CustInvoiceJour.RecId); 
в некоторых случаях перечисленные элементы ну никах не желали активироваться.

только исправление на:
PHP-Code:
FactureEditLinesCust_RU.enabled((CustInvoiceJour.RecId true false));
FactureCust_RU.enabled((CustInvoiceJour.RecId true false)); 
ситуацию разрешило.

Это конечно же не конструкция if, но все равно аргумент должен приводиться к логическому типу
__________________
Чудес не бывает (c), истина где-то рядом (c)...
Alt 23.08.2004, 10:18   #8  
bucken ist offline
bucken
Участник
Benutzerbild von bucken
 
259 / 12 (1) ++
Registriert seit: 04.09.2003
Ort: Москва
флуд
Zitat:
Чётко и ясно сказано что нулевое значение аргумента воспринимается компилятором как false, а ненулевое - true, сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код.
Вот тоже решил чуть усомниться ...
Какой компилятор может быть во время выполения?
__________________
Уточните значение слов и вы избавите человечество от половины его заблуждений. (Рене Декарт) / Axapta 2.5
Alt 23.08.2004, 12:31   #9  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Zitat:
...
FactureEditLinesCust_RU.enabled(CustInvoiceJour.RecId);
...
только исправление на:
...
FactureEditLinesCust_RU.enabled((CustInvoiceJour.RecId ? true : false));
...
ситуацию разрешило.
...
аргумент должен приводиться к логическому типу
Честно говоря когда понял до конца что тут написано - ржал как конь!

Если бы ты написал
CustInvoiceJour.RecId != 0
то фраза "аргумент должен приводиться к логическому типу" имела бы смысл, а так просто очевидно что это либо очередной и довольно серьезный и тонкий глюк аксапты, либо пятна на солнце.
CustInvoiceJour.RecId ? true : false - это масло масляное в использованном контексте...

Было бы интересно проверить эту "фичу" в своём проекте.

P.S.

И в свете того что я говорил в первом своём посте тут:

А FactureEditLinesCust_RU.enabled( CustInvoiceJour ) не пробовали?
Alt 23.08.2004, 12:41   #10  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Re: флуд
Zitat:
Вот тоже решил чуть усомниться ...
Какой компилятор может быть во время выполения?
Усомняться не стоит - просто читать внимательнее надо - я же говорил про:
Zitat:
...которые X++ унаследовал от C/C++ никто и никогда отменять не будет.
По инерции думал про C++, не спорю что X++ не C++, но смысл сказанного от этого не становится непонятнее.

Да и вообще если язык программирования не может справится с чётко оговоренным преобразованием числа в булевский тип - то какая разница компилятор он или интерпретатор?
Alt 23.08.2004, 15:36   #11  
Ser ist offline
Ser
NavAx
 
99 / 14 (1) ++
Registriert seit: 04.03.2002
Ort: Москва
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения.

Я был тоже немало удивлен, но при этом сохранил человеческие повадки
__________________
Чудес не бывает (c), истина где-то рядом (c)...
Alt 23.08.2004, 16:09   #12  
db ist offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Registriert seit: 01.04.2004
Ort: Москва
Zitat:
Изначально опубликовано Alks
сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код ......

долго смеялся )

И пятна на солнце бывают и аксапта людьми написана. А хорошо смеется тот, кто смеется последним Вот вам джобик, запустите, а я посмеюсь

PHP-Code:
static void Job9(Args _args)
{
    
int             i = -1;
    
boolean         b;
    
InventTable     inventTable;


    while (
!= -1000)
    {
        
i;
        if (! 
b)
        {
            print 
i" "b" !!!";
        }
        
i--;
    }

    
inventTable.(fieldnum(CommonRecId)) = -512;

    if (
inventTable)
    {
        print 
"ok";
    }
    else
    {
        print 
"!!!";
    }

    if (
inventTable.RecId && 100 4)
    {
        print 
"ok";
    }
    else
    {
        print 
"!!!";
    }

    
inventTable && 100 4;

    if (
b)
    {
        print 
"ok";
    }
    else
    {
        print 
"!!!";
    }


    
inventTable.RecId;

    if (
b)
    {
        print 
"ok";
    }
    else
    {
        print 
"!!!";
    }

    
pause;


Axapta 3.0 SP3. То же самое в 2.5 и 2.1 Этому приколу уже лет 5.
Ну неправильно работет преобразование типов при присвоении int к boolean. В остальном все ок

Так что сомневаться бывает очень полезно
Alt 23.08.2004, 16:49   #13  
George Nordic ist offline
George Nordic
Модератор
Benutzerbild von George Nordic
Злыдни
 
4.480 / 1255 (50) ++++++++
Registriert seit: 17.12.2003
Ort: Moscow
Blog-Einträge: 9
Хм.. и best practise молчит насчет сравнения или проверки на наличие записи по RecId... Единственное, что нашлось:
PHP-Code:
//Example
static boolean exist(CustGroupId custGroupId)
{
   return  custGroupId && (select firstonly recId from custGroup
                           index hint GroupIdx
                           where custGroup
.custGroup     == custGroupId).recId != 0;

Так что будем юзать RecId != 0

to db: спасибо за инфу - есть над чем задуматься...
Каждое Ваше сообщение - либо дельный совет, либо куча загадок

С Уважением,
Георгий
Alt 24.08.2004, 05:53   #14  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Zitat:
Изначально опубликовано db


И пятна на солнце бывают и аксапта людьми написана. А хорошо смеется тот, кто смеется последним Вот вам джобик, запустите, а я посмеюсь

PHP-Code:
static void Job9(Args _args)
{
    
int             i = -1;
    
boolean         b;
    while (
!= -1000)
    {
        
i;
        if (! 
b)
        {
            print 
i" "b" !!!";
        }
        
i--;
    }

Так что сомневаться бывает очень полезно
Да у меня просто волосы дыбом встали! И ведь по результатам видно что происходит какая то хрень с преобразованием отрицательных чисел кратных 256 - такое ощущение что для них перед преобразованием в boolean сперва идет преобразование в однобайтовое число. Хотел бы я узнать каким алгоритмом пользуются создатели X++ при этом преобразовании что возникает такой нехарактерный глюк. По хорошему a == true на низком уровне должно преобразовываться в a != 0, а a == false в a == 0. Как тут можно допустить исключительные ситуации с отрицательными числами ума просто не приложу!

Однако, я всё таки сейчас поулыбаюсь бледной улыбкаой, сразу после предыдущего попробуйте следующий джобик:

PHP-Code:
static void Job9(Args _args)
{
    
int             i = -1;
    
boolean         b;
    while (
!= -1000)
    {
        
i;
        if (! 
i)
        {
            print 
i" "b" !!!";
        }
        
i--;
    }
    
pause;



так что if ( tbl ) вполне корректно.

В подтверждение этому обратите внимание на то что участок кода:

Zitat:
inventTable.(fieldnum(Common, RecId)) = -512;

if (inventTable)
{
print "ok";
}
else
{
print "!!!";
}

if (inventTable.RecId && 100 > 4)
{
print "ok";
}
else
{
print "!!!";
}

b = inventTable && 100 > 4;

if (b)
{
print "ok";
}
else
{
print "!!!";
}
Работает тоже совершенно корректно (просто inventTable && 100 > 4 трактуется по приоритету операций как (inventTable && (100 > 4)) это хорошо видно если начать задавать скобки явно), очевидно что проблемы начинаются когда X++ вынужден сохранять результат конвертации int->boolean в явно заданную переменную (возможно так же что и как параметр ф-ии тоже). Спасибо конечно за предупреждение - теперь буду проявлять осторожность при передаче чисел как параметров в ф-ии предполагающие boolean аргумент, но глядя на то сколько сравнений вида if ( tbl ) сидит в недрах sys слоя Аксапты я свою привычку менять не буду.
Alt 24.08.2004, 06:19   #15  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Zitat:
Изначально опубликовано Ser
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения.

Я был тоже немало удивлен, но при этом сохранил человеческие повадки
Извиняюсь если был груб, это неспециально. Замечу что я не обвинял вас и не сомневался в том что такого не может быть - было просто действительно смешно видеть такие ляпы в X++.

После постинга db рассеивается эта страшная тайна - передача параметра в ф-ю видимо испытывает те же трудности с конвертацией int->boolean что и явное присваивание переменной...
Alt 24.08.2004, 11:14   #16  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Вот еще некоторые любопытные факты из жизни конвертации чисел в boolean, немножко проливающие свет на то что находится под капотом сего глюка:

PHP-Code:
static void Job4(Args _args)
{
    
boolean b;
    
real x;
    
int ij;
    ;
    
// Финт ушами №1, крест на явной конвертации real->boolean
    // хотя в language guide написано что всё должно быть пучком
    
0.7;
    
x;
    if ( 
info"TRUE" ); else info"FALSE" );
    if ( 
info"TRUE" ); else info"FALSE" );
    
    
// Финт ушами №2, принуждение к неявной конвертации спасает дело даже
    // если целью является явная ( a && true = a )
    
= -512;
    if ( 
info"TRUE" ); else info"FALSE" );
    
= -512 && true;
    if ( 
info"TRUE" ); else info"FALSE" );

    
// Финт ушами №3, немного проясняющий странность поведения явной конвертации 
    // чисел в boolean. boolean на самом деле оказывается байтом в котором
    // дамгардовцы пытаются сохранить нижние 8 бит исходного числа, что у них
    // плохо получается если это число - отрицательное
    
for ( 250<= 260i++ )
    {
        
i;
        
b;
        
infoint2str) + "->" + (b?"true":"false") + "->" int2str) );
    }
    for ( 
= -250>= -260i-- )
    {
        
i;
        
b;
        
infoint2str) + "->" + (b?"true":"false") + "->" int2str) );
    }

И всё становится ясно!

ВИДИМО где то в недрах интерпретатора Axapta присваивание переменной булевского типа использует следующий алгоритм конвертации (записано на языке C):

byte int2bool( int i )
{
return i > 255 ? 255 : i;
}

По вине разработчиков случай на i < 0 никак не обрабатывается, что приводит к урезанию ответа до последнего байта в этом случае и как следствие некорректному результату при i < 0 и кратных 256.
Alt 24.08.2004, 12:00   #17  
mazzy ist offline
mazzy
Участник
Benutzerbild von mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29.472 / 4494 (208) ++++++++++
Registriert seit: 29.11.2001
Ort: Москва
Blog-Einträge: 10
думаю, что все проще.
при присваивании булеву значению берется только младший байт

т.е. b = i выполняется как b = lowbyte(i)
Alt 24.08.2004, 12:22   #18  
Alks ist offline
Alks
Участник
 
336 / 41 (2) +++
Registriert seit: 23.07.2004
Ort: г. Новокузнецк
Zitat:
Изначально опубликовано mazzy
думаю, что все проще.
при присваивании булеву значению берется только младший байт

т.е. b = i выполняется как b = lowbyte(i)
Нет. Выполните Job из моего последнего сообщения и поймете что всё обстоит именно так как я в нём написал, а именно: b = ( i > 255 ) ? 255 : lowbyte( i );

Преобразование real->boolean происходит по видимому еще хуже - сперва происходит преобразование real -> int с потерей дробной части (!!!) и только потом уже (по всё той же корявой схеме) из int -> boolean. Тихий ужас.
Спасает только то что эти корявости имеют место быть только при присвоении к булевским переменным/параметрам ф-й, подвыражения в выражениях же вычисляются правильно.
Alt 24.08.2004, 14:52   #19  
db ist offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Registriert seit: 01.04.2004
Ort: Москва
Похоже я всех малость напугал, уж извините, больше не буду

Еще немножечко информации. Почти всю ее предыдущие авторы добыли методом тыка, просто подитожу то, что добыл когда то методом инструмента, против которого нет приема

Во первых аксаптовский интерпретатор не имеет типа boolean, там есть только enum,
который по совместительству используется как boolean

Преобразование int->enum
если int>255, то enum = 255, иначе enum=(BYTE)int
соответсвенно не прокатывают все отрицательные числа, кратные -256

Преобразование dbl->int
int=откинуть дробную часть(dbl)

Преобразование dbl->enum
int=откинуть дробную часть(dbl)
enum=(BYTE)int
соответственно не прокатывают все числа с откинутой дробной частью кратные как -256, так и +256

Все преобразования происходят именно так. Пришлось однажды разобраться, когда показалось, что глючит не Аксапту, а меня.

В общем, наслаждайтесь. Жизнь полна неожиданностей, тем она и прекрасна
Alt 24.08.2004, 15:28   #20  
mazzy ist offline
mazzy
Участник
Benutzerbild von mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29.472 / 4494 (208) ++++++++++
Registriert seit: 29.11.2001
Ort: Москва
Blog-Einträge: 10
Zitat:
Изначально опубликовано db
Похоже я всех малость напугал, уж извините, больше не буду
Нет, уж!
Огромное спасибо за вопросы!

Побольше бы таких неожиданных и интересных.
Stichworte
recid, баг, ошибка, ax3.0

 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
if (record) vs if (record.RecId) kashperuk DAX: Программирование 18 27.11.2008 18:53
Как сформировать RecId Arahnid DAX: Программирование 18 14.07.2008 15:02
поля, содержащие RecId somebody DAX: Программирование 15 16.05.2008 17:50
aEremenko: Дефрагментация RecID Blog bot DAX Blogs 2 06.03.2007 22:25
Два RecId у одной записи таблицы sparur DAX: Программирование 33 18.12.2006 15:56

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Gehe zu

Рейтинг@Mail.ru
Alle Zeitangaben in WEZ +3. Es ist jetzt 12:19 Uhr.
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.