Источник:
http://alexvoy.blogspot.com/2022/06/...p-dynamic.html
==============
Yes, guys, sometimes they come back!
Fourteen years ago
Vania Kashperuk created a class which became classics:
SysMultiTableLookup. It made possible to create lookups based on multiple tables. Some people are still looking for it in vain among the standard classes. So I decided to create a new version of it for D365FO.
It combines supporting for both
lookup and
lookupReference methods:
performFormLookup and
performFormReferenceLookup.
Vania added a tutorial form to his class, so did I. There is a form in the project, which shows how unbounded form controls can be looked up with fields and display methods from joined tables as well as the case with aggregation and a
CustTable data source to demonstrate a lookup for a reference group.
Take note that I did not implement resolving and have not tested it thoroughly, neither.
Feel free to use it and elaborate at your own risk.
The whole project
tmxSysMultiTableLookup is here in
https://github.com/wojzeh/tmxSystemTools
The only class is here
<div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
///
/// Multi table lookup. D365FO version based on the original by Vanya Kashperuk
/// http://kashperuk.blogspot.com/2008/0...c-lookups.html
///
public class tmxSysMultiTableLookup extends SysTableLookup
{
FormBuildInt64Control recIdSelectModeControl;
boolean isReference;
///
/// Is reference lookup
///
/// boolean
/// True if Reference
protected boolean
parmIsReference(boolean _parm = isReference)
{
isReference = _parm;
return isReference;
}
///
/// Places the specified form into the correct lookup selection mode.
///
///
/// The form to be put into lookup selection mode.
///
protected void setSelectMode(FormRun _formRun)
{
if(isReference)
{
if (!recIdSelectModeControl)
{
throw(error(Error::wrongUseOfFunction(funcname())));
}
_formRun.selectRecordMode(_formRun.control(recIdSelectModeControl.id()));
}
else
{
super(_formRun);
}
}
///
/// Constructs tmxSysMultiTableLookup for a formcontrol with a given query
///
/// Target form Reference group control
/// Query
/// Use input value
/// AmbiguousReferenceResolver
/// Instance of tmxSysMultiTableLookup
static tmxSysMultiTableLookup
newReferenceParameters(FormReferenceControl _callingControl, Query _query, boolean _useLookupValue =
true)
{
tmxSysMultiTableLookup sysTableLookup = tmxSysMultiTableLookup::construct();
if(_query.dataSourceCount() <
1)
{
throw error(@"Query needs to be defined before building the lookup");
}
sysTableLookup.parmIsReference(
true);
sysTableLookup.parmQuery(_query);
sysTableLookup.parmCallingControl(_callingControl);
sysTableLookup.parmUseLookupValue(_useLookupValue);
return sysTableLookup;
}
///
/// Constructs tmxSysMultiTableLookup for a formcontrol with a given query
///
/// Target form control
/// Query
/// Use input value
/// AmbiguousReferenceResolver
/// Instance of tmxSysMultiTableLookup
static tmxSysMultiTableLookup
newParameters(FormControl _callingControl, Query _query, boolean _useLookupValue =
true)
{
tmxSysMultiTableLookup sysTableLookup = tmxSysMultiTableLookup::construct();
if(_query.dataSourceCount() <
1)
{
throw error(@"Query needs to be defined before building the lookup");
}
sysTableLookup.parmQuery(_query);
sysTableLookup.parmCallingControl(_callingControl);
sysTableLookup.parmUseLookupValue(_useLookupValue);
return sysTableLookup;
}
///
/// Instantiates tmxSysMultiTableLookup
///
/// tmxSysMultiTableLookup
static tmxSysMultiTableLookup
construct()
{
return new tmxSysMultiTableLookup();
}
///
/// Adds form control
///
/// Datasource number in the query
/// Field num
/// Return item
/// Method name
/// Label
void addLookupControlMulti(
int _dataSourceNo, fieldId _fieldId, boolean _returnItem, str _methodName, str _label)
{
lookupItems += [[_dataSourceNo, _fieldId, _returnItem, _methodName]];
if (_label)
{
this.setLabel(_label);
}
}
///
/// Adds field as form control
///
/// Method name
/// Datasource number in the query
/// Label
void addLookupMethodMulti(str _methodName,
int _dataSourceNo =
1, str _label ="")
{
this.addLookupControlMulti(_dataSourceNo,
0,
false, _methodName, _label);
}
///
/// Adds field as form control
///
/// Datasource number in the query
/// Field num
/// Return item
/// Label
void addLookupFieldMulti(fieldId _fieldId,
int _dataSourceNo =
1, boolean _returnItem =
false, str _label =
'')
{
if (_dataSourceNo > query.dataSourceCount())
{
throw error(Error::wrongUseOfFunction(funcName()));
}
this.addLookupControlMulti(_dataSourceNo, _fieldId, _returnItem,
'', _label);
}
///
/// Chooses LinkType appropriate to JoinMode
///
/// JoinMode
/// FormLinkType
protected FormLinkType
joinMode2LinkType(JoinMode _joinMode)
{
switch (_joinMode)
{
case JoinMode::InnerJoin:
return FormLinkType::InnerJoin;
case JoinMode::OuterJoin:
return FormLinkType::OuterJoin;
case JoinMode::ExistsJoin:
return FormLinkType::ExistJoin;
case JoinMode::NoExistsJoin:
return FormLinkType::NotExistJoin;
}
throw error(Error::wrongUseOfFunction(funcName()));
}
///
/// Configures the data source of the lookup form.
///
/// FormBuildDataSource
/// QueryBuildDataSource
protected void configureLookupDataSourceMulti(FormBuildDataSource _formBuildDataSource, QueryBuildDataSource _queryBuildDataSource)
{
this.configureLookupDataSource(_formBuildDataSource);
if(_queryBuildDataSource.embedded())
//joined() or level() > 1
{
_formBuildDataSource.linkType(
this.joinMode2LinkType(_queryBuildDataSource.joinMode()));
_formBuildDataSource.joinSource(_queryBuildDataSource.parentDataSource().name());
}
}
///
/// Builds grid form control
///
/// FormBuildGridControl
/// Form
/// FormBuildGridControl
protected FormBuildGridControl
buildGridMulti(FormBuildGridControl _formBuildGridControl, Form _form)
{
FormBuildDataSource formBuildDataSource;
FormBuildControl formBuildControl;
Object obj;
boolean returnItem;
str method;
int fieldId;
int i;
boolean lookupFieldSet =
false;
int dataSourceNo;
fieldId recIdFieldId;
boolean firstDS =
true;
// add fields and display methods for all given data sources
for (i =
1; i
1)
{
throw error("Multiple temporary datasource lookups are not supported");
}
formDataSource.init();
//BP deviation documented
formDataSource.cursor().setTmp();
formDataSource.cursor().setTmpData(tmpBuffer);
}
this.setSelectMode(formRun);
this.buildSelectionListMulti(formDataSource.query());
this.addFilter(formRun);
return formRun;
}
///
/// Creates selection list from a given query
///
/// Query
protected void buildSelectionListMulti(Query _query)
{
boolean returnItem;
str method;
int fieldId;
int i;
int dataSourceNo;
SelectionField
fieldKind()
{
int j;
QueryBuildFieldList qbfl;
qbfl = _query.dataSourceNo(dataSourceNo).fields();
for (j =
1; j