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"