Como o nome já diz, QueryRun é o executor de uma query que está associada a ele. Para construir a query que você quer que o QueryRun execute, você precisa configurar as classes:

*Query
*QueryBuildDataSource
*QueryBuildRange
*QueryBuildFieldList
*QueryBuildLink
*QueryBuildDynaLink

O exemplo de hoje usará os quatro primeiros para demonstrar uma query que soma o campo de limite de credito da tabela CustTable agrupado pelo país e pela moeda corrente. Será também mostrado um campo que servirá para contar quantos campos geraram aquele resultado da soma. Ranges são implementados por AccountNum e Country, mas o usuário pode adicionar um novo critério na caixa de dialogo. Para demonstrar o status() eu travei ele, assim o usuário não pode mudar.

QueryRun

QueryRun executa a query, se necessário uma caixa de dialogo pode ser aberta antes da query ser executada. Isto é feito usando o método prompt(). QueryRun herda SysQueryRun e passa a ter um total de 7 métodos prompt*() com diferentes comportamentos, por exemplo: promptAllowAddRange() irá permitir ao usuário adicionar novas condições a query.

Query

Uma query representa o select, aqui é onde todas as strings se juntam.

QueryBuildDataSourceUnsando QueryBuildDataSources você adicionara todas as tabelas que você deseja fazer join (usaremos apenas uma neste exemplo). Aqui é também onde você define como o resultset será ordenado. O método orderMode() permite que seja definido *OrderBy e *GroupBy.

QueryBuildRange

Ranges representam as condições (where). Multiplos ranges são conectados com condições AND e infelizmente não como alterar isso.

QueryBuildFieldList

Representa os campos selecionados da query, por default todos os campos são selecionados. Em queries regulares você provavelmente não irá usá-lo, mas quando quiser agrupar irá usá-lopara definir quais campos serão calculados. SelectionField é um enum com os seguintes valores *Avg, *Count, *Database, *Max, *Min e *Sum.

O resultado da Test_Query no teste feito é o abaixo mostrado:
CA CAD 1120,00 (3 records)
CA USD 500,00 (1 records)
DE EUR 0,00 (1 records)
DK CAD 5000,00 (1 records)
DK EUR 300,00 (6 records)
DK GBP 560,00 (2 records)
ES EUR 0,00 (1 records)
IE EUR 0,00 (1 records)
NL EUR 20,00 (2 records)
NO EUR 3000,00 (1 records)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
static void Test_Query(Args _args) 
{ 
  CustTable custTable; 
  Query query = new Query(); 
  QueryRun qr = new queryRun(query); 
  QueryBuildDataSource qbds = qr.query().addDataSource(tableNum(CustTable)); 
  QueryBuildRange qbrAccN = qbds.addRange(fieldNum(CustTable,AccountNum)); 
  QueryBuildRange qbrCountry = qbds.addRange(fieldNum(CustTable,Country)); 
  QueryBuildFieldList qbfl = qbds.fields(); 
  ; 
  qbrAccN.value('4000..4050'); 
  qbrAccN.status(RangeStatus::Locked); 
  qbrCountry.value('CA..NO'); 
  qbfl.addField(fieldNum(CustTable,CreditMax),SelectionField::Sum); 
  qbfl.addField(fieldnum(CustTable,RecId),SelectionField::Count); 
  qbds.addSortField(fieldnum(CustTable,Country)); 
  qbds.addSortField(fieldNum(CustTable,Currency)); 
  qbds.orderMode(OrderMode::GroupBy); 
  if (qr.prompt()) 
  { 
    while (qr.next()) 
    { 
      custTable = qr.get(tableNum(CustTable)); 
      print strfmt("%1 %2 %3 (%4 records)",custTable.Country,custTable.Currency, 
      num2str(custTable.CreditMax,10,2,0,0),custTable.RecId); 
    } 
  } 
  pause; 
}

Post original.