RecCount e LastRec quando aplicar?

Boa tarde. Tudo bem? As funções RECCOUNT() e LASTREC() retornam zero (0) quando executado o trecho abaixo:

cQuery := " SELECT DISTINCT DCZ.DCZ_LOCAL,"

cQuery += " DCZ.DCZ_IDUNIT"

cQuery += " FROM "+RetSqlName('DCZ')+" DCZ"

cQuery += " WHERE DCZ.DCZ_FILIAL = '"+xFilial('DCZ')+"'"

cQuery += " AND DCZ.DCZ_EMBARQ = '"+cEmbarque+"'"

cQuery += " AND DCZ.DCZ_IDUNIT <> '"+Space(TamSX3("DCZ_IDUNIT")[1])+"'"

cQuery += " AND DCZ.DE_L_E_T = ' '"

cQuery := ChangeQuery(cQuery)

cAliasDCZ := GetNextAlias()

dbUseArea(.T.,'TOPCONN',TcGenQry(,,cQuery),cAliasDCZ,.F.,.T.)

Existe alguma particularidade para aplicar a função, por favor? Nunca consegui executar a contagem de registros.

Segue a solução alternativa:

//Contador

While (cAliasQry)->(!Eof())

nContador++

(cAliasQry)->(DbSkip())

EndDo

(cAliasQry)->(DbgoTop())

Obrigado.

Olá,

A função LastRec, que substitui a função RecCount (obsoleta) retorna o ultimo registro de uma tabela.

Porém você está utilizando uma query, logo ela não funcionará.

Você pode ler via um laço todos os registros da query para saber a quantidade ou fazer um count do SQL com o mesmo where para retornar a quantidade de registros.

Documentação: https://tdn.totvs.com/display/tec/LastRec

Sobre o count: https://www.w3schools.com/sql/func_sqlserver_count.asp

Carlos,

Conforme o Daniel informou, a LastRec só funciona para tabelas e não para queries.

Para queries eu uso o comando Count To. Ele irá ler a quantidade de registros retornados e informar o total na variável desejada.

Só atente-se pois após sua execução, a sua query estará no último registro (em EoF), sendo necessário retorná-la para o primeiro registro via DbGoTop.

Segue exemplo:



cQuery := " SELECT DISTINCT DCZ.DCZ_LOCAL,"

cQuery +=        " DCZ.DCZ_IDUNIT"

cQuery +=   " FROM "+RetSqlName('DCZ')+" DCZ"

cQuery +=  " WHERE DCZ.DCZ_FILIAL = '"+xFilial('DCZ')+"'"

cQuery +=    " AND DCZ.DCZ_EMBARQ = '"+cEmbarque+"'"

cQuery +=    " AND DCZ.DCZ_IDUNIT <> '"+Space(TamSX3("DCZ_IDUNIT")[1])+"'"

cQuery +=    " AND DCZ.D_E_L_E_T_ = ' '"

cQuery := ChangeQuery(cQuery)

cAliasDCZ := GetNextAlias()

dbUseArea(.T.,'TOPCONN',TcGenQry(,,cQuery),cAliasDCZ,.F.,.T.)

// conta os registros da query
Count To nContador

// posiciona no primeiro registro
(cAliasDCZ)->(DbGoTop())

Eu aqui particularmente utilizo uma função customizada para fazer isso ao invés do comando Count To, esse comando funciona bem o único porém é que ele força percorrer toda a query, se esta for muito grande pode demorar muito tempo.

Na minha função eu converto a query passada em um formato de count() do sql server, então ele é que faz essa contagem para mim, sem precisar ficar gerando tráfego e assim é muito mais performático. Claro que tem algumas restrições, mas em 90%

Fica mais ou menos assim:


//Monta query para contagem de registros
cQueryTmp    := 'SELECT COUNT(1) QTD_REG '+CRLF+;
                'FROM '+CRLF+;
                '    ( '+CRLF+;
                '    '+cQueryTmp+CRLF+;
                ') QUERY '