10.07.2007, 13:25 | #1 |
Участник
|
Посмотреть Dimension в контейнере
Подскажите, пожалуйста - каким образом вывести на экран содержимое элемента контейнера, который (элемент) имеет тип Dimension, т.е. имеет ArrayElements.
Если написать тестовый job: X++: Dimension dim; container con; ; dim[1] = "dim"; dim[2] = "dim"; dim[3] = "dim"; con = [1, "2", dim]; info(con2str(con));
__________________
Paul_ST |
|
10.07.2007, 13:57 | #2 |
MCT
|
Вот это поможет?
X++: static void GetDimension(Args _args) { Dimension dim; container con, confin; ; dim[1] = "dim1"; dim[2] = "dim2"; dim[3] = "dim3"; con = [1, "2", dim]; dim = conpeek(con,3); print dim[1] ; print dim[2] ; print dim[3] ; pause; } |
|
10.07.2007, 14:05 | #3 |
Участник
|
Работать это решение конечно же будет. Только исходная задача состоит именно в том, что неизвестно - на каких местах в контейнере находятся переменные с типами (разными), которые имеют ArrayElements. Одним словом - хотелось бы понять - есть ли какое то простое и общее средство в данном случае.
__________________
Paul_ST |
|
10.07.2007, 14:06 | #4 |
Участник
|
Набросал я тут метод, правда не особо тестил, так что юзай осторожно.
третий параметр необязательный, поэтому в принципе можно в дальнейшем подменить им оригинальную con2str X++: static str 1000 con2Str_Arr(container c, str 10 sep = ',', container cType = conNull()) { int idx = 0; int len = conLen(c); str 100 tmp; str 1000 retStr; SysDictType dictType; ExtendedTypeId extTypeId; int i; str arr2str() { str ret; ; dictType.setValue(conPeek(c,idx)); for (i = 1; i <= dictType.arraySize(); i++) { ret += ret ? ',' : '<'; ret += dictType.getValue(i); } ret += '>'; return ret; } ; while (idx < len) { idx += 1; if (retStr) retStr += sep; tmp = conPeek(c,idx); if (cType) { extTypeId = conPeek(cType, idx); if (extTypeId) { dictType = new SysDictType(extTypeId); if (dictType.arraySize() > 1) tmp = arr2str(); } } retStr += tmp; } return retStr; } X++: static void Job87(Args _args) { Dimension dim; container con; ; dim[1] = "dim123"; dim[2] = "dim321"; dim[3] = "dim333"; con = [1, "2", dim]; info(con2str_Arr(con)); info(con2str_Arr(con, ',', [0, 0, extendedTypeNum(Dimension)])); } |
|
10.07.2007, 14:28 | #5 |
Участник
|
Спасибо за пример, но без третьего параметра существенно не будет отличаться от моего изначального кода - т.е. в Вашем примере как раз ключевую роль имеет указание типа данных.
__________________
Paul_ST |
|
10.07.2007, 14:39 | #6 |
Участник
|
Естественно. В этом вся соль. Что если третий параметр не передавать, то работать будет, как и con2str
а передав третий параметр, можем выводить еще и массивы. а не передавая тип данных узнать arraySize не получиться, так как контейнер может содержать все типы. |
|
10.07.2007, 14:42 | #7 |
Участник
|
Получается очень странно - ведь по идее можно было бы у любого типа перебирать все его значения в arrayElement и выводить их банальным any2str().
__________________
Paul_ST |
|
10.07.2007, 15:20 | #8 |
Участник
|
Может и странно. Но у меня сходу не получилось определить тип значения в контейнере. typeOf(conPeek(c, idx)) возвращает null для третьего элемента.
|
|
10.07.2007, 18:51 | #9 |
Microsoft Dynamics
|
Создала баг Но если и пофиксят, то явно не в 3ке-4ке.
|
|
|
За это сообщение автора поблагодарили: mazzy (5). |
12.07.2007, 13:17 | #10 |
Microsoft Dynamics
|
Не пофиксят пока.
Проблема не в сохранении дименшена в контейнере, а в том, что дименшен нельзя в anytype перевести при извлечении, а кастинг крешит ахапту. |
|
12.07.2007, 15:32 | #11 |
Участник
|
Могу предложить такой вариант. В принципе, должен работать с массивами любых типов (в том числе и динамическими)
X++: str con2Str_ext(container _in, str 10 sep = ',') { int i; container c; int clen = conlen(_in); int k; str s; str res; int len; int pos; str 4 enumType; DictEnum dictEnum; enumId type; date dt; boolean first; ; res = ""; for (k=1;k<=clen;k++) { c = [conpeek(_in, k)]; s = BinData::dataToString(new ContainerClass(c).toBlob()); s = strrem(s, "\r"); if (substr(s, 1, 2) == "07") { if (substr(s, 3, 1) == "2") { len = str2int("0x" + substr(s, 7, 2) + substr(s, 5, 2)); res += (res ? sep : "") + "["; first = true; switch (substr(s, 4, 1)) { case "0": // строка pos = 0; s = substr(s, 6*2+1, strlen(s)); while (strscan(s, "00", 1, strlen(s))) { pos = strscan(s, "00", 1, strlen(s)); if (pos mod 2 == 0) pos++; c = ContainerClass::blob2Container( BinData::stringToData("0700" + substr(s, 1, pos-1) + "00ff")); res += (!first ? sep : "") + con2str(c) ; first = false; s = strdel(s, 1, pos+1); } break; case "1": // целое значение for (i=0;i<len;i++) { c = ContainerClass::blob2Container( BinData::stringToData("0701" + substr(s, i*8 + 9, 8) + "ff")); res += (!first ? sep : "") + con2str(c) ; first = false; } break; case "2": // значение с плавающей точкой for (i=0;i<len;i++) { c = ContainerClass::blob2Container( BinData::stringToData("0702" + substr(s, i*20 + 9, 20) + "ff")); res += (!first ? sep : "") + con2str(c) ; first = false; } break; case "3": // дата for (i=0;i<len;i++) { c = ContainerClass::blob2Container( BinData::stringToData("0703" + substr(s, i*6 + 9, 6) + "ff")); [dt] = c; res += (!first ? sep : "") + date2str(dt, 123, 2, 2, 2, 2, 4) ; first = false; // res += (res ? sep : "") + con2str(c) ; } break; case "4": // енум enumType = substr(s, 9, 4); type = str2int("0x" + substr(enumType, 3, 2) + substr(enumType, 1, 2)); dictEnum = new DictEnum(type); for (i=0;i<len;i++) { /* c = ContainerClass::blob2Container( BinData::stringToData("0704" + substr(s, i*2 + 13, 2) + enumType + "ff")); res += (res ? sep : "") + con2str(c) ;*/ // если необходимо выводить значения енума в числовом виде, // то надо убрать предыдущий комментарий и закомментировать эту строку res += (!first ? sep : "") + /*dictEnum.name() + "::" + */dictEnum.value2Symbol(str2int("0x" + substr(s, i*2 + 13, 2))); first = false; } break; } res += "]"; } else { s = conpeek(c, 1); res += (res ? sep : "") + s; } } } return res; } Для динамических массивов возможно появление в конце пустых значений. Для енумов это будет элемент с EnumValue==0 (если он есть)
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Logger (4). |
12.07.2007, 16:24 | #12 |
Administrator
|
2AndyD:
Тогда уж заменить можно было бы магические цифры 0, 1, 2, ... "07" на значение Types::String, Types::Integer, Types::Real,..., Types::Container А то уж больно смущают "магические" цифры
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: Lemming (2), Logger (1). |
13.07.2007, 08:56 | #13 |
Участник
|
2 AndyD: Спасибо большое! То, что нужно!
__________________
Paul_ST |
|
26.03.2008, 11:09 | #14 |
Участник
|
Цитата:
Приложение - в примере, вызывается из паспорта записи кнопкой "Поля в буфер". Соответственно, на таблице, имеющей Dimension, например, Клиенты Последний раз редактировалось gefr; 26.03.2008 в 14:05. |
|
|
За это сообщение автора поблагодарили: kashperuk (5). |
26.03.2008, 13:46 | #15 |
Участник
|
Если я правильно понял, вот пример: (над ним возможно поработать надо, чтоб не падал в различных ситуациях, но суть думаю будет ясна)
X++: static void Job1(Args _args) { SysDictTable dictTable = new SysDictTable(tableNum(CustTable)); Common common; SysDictField dictField; container con; int i, j; str value; ; common = dictTable.makeRecord(); select common where common.RecId == 5637144579; for (i = 1; i <= dictTable.fieldCntWithoutSys(); i++) { dictField = dictTable.fieldObject(dictTable.fieldCnt2Id(i)); if (dictField.arraySize() > 1) { for (j = 1; j <= dictField.arraySize(); j++) { if (value) value += ','; value += common.(fieldId2Ext(dictField.id(), j)); } info(value); } else { info(strFmt("%1", common.(dictField.id()))); } } } - Можно комментарии на англ. язык перевести? - Убедиться, что проект работает если вызывать НЕ из Паспорт записи Спасибо |
|
|
За это сообщение автора поблагодарили: gefr (1). |
26.03.2008, 13:59 | #16 |
Участник
|
это и был проект, который работает НЕ из паспорта записи. Описываемый блок вызывается при наличии буфера записи. Проект не мой, нашел может даже и здесь, докрутил, что было надо нам. Старая функциональность осталась без изменений
|
|
26.03.2008, 14:02 | #17 |
Участник
|
спасибо, этот вариант сработал.
Последний раз редактировалось gefr; 26.03.2008 в 14:39. |
|
26.03.2008, 14:33 | #18 |
Участник
|
Угу. Проект этот мой.
Вот здесь, насколько я вижу, Вы добавили проект с возможностью вызова из Паспорта Записи. http://www.axaptapedia.com/AxCopyTab...istToClipboard Поэтому и прошу проверить, что он по прежнему работает при вызове НЕ из паспорта записи. + комментарии еще в нескольких местах у Вас остались на русском. |
|
26.03.2008, 14:41 | #19 |
Участник
|
Без паспорта работает - проверил изнчально. Все комменты заменил, выложил на прежний пост.
|
|
26.03.2008, 14:46 | #20 |
Участник
|
перевыложил на axaptapedia
|
|
Теги |
container, аналитика, баг, axapta |
|
|