In my case, I want to merge query ranges from Query object to Form Data source. The data source will join to CustTable. The CustTable will be filtered by Query Object TIDCustTable.
public class FormRun extends ObjectRun
{
QueryBuildDatasource qbds3;
Query q3;
QueryRun qRunCustTable;
}
public void init()
{
QueryBuildDatasource qbds1, qbds4;
;
qRunCustTable = new QueryRun(QueryStr(TIDCustTable));
super();
qbds1 = TIDIRTable_ds.query().dataSourceTable(tablenum(TIDIRTable));
qbds4 = SalesTableDS_ds.query().dataSourceTable(tablenum(SalesTable));
qbds4.addLink(fieldnum(TIDIRTable, SalesId), fieldnum(SalesTable, SalesId));
qbds3 = qbds1.addDataSource(tablenum(CustTable));
qbds3.addLink(fieldnum(TIDIRTable, InvoiceAccount), fieldnum(CustTable, AccountNum));
}
When click Select button:
void btnSelect()
{
;
if(qRunCustTable.prompt())
{
q3 = new Query(qRunCustTable.query());
}
}
Process button:
public void btnProcess()
{
QueryBuildDatasource qbds1 = TIDIRTable_ds.query().dataSourceTable(tablenum(TIDIRTable));
QueryBuildDatasource qbds4 = SalesTableDS_ds.query().dataSourceTable(tablenum(SalesTable));
;
if(element.validateProcess())
{
qbds3.clearRanges();
if(qRunCustTable.query().dataSourceTable(tablenum(CustTable)).rangeCount() >0)
element.mergeRanges(TIDIRTable_ds.query(), qRunCustTable.query(), 4);//4 is table number of CustTable in TIDIRTable query
SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, InvoiceDate)).value(SysQuery::range(dtFromDate.dateValue(), dtToDate.dateValue()));
if(txBranch.valueStr())
{
SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, CountryRegionId)).value(SysQuery::value(txCountryRegionId.valueStr()));
SysQuery::findOrCreateRange(qbds1, fieldnum(TIDIRTable, Branch)).value(SysQuery::value(txBranch.valueStr()));
}
else
{
if(qbds1.findRange(fieldnum(TIDIRTable, CountryRegionId)))
qbds1.clearRange(fieldnum(TIDIRTable, CountryRegionId));
if(qbds1.findRange(fieldnum(TIDIRTable, Branch)))
qbds1.clearRange(fieldnum(TIDIRTable, Branch));
}
if(cbSalesStatus.selection() == SalesStatus::None)
{
qbds4.joinMode(JoinMode::OuterJoin);
if(qbds4.findRange(fieldnum(SalesTable, SalesStatus)))
{
qbds4.clearRange(fieldnum(SalesTable, SalesStatus));
}
}
else
{
qbds4.joinMode(JoinMode::InnerJoin);
SysQuery::findOrCreateRange(qbds4, fieldnum(SalesTable, SalesStatus)).value(SysQuery::value(cbSalesStatus.selection()));
}
TIDIRTable_ds.executeQuery();
}
}
Merge method:
public void mergeRanges(Query q,
Query initQ,
int dsNo,
int initQdsNo = 1,
boolean alwaysAddDatasource = false,
boolean addSameFieldRange = true)
{
QueryBuildRange fromQbr;
QueryBuildRange toQbr;
QueryBuildDynalink dyna;
Counter fromI = 1;
//int qdsNo = initQdsNo;
int qdsNo = dsNo;
Counter toI;
tableId tableId;
DictField dictField;
int dictIndex;
int originalId;
void add()
{
q.addDataSource(initQ.dataSourceNo(initQdsNo).file());
qdsNo = q.dataSourceCount();
}
void findToQbr(fieldId id)
{
originalId = id;
id = fieldExt2Id(id);
toQbr = null;
// get table id & dictField
tableId = q.dataSourceNo(qdsNo).table();
dictField = new DictField(tableId,id);
dictIndex = originalId >> 16;
// If this is a dimension field, get range using the array index, otherwise get range with id
if ( ((dictField.arraySize() > 1) && q.dataSourceNo(qdsNo).findRange(fieldId2Ext(id, dictIndex))) ||
((dictField.arraySize() <= 1) && q.dataSourceNo(qdsNo).findRange(id)) )
{
// If same range is found, then next range
if (! addSameFieldRange)
continue;
toI = 1;
while (toI)
{
// is this a Dimension field?
if (dictField.arraySize() > 1)
toQbr = q.dataSourceNo(qdsNo).findRange(fieldId2Ext(id, dictIndex),toI);
else
toQbr = q.dataSourceNo(qdsNo).findRange(id,toI);
if (! toQbr)
break;
// If To value is empty, use it later
if (! toQbr.value())
break;
// If To and From values are equal then add new range later
if (toQbr.value() == fromQbr.value())
break;
toI++;
}
}
if (! toQbr ||
(addSameFieldRange &&
toQbr &&
toQbr.value() &&
fromQbr.value() &&
toQbr.value() != fromQbr.value()
)
)
{
if (dictField.arraySize() > 1)
{
// yes, working with Dimension
toQbr = q.dataSourceNo(qdsNo).addRange(fieldId2Ext(id, dictIndex));
}
else
{
toQbr = q.dataSourceNo(qdsNo).addRange(id);
}
}
}
// Start
if (! initQ)
throw error(strfmt("@SYS23669",funcname()));
if (! initQ.dataSourceNo(initQdsNo))
throw error(strfmt("@SYS23667",funcname()));
if (! q)
throw error(strfmt("@SYS23669",funcname()));
/*
if (q.dataSourceCount() >= initQdsNo)
{
if (q.dataSourceNo(initQdsNo).file() != initQ.dataSourceNo(initQdsNo).file())
{
if (alwaysAddDatasource)
add();
else
throw error(strfmt("@SYS23668",funcname()));
}
}
else
add();
*/
if (! initQ)
return;
for (fromI=1;fromI<=initQ.dataSourceNo(initQdsNo).rangeCount();fromI++)
{
fromQbr = initQ.dataSourceNo(initQdsNo).range(fromI);
findToQbr(fromQbr.field());
if (toQbr)
{
// Only set if From has a value
if (fromQbr.value())
toQbr.value(fromQbr.value());
switch (fromQbr.status())
{
case RangeStatus::Locked:
if (toQbr.status() == RangeStatus::Open)
toQbr.status(RangeStatus::Locked);
break;
case RangeStatus::Hidden:
switch (toQbr.status())
{
case RangeStatus::Open,RangeStatus::Locked:
toQbr.status(RangeStatus::Hidden);
break;
}
break;
}
}
}
fromI = 1;
while (fromI <= initQ.dataSourceNo(initQdsNo).dynalinkCount())
{
dyna = initQ.dataSourceNo(initQdsNo).dynalink(fromI);
findToQbr(dyna.field());
if (toQbr)
toQbr.value(queryValue(dyna.cursor().(dyna.dynamicField())));
fromI++;
}
}