Página 1 de 1

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 01 Fev 2020 10:37
por asimoes
Olá Pessoal,

Estou convertendo consultas utilizando BROWSE da HwGui, nessa rotina utilizao um recurso de setas para rolar os registros quando usa as seta de navegação

Seta a direita vai para o próximo registro e faz um refresh() no browse ex.:

APC01->(DbSkip())

Seta a esquerda vai para o registro anterior e faz um refresh() no browse ex.:

APC01->(DbSkip(-1))

Como traduzir isso em uma query SQL?

Nessa consulta tem um campo para o usuário informar o código do cliente, quando ele informa a Grid é atualizada com informações, mas se ele quiser rolar o registro com as setas para frente ou para trás a tela é atualizada com registro de outro cliente, isso funciona assim direto no dbf, agora como simular isso em uma query?

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 01 Fev 2020 12:18
por JoséQuintas
Não se esqueça que, se usa ADO, trata-se de uma tabela ADO:

rs:Move( x )
rs:MoveNext()
rs:MoveFirst()
rs:MoveLast()
rs:MovePrevious()
Rs:AbsolutePosition // algo como RecNo()

E como se trata de um "arquivo temporário", talvez tenha que atualizar.

https://pctoledo.org/forum/viewto ... 43&t=23720

Mas... fica confuso aparecer outro cliente, se não faz parte da Query/Temporário.

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 01 Fev 2020 12:55
por JoséQuintas
O interessante no ADO é que o Absolute Position, apesar de parecer o RecNo(), ele vale pra o que está visível, na ordem em que está visível.
O primeiro da lista é 1, e se aplicar um filtro, ou index, o "novo primeiro" passa a ser o 1.
É como se tudo fosse um array, e está pegando os elementos do array.

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 01 Fev 2020 15:01
por asimoes
JoséQuintas escreveu:Não se esqueça que, se usa ADO, trata-se de uma tabela ADO:
Sim é ADO, nesse caso vou ter que carregar toda a tabela e trabalhar em cima do resultset.

O código do cliente é um caracter de 5.

Pensando uma coisa maluca aqui.

No GET o usuário digita o código 20735

SELECT APC.CODIGO, APC.NOME FROM APC01 APC WHERE APC.CODIGO = ?"

oPrm := oCommand:CreateParameter("0'", adVarChar, adParamInput, 5, cCodigo)
oCommand:Parameters:Append( oPrm )

O resultset pode ser true (achou) ou false (não achou)

Se achou, mostra os dados do cliente e faz outro select em outra tabela que contém dados de cobrança, a chave é código.

Se o usuário resolve mover para outro cliente seta para direita, posso fazer um cCodigo := StrZero( Val( cCodigo ) + 1, 5 ) e refazer o select do cliente, até achar o próximo quando o resultset for true ( tipo softweek on )

Código: Selecionar todos

cSql := "SELECT APC.CODIGO, APC.NOME, APC.CLASSE_PG, APC.CATEGORIA, APC.D_FALECI "
cSQL += "FROM APC01 APC "
cSQL += "WHERE APC.CODIGO = ? "
cSQL += "ORDER BY APC.CODIGO"
   
   cCodigo := "20735"
   
   lAchou  := .F.
   
   DO WHILE ! lAchou //Tenta achar 
      oPrm := oCommand:CreateParameter(StrZero(nLoop,2), adVarChar, adParamInput, 5, cCodigo )
              oCommand:Parameters:Append( oPrm )   
              oCommand:CommandText := cSql
              oCommand:CommandType := adCmdText
       oRs := oCommand:Execute()
       lAchou := ! oRs:Eof
       IF lAchou
          hwg_MsgInfo( oRs:Fields( 0 ):Value + " " + oRs:Fields( 1 ):Value )
          Exit // Sai para fazer outro select para atualizar a grid (browse)
       ELSE
          cCodigo := StrZero( Val( cCodigo ) + 1, 5 )
       ENDIF   
       oCommand := Nil
       AbreCommand( @oCommand ) // Tem que recarregar o objeto command se não dá crash
   ENDDO

FUNCTION AbreCommand( oCommand )

   WITH OBJECT oCommand := Win_OleCreateObject( "ADODB.Command" ) 
      :ActiveConnection := oConexao
   END
   
RETURN Nil

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 02 Fev 2020 11:59
por asimoes
Consegui,

Agora a rotina está com 90% com consulta Sql

O Browse(grid)

Código: Selecionar todos

METHOD Proximo()
LOCAL oRecordSet := "", cErro := "", aDados := {}, aChave, oElemento, cCodigo

   cQuery := "SELECT APC.CODIGO, APC.NOME, APC.CLASSE_PG, APC.CATEGORIA, APC.D_FALECI, APC.UTI "
   cQuery += "FROM APC01 APC "
   cQuery += "WHERE "
   cQuery += "APC.CODIGO = ? AND "
   cQuery += "APC.UTI = ? "
   cQuery += "ORDER BY APC.CODIGO"
   
   cCodigo := StrZero( Val( ThisForm:oCodigo:VarGet() ) + 1, 5 ) 
    
   aChave := { cCodigo, "S" }
   
   IF ! Empty( ThisForm:oCodigo:VarGet() )
      
      oGuiProc:WriteStatusPanel( Thisform, "oStatus", 1, "Localizando registro, Aguarde..." )
      
      oConexao:AdoSelect( @::oRecordSet, @aDados, cQuery, aChave, 1, @cErro, , "PA040300->Proximo" )
      
      DO WHILE ::oRecordSet:Eof
         oGuiProc:WriteStatusPanel( Thisform, "oStatus", 1, "Localizando registro, Aguarde..." )
         cCodigo := StrZero( Val( cCodigo ) + 1, 5 ) 
         aChave := { cCodigo, "S" }
         oConexao:AdoSelect( @::oRecordSet, @aDados, cQuery, aChave, 1, @cErro, , "PA040300->Proximo" )
         oClPF:DoEvents()
      ENDDO
      
      oGuiProc:WriteStatusPanel( Thisform, "oStatus", 1, "" )
      
      lValid := APA41->( DbSeek( ::oRecordSet:Fields( "CODIGO" ):Value ) )
      
      IF lValid
         ThisForm:oCodigo:VarPut( ::oRecordSet:Fields( "CODIGO" ):Value )
         ThisForm:oCodigo:Refresh()
         ::SetArray()
         ::cCodigo := ThisForm:oCodigo:VarGet()
         ::SetGet()
         ThisForm:oCodigo:SetFocus()
      ENDIF
   ENDIF     
      
RETURN Nil

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 02 Fev 2020 12:09
por JoséQuintas
Código atual é 5

anterior: SELECT CODIGO FROM TABELA WHERE CODIGO < 5 ORDER BY CODIGO DESC LIMIT 1
próximo: SELECT CODIGO FROM TABELA WHERE CODIGO > 5 ORDER BY CODIGO LIMIT 1

APC01->(DbSkip()) E APC01->(DbSkip(-1)) como fazer em SQL?

Enviado: 02 Fev 2020 14:11
por asimoes
Boa Quintas,

Muito bom!, funcionou a sua dica

Como ainda estou usando o ADS, o limit 1 não funcionou, mas top 1 sim

cSQL := "SELECT top 1 APC.CODIGO FROM APC01 APC WHERE APC.CODIGO < '00630' AND APC.UTI = 'S' ORDER BY APC.CODIGO DESC"