Код написан не мной и написан видимо плохо..
Цитата:
Только мы закончили проход по QueryRun, как начинаем модифицировать его запрос, что бы, по всей вероятности, потом снова запустить. Не знаю каков будет эффект от такого фокуса, т.к. не приходило такого в голову, но вообще это и листинг в целом оставляют впечатление типичного bad design.
Queryrun используется в методе fetch репорта..:
X++:
public boolean fetch()
{
boolean ret;
MapIterator itGroupFinanc;
MapIterator itAccount;
MapIterator itContract;
MapIterator itRecord;
MapIterator itGroupTotal;
if (paymentGroupFinancing && this.queryRun())
this.queryRun().setRecord(paymentGroupFinancing.parmTmpTable());
if(paymentGroupFinancing.parmDocuments() == NoYes::No)
{
TmpGroupFinancingTable_Body.height(0,Units::Char);
if (paymentGroupFinancing.parmTotalContract() == NoYes::No)
{
ContractNameFooter.height(0,Units::Char);
ContractNameHeader.height(0,Units::Char);
}
if (paymentGroupFinancing.parmTotalAccount() == NoYes::No)
{
AccountNameFooter.height(0,Units::Char);
AccountNameHeader.height(0,Units::Char);
}
}
mapGroupTotal = new Map(Types::String,Types::Container);
itGroupFinanc = new MapIterator(mapGroupFinanc);
itGroupFinanc.begin();
while (itGroupFinanc.more())
{
groupFinanc = itGroupFinanc.key();
this.execute(10);
mapAccount = itGroupFinanc.value();
itAccount = new MapIterator(mapAccount);
itAccount.begin();
while (itAccount.more())
{
account = itAccount.key();
this.execute(11);
mapContract = itAccount.value();
itContract = new MapIterator(mapContract);
itContract.begin();
while (itContract.more())
{
contract = itContract.key();
this.execute(12);
mapRecord = itContract.value();
itRecord = new MapIterator(mapRecord);
itRecord.begin();
while (itRecord.more())
{
tmpTable = itRecord.value();
this.send(tmpTable);
itRecord.next();
}
this.execute(22);
itContract.next();
}
this.execute(21);
itAccount.next();
}
this.execute(20);
itGroupFinanc.next();
}
itGroupTotal = new MapIterator(mapGroupTotal);
itGroupTotal.begin();
while (itGroupTotal.more())
{
contract = itGroupTotal.key();
[#ContainerSumsGroup] = itGroupTotal.value();
itGroupTotal.next();
}
this.execute(30);
return true;
}
Привожу код метода run этого класса:
X++:
public void run()
{
rangeDimension = queryRun.query().dataSourceTable(tableNum(CustTrans)).rangeField(fieldId2ext(fieldnum(CustTrans, Dimension),2)).value();
rangeGroupFinanc = queryRun.query().dataSourceTable(tableNum(RContractTable)).rangeField(fieldnum(RContractTable,GroupFinancId)).value();
this.insertTmpFromCustTrans();
this.insertTmpFromCustInvoiceJour();
this.insertTmpFromLedgerJournalTrans();
this.prepareMaps();
super();
}
Т.е. темповая таблица заполняется из Custtrans, CustInvoiceJour, LedgerJournalTrans..
по последним двум кверики проходят быстро..
Убрал заполнении полей, когда в tmptable суммируются незаполненные поля из той же записи.
Теперь выглядит так:
X++:
void insertTmpFromCustTrans()
{
CustTrans qCustTrans;
RContractTable qContractTable,
contractTable;
;
queryRun.query().dataSourceTable(tableNum(CustTrans)).addRange(fieldNum(CustTrans,TransDate)).value(queryRange(dateNull(),datefrom-1));
if (accountNum)
queryRun.query().dataSourceTable(tableNum(CustTrans)).addRange(fieldNum(CustTrans,AccountNum)).value(accountNum);
if (contractAccount)
{
queryRun.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractCode)).value(contractCode);
queryRun.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractAccount)).value(contractAccount);
queryRun.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractPartnerCode)).value(accountNum);
}
while (queryRun.next())
{
qCustTrans = queryRun.get(tableNum(CustTrans));
qContractTable = queryRun.get(tableNum(RContractTable));
if (qCustTrans)
{
tmpTable.clear();
tmpTable.GroupFinancName = GroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
tmpTable.AccountNum = qCustTrans.AccountNum;
tmpTable.AccountName = CustTable::find(qCustTrans.AccountNum).NameAlias;
tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
tmpTable.Voucher = qCustTrans.Voucher;
tmpTable.Advance = NoYes::No;
tmpTable.DebtBeginPeriod = qCustTrans.AmountCur;
tmpTable.insert();
}
}
queryRun.query().addDataSource(tableNum(TmpGroupFinancingTable));
}
Цитата:
Можно привести параметры запуска, т.е. какие из условий запроса действительно подхватываются?
Параметры запуска:
datefrom 01.01.2009, dateto-сегодняшний день, договора отбираются только с нужным нам кодом группы финансирования.
Цитата:
Как много проводок по клиентам у вас в базе?
1,2 млн. записей в custtrans
Цитата:
Что потом происходит с tmpTable ? Насколько критичен параметр Voucher - а, т.е. нет ли в дальнейшем просто группировки скажем по группе финансирования, клиенту, договору и нахождения общей суммы в поле tmpTable.DebtBeginPeriod?
Потом tmptable заполняется данными из CustInvoiceJour и LedgerJournalTrans, после вызывается метод preparemaps:
X++:
private void prepareMaps()
{
str KeyMap;
Int standardSort;
GroupFinancName curGroupFinanc;
Name curAccount;
Name curContract;
;
mapGroupFinanc = new Map(Types::String,Types::Class);
mapAccount = new Map(Types::String,Types::Class);
mapContract = new Map(Types::String,Types::Class);
mapRecord = new Map(Types::Integer,Types::Record);
while select * from tmpTable
order by ContractNumberDate
{
standardSort++;
curGroupFinanc = tmpTable.GroupFinancName;
curAccount = strFmt('@SYS26868', tmpTable.AccountNum, tmpTable.AccountName);
curContract = tmpTable.ContractNumberDate;
if (mapGroupFinanc.exists(curGroupFinanc))
{
mapAccount = mapGroupFinanc.lookup(curGroupFinanc);
if (mapAccount.exists(curAccount))
{
mapContract = mapAccount.lookup(curAccount);
if (mapContract.exists(curContract))
mapRecord.insert(standardSort,tmpTable);
else
{
mapRecord = new Map(Types::Integer,Types::Record);
mapRecord.insert(standardSort,tmpTable);
mapContract.insert(curContract,mapRecord);
}
}
else
{
mapRecord = new Map(Types::Integer,Types::Record);
mapRecord.insert(standardSort,tmpTable);
mapContract = new Map(Types::String,Types::Class);
mapContract.insert(curContract,mapRecord);
mapAccount.insert(curAccount,mapContract);
}
}
else
{
mapRecord = new Map(Types::Integer,Types::Record);
mapContract = new Map(Types::String,Types::Class);
mapAccount = new Map(Types::String,Types::Class);
mapRecord.insert(standardSort,tmpTable);
mapContract.insert(curContract,mapRecord);
mapAccount.insert(curAccount,mapContract);
mapGroupFinanc.insert(curGroupFinanc,mapAccount);
}
}
}