24.07.2009, 19:41 | #1 |
Участник
|
conPeek() и common.dataareaID
Коллеги, кто-нибудь знает способ, как можно извлечь буфер из контейнера и сохранить оригинальное значение dataareaID.
Суть проблемы в том, что при извленчении буфера из контейнера, ядро заново констрактит экземпляр common, соответственно в common.datareaID кладется текущая компания, а исходное значение этого поля теряется. Таким образом если мы имеем контейнер содержащий буфер, то непонятно как определить его компанию. Есть какой нибудь нормальный способ ? |
|
|
За это сообщение автора поблагодарили: glibs (1). |
24.07.2009, 20:22 | #2 |
Member
|
static void glibs(Args _args)
{ CustTable custTable; List list; ListEnumerator listEnumerator; ; list = new List(Types::Record); select firstonly custTable; list.addEnd(custTable); changecompany ("DAT") { listEnumerator = list.getEnumerator(); while (listEnumerator.moveNext()) { custTable.data(listEnumerator.current()); info (strfmt("%1", custTable.dataAreaId)); } } }
__________________
С уважением, glibs® |
|
|
За это сообщение автора поблагодарили: Logger (2). |
24.07.2009, 20:34 | #3 |
Участник
|
Спасибо. Пример хороший.
Но вопрос был про контейнеры. Для них все плохо. Немного переделал джоб для иллюстрации. (Запускать надо не в компании dat) X++: static void glibs(Args _args) { container con; CustTable custTable; CustTable custTable2; CustTable custTable3; CustTable custTableCon; CustTable custTableCon2; CustTable custTableCon3; List list; ListEnumerator listEnumerator; ; list = new List(Types::Record); select firstonly custTable; list.addEnd(custTable); con = [custTable]; changecompany ("DAT") { listEnumerator = list.getEnumerator(); while (listEnumerator.moveNext()) { custTable.data(listEnumerator.current()); custTable2.data(listEnumerator.current()); custTable3 = listEnumerator.current(); info (strfmt("%1", custTable.dataAreaId)); info (strfmt("2 : %1", custTable2.dataAreaId)); info (strfmt("3 : %1", custTable3.dataAreaId)); [custTableCon] = con; custTableCon2 = conPeek(con,1); //custTableCon3 = listEnumerator.current(); info (strfmt("Con %1", custTableCon.dataAreaId)); info (strfmt("Con2 : %1", custTableCon2.dataAreaId)); //info (strfmt("Con3 : %1", custTableCon3.dataAreaId)); } } } |
|
24.07.2009, 20:47 | #4 |
Member
|
Вставляйте в контейнер List с единственной записью.
А если серьезно, то почему для вас так принципиален контейнер?
__________________
С уважением, glibs® |
|
24.07.2009, 20:53 | #5 |
Member
|
Джоб у меня такоо плана был .
Цитата:
Сообщение от glibs
...Вставляйте в контейнер List с единственной записью...
Кстати, в List можно вставить объект, в контейнер нет. Если я не ошибаюсь. А вообще мне казалось, что буфер в контейнер не вставляется. Так что спасибо, вспомнил теорию.
__________________
С уважением, glibs® |
|
24.07.2009, 20:55 | #6 |
Участник
|
Цитата:
Заметил что многие разработчики любят использовать контейнеры и класть туда все скопом. У нас из-за описанного бага в некоторых местах ошибки лезли. |
|
24.07.2009, 21:00 | #7 |
Member
|
Цитата:
Сообщение от Logger
...многие разработчики любят использовать контейнеры...
Не бросайте в меня камнями, пож. Я знаю, что вас тут много.
__________________
С уважением, glibs® |
|
24.07.2009, 21:30 | #8 |
Moderator
|
Вообще, создание классов-контейнеров (Map, List, Set) с типом Record у меня находится в списке приемов, благодаря которым можно получить проблему на ровном месте.
Уже несколько раз натыкался на случаи, когда память, выделенная на AOS под хранение Record не возвращается операционной системе даже после переиниициализации класса контейнера. Как правило, данная проблема ловится на самописных отчетах, обрабатывающих большой объем данных. Может быть в пятерке исправили - не проверял. Кроме того, подозреваю, что существует некая критическая длинна записи, после которой начинает проявляться данная проблема, но я не экспериментировал, а просто перепаковал все необходимые поля в контейнер от греха подальше. |
|
24.07.2009, 21:33 | #9 |
Боец
|
Есть 2 отличные функции у класса Global:
container buf2Con(Common common) static void con2Buf(container c, Common common) И ещё полезные: con2List, con2Str, buf2Buf, bufCmp X++: static void dspic(Args _args) { CustTable custTable; container conCustTable; ; select firstonly custTable; conCustTable = buf2con(custTable); changecompany ("DAT") { con2buf(conCustTable, custTable); info (strfmt("%1", custTable.dataAreaId)); } } |
|
|
За это сообщение автора поблагодарили: ZVV (2), Logger (2). |
27.07.2009, 08:41 | #10 |
Участник
|
Наиболее логичным способом помещения record в контейнер, как мне кажется является вариант, предложенный DSPIC, использование функций
container buf2Con(Common common) и static void con2Buf(container c, Common common), по всей видимости они для этого и предназначены Цитата:
Сообщение от DSPIC
Есть 2 отличные функции у класса Global:
container buf2Con(Common common) static void con2Buf(container c, Common common) ... X++: static void dspic(Args _args) { CustTable custTable; container conCustTable; ; select firstonly custTable; conCustTable = buf2con(custTable); changecompany ("DAT") { con2buf(conCustTable, custTable); info (strfmt("%1", custTable.dataAreaId)); } } Также в случае использования одной табличной переменной и функции xRecord.company(...) можно получить реальную компанию(однако, если в changeCompany("dat") вместо CustTable, использовать CustTable2, то в обоих случаях будет выведено "dat") X++: static void srf_test(Args _args) { CustTable custTable; Container conCustTable; ; select firstOnly custTable; conCustTable = [custTable]; changecompany("dat") { custTable.clear(); custTable.data(conpeek(conCustTable, 1)); info(custTable.dataAreaId); info(custTable.company()); } }
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: Logger (2). |
27.07.2009, 11:07 | #11 |
Боец
|
Цитата:
Однако стоить помнить, что функция Global \ container buf2Con(Common common) в версиях AX 3.0(возможно только в некоторых, проверял на AX 3.0 SP 2, AX 3.0 SP 3 CU 1) не работает(выпадает эксепшен), если у табличных переменных есть поля-массивы(т.е. выше описанный job работать не будет )
Я вот только не совсем понял, зачем вообще трогать dataAreaId? Насколько это корректно? Читать - да, менять - не знаю. По-моему, это бубен какой-то... |
|
28.07.2009, 11:30 | #12 |
Участник
|
По моему с записями лучше уже использовать RecordSortedList / RecordInsertList - они же для этого и созданы (journalTransList)
Чтоб пихать контейнер в List можно использовать ContainerClass, для уверенности, а вообще в 4.0 и выше уже можно пихать контейнер в список
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
04.03.2011, 00:19 | #13 |
Участник
|
В 2009-й исправлено.
Теперь сохраняется исходный dataareaID. |
|
Теги |
container, dataarea, компания |
|
|