![]() |
#3 |
Участник
|
Цитата:
Изначально я пытался порешать вот эту проблему: http://sashanazarov.blogspot.com/201...-fails-on.html Для решения написал метод в Global (он как раз решает проблему описанную в блоге sashanazarov - позволяет обойти баги ядра) X++: // обходим баг вызова orig() для табличек с наследованием // [url]http://sashanazarov.blogspot.com/2014/01/dynamics-ax-2012-orig-method-fails-on.html[/url] // [url=http://axforum.info/forums/showthread.php?p=328140#post328140]Опасный orig[/url] public static anyType origFieldValue_MRC(Common _common, FieldId _fieldId) { TableId tableId; TableId tableId4Field; FieldName fieldName; Common commonCasted; Common commonOrig; DictTable dictTable; anytype ret; ; if (_common.RecId == 0) { // обходим баг // [url=http://axforum.info/forums/showthread.php?p=328140#post328140]Опасный orig[/url] commonOrig = _common.orig(); commonOrig.doClear(); ret = commonOrig.(_fieldId); } else { dictTable = new DictTable(_common.TableId); if (!(dictTable && dictTable.supportInheritance())) { // обычная табличка без наследования - все как обычно commonOrig = _common.orig(); ret = commonOrig.(_fieldId); } else { // обходим баг // [url]http://sashanazarov.blogspot.com/2014/01/dynamics-ax-2012-orig-method-fails-on.html[/url] // решаем проблемы с получением значений из родительских табличек для orig() буфера // ищем tableId в иерархии наследования для которой первой определено поле _fieldId т.е. ту для которой оно было введено, а не отнаследовано. fieldName = fieldId2name(_common.TableId, _fieldId); tableId4Field = _common.TableId; if(fieldName) { tableId = dictTable.extends(); while(tableId) { dictTable = new DictTable(tableId); if (fieldName2id(tableId, fieldName)) { tableId4Field = tableId; } else { break; } tableId = dictTable.extends(); } } if (tableId4Field) { commonCasted = SysDictTable::as(_common, tableId2name(tableId4Field)); commonOrig = commonCasted.orig(); ret = commonOrig.(_fieldId); } else { // не должны сюда попасть. Можно кидать исключение. commonOrig = _common.orig(); ret = commonOrig.(_fieldId); } } } return ret; } иллюстрация работы метода origFieldValue_MRC - джоб: X++: // [url]http://sashanazarov.blogspot.com/2014/01/dynamics-ax-2012-orig-method-fails-on.html[/url] static void reproOrigBug_MRC(Args _args) { CompanyInfo companyInfo; DirPartyTable dirPartyTable; Common common5; Common common6; anytype any; ; select firstOnly companyInfo; info(strFmt("Поле СompanyInfo.DataAreaId (системное. Определено на СompanyInfo). Значение \"%1\"", companyInfo.DataAreaId)); info(strFmt("Поле СompanyInfo.VATNum (не наследовано). Значение \"%1\"", companyInfo.VATNum)); info(strFmt("Поле СompanyInfo.Name (наследовано из DirPartyTable - от головной таблички в иерархии наследования). Значение \"%1\"", companyInfo.Name)); info(strFmt("Поле СompanyInfo.PhoneticName (наследовано из DirOrganizationBase - от промежуточной таблички в иерархии наследования. 1-й уровень наследования). Значение \"%1\"", companyInfo.PhoneticName)); info(strFmt("Поле СompanyInfo.DEL_RelationTypeName_OMInternalOrg (наследовано из OMInternalOrganization - от промежуточной таблички в иерархии наследования. 2-й уровень наследования). Значение \"%1\"", companyInfo.DEL_RelationTypeName_OMInternalOrg)); info(""); info("Теперь проверяем работу Orig()"); info(""); info("1. Обычный вызов companyInfo.orig().FieldName - для полей из таблиц родителей - теряем значения"); info(strFmt("companyInfo.orig().DataAreaId = \"%1\"", companyInfo.orig().DataAreaId)); info(strFmt("companyInfo.orig().VATNum = \"%1\"", companyInfo.orig().VATNum)); info(strFmt("companyInfo.orig().Name = \"%1\" %2", companyInfo.orig().Name, (companyInfo.orig().Name ? "" : "Потеряли значение !"))); info(strFmt("companyInfo.orig().PhoneticName = \"%1\" %2", companyInfo.orig().PhoneticName, (companyInfo.orig().PhoneticName ? "" : "Потеряли значение !"))); info(strFmt("companyInfo.orig().DEL_RelationTypeName_OMInternalOrg = \"%1\" %2", companyInfo.orig().DEL_RelationTypeName_OMInternalOrg, (companyInfo.orig().DEL_RelationTypeName_OMInternalOrg ? "" : "Потеряли значение !"))); info(""); dirPartyTable = companyInfo as DirPartyTable; info("2. Явно приводим тип к табличной переменной другого типа. dirPartyTable = companyInfo as DirPartyTable. Вызов dirPartyTable.orig().FieldName. Лечит проблему но неудобно использовать. Надо помнить из какой таблички пришло поле в иерархии наследования. Держать в коде отдельную табличную переменную другого типа."); info(strFmt("dirPartyTable.orig().DataAreaId = \"%1\"", dirPartyTable.orig().DataAreaId)); info(strFmt("dirPartyTable.orig().VATNum - НЕПРИМЕНИМО" /*, dirPartyTable.orig().VATNum*/)); info(strFmt("dirPartyTable.orig().Name = \"%1\"", dirPartyTable.orig().Name)); info(strFmt("dirPartyTable.orig().PhoneticName - НЕПРИМЕНИМО" /*, dirPartyTable.orig().PhoneticName*/)); info(strFmt("dirPartyTable.orig().DEL_RelationTypeName_OMInternalOrg - НЕПРИМЕНИМО" /*, dirPartyTable.orig().DEL_RelationTypeName_OMInternalOrg*/)); info(""); info("3. Попытка достать через common.orig() и прочие танцы с бубном - не помогло"); common5 = null; common6 = null; common5 = new SysDictTable(tableNum(DirPartyTable)).makeRecord(); // тип DirPartyTable common5.data(companyInfo); // тип DirPartyTable , но это не помогает вытащить правильное значение common6 = common5.orig(); // тип DirPartyTable , но это не помогает вытащить правильное значение info(strFmt("common6.(fieldNum(DirPartyTable, Name)) = \"%1\"", common6.(fieldNum(DirPartyTable, Name)))); common5 = null; common6 = null; common5 = new SysDictTable(tableNum(DirPartyTable)).makeRecord(); // тип DirPartyTable , но это не помогает вытащить правильное значение common5.data(companyInfo.orig()); // вот тут уже при вызове Orig() значение потеряно common6 = common5; info(strFmt("common6.(fieldNum(DirPartyTable, Name)) = \"%1\"", common6.(fieldNum(DirPartyTable, Name)))); info(""); info("4. Игры с приведением типов через переменную с типом anyType - все хорошо, но неудобно использовать."); any = new SysDictTable(tableNum(DirPartyTable)).makeRecord(); // any - тип DirPartyTable any = companyInfo; // any - все равно тип DirPartyTable - в этот момент происходит "приведение" типа. common5 = any; // common5 - тип DirPartyTable common6 = common5.orig(); // common6 - тип DirPartyTable info(strFmt("common6.(fieldNum(DirPartyTable, Name)) = \"%1\"", common6.(fieldNum(DirPartyTable, Name)))); info(""); info("5. Достаем значение вызовом origFieldValue_MRC(companyInfo, ...) - все нормально. Удобно использовать."); info(strFmt("origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, DataAreaId)) = \"%1\"", origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, DataAreaId)))); info(strFmt("origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, VATNum)) = \"%1\"", origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, VATNum)))); info(strFmt("origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, Name)) = \"%1\"", origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, Name)))); info(strFmt("origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, PhoneticName)) = \"%1\"", origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, PhoneticName)))); info(strFmt("origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, DEL_RelationTypeName_OMInternalOrg)) = \"%1\"", origFieldValue_MRC(companyInfo, fieldnum(CompanyInfo, DEL_RelationTypeName_OMInternalOrg)))); info(""); } Последний раз редактировалось Logger; 25.09.2018 в 11:38. |
|