Спасибо огромное, помогло, работает и правда долго (минуты 3), но работает.
Получился вот такой метод, может кому пригодится, на качество кода не претендую:
X++:
void securitykey2utilidelements()
{
#AOT
str path, properties;
treenode treenode;
identifiername identifiername;
UtilIDElements utils, utils1;
UtilElementType CurElementType;
dictionary dict;
DictSecurityKey DictSK;
SecurityKeyID SecurityKeyID;
;
delete_from seckey2utilstable;
while select typessubset
{
CurElementType = typessubset.UtilElementType;
While Select count(recid) from utils group by id, recordtype, name
where utils.recordType == CurElementType
{
select firstonly utils1 where
utils.recordType == utils1.recordType &&
utils.id == utils1.id &&
utils.name == utils1.name;
treenode = xUtilIDElements::getNode(utils1);
If (treenode)
{
properties = treenode.AOTgetProperties();
path = treenode.treeNodePath();
identifiername = findproperty(properties, 'SecurityKey');
ttsbegin;
seckey2utilstable = null;
seckey2utilstable.insert();
if (identifiername != '')
{
dict = new dictionary();
SecurityKeyID = dict.securityKeyName2Id(identifiername);
seckey2utilstable.SecurityKeyID = SecurityKeyID;
DictSK = new DictSecurityKey(SecurityKeyID);
seckey2utilstable.SecurityKeyLabel = DictSK.label();
seckey2utilstable.SecurityKeyName = identifiername;
}
seckey2utilstable.ObjectPath = path;
seckey2utilstable.ObjectName = utils.name;
seckey2utilstable.ObjectNum = utils.id;
seckey2utilstable.UtilElementType = typessubset.UtilElementType;
seckey2utilstable.update();
ttscommit;
//info(strfmt( treenode.treeNodePath()) + ' / ' + identifiername);
}
}
}
}
Таблица typessubset нужна чтобы выбрать туда только те элементы из UtilElementType которые имеют SecurityKey, чтобы перебирать не все типы элементов, например элементы типа class, form, report не нужны.
Спасибо еще раз!