11.11.2015, 13:26 | #1 |
Участник
|
Проход по всему АОТ и изменение свойств
Доброго времени суток!
Стоит задача обойти абсолютно все узлы АОТ, проверить есть ли у них свойство CountryRegionCodes, получить его значение и в определенных условиях присвоить новое значение. Нашел много вариантов прохода по АОТ, но не нашел способа решить вторую часть задачи. Подскажите самый простой способ решения. |
|
11.11.2015, 13:45 | #2 |
Участник
|
Вам нужно, чтобы поля, доступные в определенных регионах, были видны в других или вообще всех регионах? Задача нетривиальная. В коде куча проверок типа "if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoRU]))", т.е. даже если вы "откроете" поля, они могут оказаться пустыми. От региона может зависеть, как то или иное поле будет заполнено. Так что автоматически присваивать новое значение свойству CountryRegionCodes опасно, если не анализировать каждое изменение.
Последний раз редактировалось Stitch_MS; 11.11.2015 в 13:48. |
|
11.11.2015, 13:45 | #3 |
Участник
|
X++: TreeNode.AOTsetProperty( 'name', value ); TreeNode.AOTsave(); If(TreeNode.TreeNodeType().isConsumingMemory()) TreeNode.treeNodeRelease(); Последний раз редактировалось Товарищ ♂uatr; 11.11.2015 в 13:56. |
|
11.11.2015, 14:06 | #4 |
Участник
|
Цитата:
Сообщение от Stitch_MS
Вам нужно, чтобы поля, доступные в определенных регионах, были видны в других или вообще всех регионах? Задача нетривиальная. В коде куча проверок типа "if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoRU]))", т.е. даже если вы "откроете" поля, они могут оказаться пустыми. От региона может зависеть, как то или иное поле будет заполнено. Так что автоматически присваивать новое значение свойству CountryRegionCodes опасно, если не анализировать каждое изменение.
Я в курсе что по коду придется тоже проходить, думаю вручную поиском это вполне реально сделать. Просто АОТ вручную перелопачивать так себе вариант ) |
|
11.11.2015, 16:55 | #5 |
Участник
|
Можно попробовать значение макросов изменить так чтобы два региона имели одно и тоже значение. Сам не пробовал, нужно тестировать.
|
|
11.11.2015, 17:35 | #6 |
Британский учённый
|
Цитата:
Если не взлетит, то тогда альтернатива - выгрузить нужные объекты и пройтись по коду и свойствам один раз, сделав нужные изменения.
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. |
|
13.11.2015, 01:11 | #7 |
Боец
|
Цитата:
Сообщение от syl
Доброго времени суток!
Стоит задача обойти абсолютно все узлы АОТ, проверить есть ли у них свойство CountryRegionCodes, получить его значение и в определенных условиях присвоить новое значение. Нашел много вариантов прохода по АОТ, но не нашел способа решить вторую часть задачи. Подскажите самый простой способ решения. Умеет искать любое свойство элемента в АОТ. - патчим, и она начинает Работать на вас - не забываем снести патч по окончанию |
|
13.11.2015, 11:58 | #8 |
Участник
|
Написал такой джоб:
X++: static void ChangeRegionCodes(Args _args) { UtilElements e; TreeNode treeNode; Dialog dialog; DialogField _level; DialogField _from; DialogField _to; UtilEntryLevel utilLevel; str _fromVal; str _toVal; str value; int i; ; dialog = new Dialog("Change locale"); _level = dialog.AddField(enumStr(UtilEntryLevel)); _from = dialog.AddField(extendedTypeStr(Region)); _to = dialog.AddField(extendedTypeStr(Region)); if(dialog.run()) { utilLevel = _level.value(); _fromVal = _from.value(); _toVal = _to.value(); } while select e where e.utilLevel == utilLevel && !(e.recordType == 37) //SharedProjects { treeNode = xUtilElements::getNodeInTree(xUtilElements::parentElement(e)); try { if(treeNode.AOTtypeStr() != "WMU" && treeNode.AOTtypeStr() != "PRN" && treeNode.AOTtypeStr() != "JOB") value = treeNode.AOTgetProperty("CountryRegionCodes"); if(value && strContains(value, _fromVal) && !strContains(value, _toVal)) { treeNode.AOTsetProperty("CountryRegionCodes", value + strFmt(",",_toVal)); treeNode.AOTsave(); i++; } If(treeNode.TreeNodeType().isConsumingMemory()) treeNode.treeNodeRelease(); } catch { info(treeNode.AOTtypeStr()); } } info(strFmt("Count of objects changed: %1", i)); } Есть еще варианты? |
|
13.11.2015, 12:12 | #9 |
Участник
|
Случаи нехватки памяти при перелопачивании клиентом всего АОТа нередки. Во-первых, можно перенести работу job'а на сервер (запускать его соотв. пунктом меню), во-вторых, можно сжалиться и лопатить не весь АОТ за раз, а по отдельным веткам
|
|
|
За это сообщение автора поблагодарили: syl (1). |
13.11.2015, 12:29 | #10 |
Британский учённый
|
Цитата:
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. |
|
|
За это сообщение автора поблагодарили: syl (1). |
13.11.2015, 13:34 | #11 |
Участник
|
В таблице UtilElements я не нашел типов View и Map. И есть проблема с формами, сама форма не содержит свойство CountryRegionCodes, надо както получать свойство из дочерней ноды дизайна
|
|
16.11.2015, 11:55 | #12 |
Участник
|
Все сделал. Если кому интересно, вот код:
X++: class ChangeRegionCodes { int64 i,z; } private void ChangeCode(TreeNode _objTreeNode) { int line; str value; ; if (_objTreeNode) { _objTreeNode = _objTreeNode.AOTfirstChild(); while (_objTreeNode) { z++; try { value = _objTreeNode.AOTgetProperty("CountryRegionCodes"); if(strContains(value, "RU") && !strContains(value, "UA")) { _objTreeNode.AOTsetProperty("CountryRegionCodes", value + ",UA"); _objTreeNode.AOTsave(); i++; } } catch { infolog.clear(0); } this.ChangeCode(_objTreeNode); _objTreeNode = _objTreeNode.AOTnextSibling(); } } } private void Proceed() { TreeNode objTreeNode; utcDateTime time; setPrefix("Change region codes"); time = DateTimeUtil::utcNow(); objTreeNode = TreeNode::findNode(@"\Menu Items\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Data Dictionary\Tables\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Data Dictionary\Maps\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Data Dictionary\Views\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Data Dictionary\Extended Data Types\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Data Dictionary\Base Enums\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Menus\"); this.ChangeCode(objTreeNode); objTreeNode = TreeNode::findNode(@"\Forms\"); this.ChangeCode(objTreeNode); info(strFmt("Process started at %1",time)); info(strFmt("Count of objects changed: %1. Objects count: %2", i, z)); info(strFmt("Process ended at %1",DateTimeUtil::utcNow())); } static server void main() { ChangeRegionCodes c = new ChangeRegionCodes(); c.Proceed(); } |
|
16.11.2015, 11:59 | #13 |
Гость
|
|
|
|
|