Привет всем.
Оказывается на этом фичи формы персонализации не заканчиваются.
Для связей с типом PrimaryKey криво отображаются связи в запросе.
Пример :
1. Форма перекрестных ссылок "Чем используется" (\Forms\xRefReferencesUsedByTypedTree)
Связи датасорса xRefReferences с дочерними отображаются так
xRefPaths. == xRefReferences. Role: xRefPaths_1
xRefNames. == xRefReferences. Role: xRefNames
т.е. пропущено имя поля и добавлено имя роли. Но пропуск сделан глючно. Нет нормальной обработки. Похоже не тестировали это место. Даже не открывали.
2. Форма проводок по расчетам с поставщиками (\Forms\VendTrans)
Связь датасорса VendTrans с дочерним VendTrans_W отображается так
VendTrans_W. == VendTrans. Role: VendTrans
3. Форма складских проводок в управлении запасами (\Forms\InventTrans)
Связь датасорса InventTrans с дочерним InventDim отображается так
InventDim. == InventTrans. Role: InventDim
а с DirPartyTable так
DirPartyTable. == InventTransOrigin. Role: DirPartyTable
Так получается потому, что при разборе запроса класс ядра QueryBuildLink для таких связей почему-то возвращает пустые значения методами
queryBuildLink.relatedField()
queryBuildLink.field()
и непустое методом
queryBuildLink.joinRelation()
(возвращается значение свойства RelatedTableRole для использованной при линке связи. А если оно пустое то значение, которое ядро автоматом генерирует - обычно это имя связанной таблички)
а форма персонализации никак этот факт не обрабатывает.
Не совсем понятно такое поведение класса QueryBuildLink. Зачем скрывать идентификаторы полей. Разработчик должен названия связей что ли помнить ?Ерунда какая-то. Во всяком случае пользоваться этим неудобно. Нужно чтобы было просто - посмотрел запрос на диалоге и все понятно. А так приходится лезть в AOT, чтобы понять как точно идет связь.
Или может я чего-то недопонимаю ?
Пока исправил так
на форме SysSetupForm
добавил метод
X++:
// PKoz 21.05.2024
private boolean fillQueryTreeQueryDsRelation_MRC(
QueryBuildLink _queryBuildLink,
int _treeId,
str _queryBuildLinkNodeText,
boolean _general // по какой табличке перебираем связи
// true - по основной табличке линка (_queryBuildLink.table()),
// false - по связанной табличке линка (_queryBuildLink.relatedTable())
// метод вызывается последовательно для true и для false
)
{
FormTreeItem formTreeItem;
DictTable dictTable;
SysDictRelation dictRelationRelation;
int relationNum;
int relationLine;
tableId relatedTableId;
str linkStr;
int parentTreeId;
str xppRelationName;
container con;
container conRev;
TableId sourceTable = _general ? _queryBuildLink.table() : _queryBuildLink.relatedTable();
TableId relatedTable = _general ? _queryBuildLink.relatedTable() : _queryBuildLink.table();
str relation = _queryBuildLink.joinRelation();
int addParentNode()
{
int ret;
;
// BP deviation documented
formTreeItem = new FormTreeItem(_queryBuildLinkNodeText + strFmt(' [Table.XppRelationName: %1.%2]', dictTable.name(), xppRelationName), imagelist.image(#ImageRelation), -1, null);
ret = queryTree.addItem(_treeId, FormTreeAdd::Last, formTreeItem);
return ret;
}
;
dictTable = new DictTable(sourceTable);
if (!dictTable)
{
return false;
}
dictRelationRelation = new SysDictRelation(dictTable.Id());
for (relationNum = dictTable.relationCnt(); relationNum; relationNum--)
{
relatedTableId = dictRelationRelation.loadNameRelation(dictTable.relation(relationNum));
if (dictRelationRelation.relatedTableRole() == relation)
{
if (relatedTableId == relatedTable)
{
xppRelationName = dictTable.relation(relationNum);
break;
}
}
}
if (!xppRelationName)
{
return false;
}
for (relationLine = dictRelationRelation.lines(); relationLine; relationLine--)
{
linkStr = dictRelationRelation.lineDescription(relationLine);
if (linkStr)
{
if (_general)
{
// метод dictRelationRelation.lineDescription() возвращает нужное нам значение для _general = true, только нужно поменять местами операнды около символа "=="
// меняем их местами :
con = str2con_RU(linkStr, '==');
conRev = con;
conRev = conPoke(conRev, 1, conPeek(con, 2));
conRev = conPoke(conRev, 2, conPeek(con, 1));
linkStr = con2Str(conRev, ' == ');
}
if (dictRelationRelation.lineSubType(relationLine) != RelationshipSubType::Default)
{
// добавляем допинфу по типу связи
linkStr += strFmt(" [LinkSubType = %1]", dictRelationRelation.lineSubType(relationLine));
}
if (!parentTreeId)
{
parentTreeId = addParentNode();
}
// BP deviation documented
formTreeItem = new FormTreeItem(linkStr, imagelist.image(#ImageField), -1, null);
queryTree.addItem(parentTreeId, FormTreeAdd::Last, formTreeItem);
}
}
return true;
}
а в методе fillQueryTreeQueryDatasource
в конце поменять кусок кода
X++:
// Relation
if (queryBuildDataSource.linkCount())
{
formTreeItem = new FormTreeItem('Relation',imagelist.image(#ImageRelations),-1,null);
treeId = queryTree.addItem(sourceRootId,FormTreeAdd::Last,formTreeItem);
for (i = 1; i <= queryBuildDataSource.linkCount(); i++)
{
queryBuildLink = queryBuildDataSource.link(i);
nodeText = this.CalculateNodeTextForRelations(queryBuildLink.table(),
queryBuildLink.relatedTable(),
queryBuildLink.field(),
queryBuildLink.relatedField());
// Add the context of the joinRelation name if it is specified.
// This is for Surrogate Foreign Key scenarios where the fields aren't specified in the link.
if (queryBuildLink.joinRelation())
{
nodeText += ' Role: ' + queryBuildLink.joinRelation();
}
// BP deviation documented
formTreeItem = new FormTreeItem(nodeText,imagelist.image(#ImageRelation),-1,null);
queryTree.addItem(treeId,FormTreeAdd::Last,formTreeItem);
}
}
на такой
X++:
// Relation
if (queryBuildDataSource.linkCount())
{
formTreeItem = new FormTreeItem('Relation',imagelist.image(#ImageRelations),-1,null);
treeId = queryTree.addItem(sourceRootId,FormTreeAdd::Last,formTreeItem);
for (i = 1; i <= queryBuildDataSource.linkCount(); i++)
{
queryBuildLink = queryBuildDataSource.link(i);
nodeText = this.CalculateNodeTextForRelations(queryBuildLink.table(),
queryBuildLink.relatedTable(),
queryBuildLink.field(),
queryBuildLink.relatedField());
// Add the context of the joinRelation name if it is specified.
// This is for Surrogate Foreign Key scenarios where the fields aren't specified in the link.
if (queryBuildLink.joinRelation())
{
// nodeText += ' Role: ' + queryBuildLink.joinRelation();
nodeText += ' Role: ' + queryBuildLink.joinRelation();
}
// BP deviation documented
formTreeItem = new FormTreeItem(nodeText,imagelist.image(#ImageRelation),-1,null);
// PKoz 22.05.2024 -->
if (!(queryBuildLink.joinRelation() &&
(
this.fillQueryTreeQueryDsRelation_MRC(queryBuildLink, treeId, nodeText, false) || // именно в таком порядке, сперва вызов false так как ядро сперва проверяет связи для подчиненной таблицы
this.fillQueryTreeQueryDsRelation_MRC(queryBuildLink, treeId, nodeText, true)
)
)
)
// PKoz 22.05.2024 <--
{
queryTree.addItem(treeId,FormTreeAdd::Last,formTreeItem);
}
}
}