Imprimi Página | Fechar janela

Update Com Query

Impresso de: Helpfacil - Portal do conhecimento
Nome do Forum: ADVPL
Descrição do Forum: Dúvidas sobre a programação em ADVPL
URL:http://www.helpfacil.com.br/display_topic_threads.asp?ForumID=1&TopicID=43244
Data da Impressão: sexta-feira, 19 de abril de 2024 at 21:07


Topico: Update Com Query

Postado por: LUCASLOTT
Assunto: Update Com Query
Data Postagem: quinta-feira, 21 de maio de 2020 at 15:33

Boa tarde, sou novo no fórum e em ADVPL. Estamos no primeiro mês de uso do Protheus.

Eu preciso pegar a Data de validade de um produto no caso a que vence primeiro
pois alguns produto tem mais de um lote. Fiz um código que executa uma query
e faz o update através TcSqlExec(), isso funciona perfeitamente, porém a TOTVS
não recomenda fazer dessa forma que se deve fazer diretamente update e insert
no BD, gostaria de saber de saber como eu iria transformar esse fonte para funcionar com Reclock, vi em alguns site, porém não consegui entender direito como eu faria uma query com reclock. Poderiam me ajudar?

Segue fonte que criei:

#INCLUDE "TOTVS.CH"
#include "TOPCONN.CH"

User Function DTVAL()

Local cUpdate

cUpdate := "UPDATE SB1010 SET B1_XVAL = (SELECT "
cUpdate += "(CASE WHEN (COALESCE(SUM(B8_SALDO - B8_EMPENHO), ‘0‘) = ‘0‘) "
cUpdate += "THEN(‘‘) "
cUpdate += "ELSE (FORMAT(CONVERT(DATE,MIN(B8_DTVALID), 103), ‘dd/MM/yyyy‘)) "
cUpdate += "END) "
cUpdate += "FROM SB8010 WHERE "
cUpdate += "B1_COD = B8_PRODUTO AND B1_MSBLQL = ‘2‘ "
cUpdate += "AND B1_TIPO IN (‘PA‘) "
cUpdate += "AND B1_RASTRO = ‘L‘ "
cUpdate += "AND B1_XDESCM not like ‘TERMOTECNICA‘ AND B1_XDESCM not like ‘ATIVO FIXO‘ "     
cUpdate += "AND B1_XDESCM not like ‘GOLDPAC‘ AND B8_LOCAL NOT IN (‘03‘,‘53‘,‘04‘,‘54‘) "
cUpdate += "AND B8_DTVALID > GETDATE() AND SB8010.D_E_L_E_T_ <> ‘*‘)"

TcSqlExec(cUpdate)

Return .T.

Lucas Lott


Respostas:

Postado Por: PIERRY14
Data Postagem: quinta-feira, 21 de maio de 2020 at 16:14

Utiliza essa mesma query, sem o trecho do update.
E executa ela com a função DbUseArea
( http://helpfacil.com/FORUM/display_topic_threads.asp?ForumID=1&TopicID=35746&PagePosition=4 )

Você percorre esse resultado da Query, posiciona na SB1 usando o DbSeek e vai fazendo o RecLock pra alterar o campo que você quer.



Postado Por: LUCASLOTT
Data Postagem: quinta-feira, 21 de maio de 2020 at 19:07

Desculpe vou pedir para que tenha paciência kkkk, como eu faria para percorrer o resultado da Query?

Sobre o DbUseArea fiz dessa forma - DbUseArea(.T.,"TOPCONN",TcGenQry(,,ChangeQuery(cUpdate)),"TMP",.T.,.T.), basicamente copiei e colei alterei a variavel para a minha (arrumei a query para que faça apenas o select como sugeriu acima) o que seria esse TMP?

O que eu li sobre o DbSeek está assim DbSeek("01" + "000000377" + "01",.T.), pelo que entendi, o primeiro numero seria a filial, depois o codigo do cliente por exemplo e depois a loja, ele seria para eu posicionar em um determinado registro correto?

E então eu usaria o RecLock para fazer o update no campo que o DbSeek estaria posicionado?


Lucas Lott



Postado Por: INFOBRENO
Data Postagem: quinta-feira, 21 de maio de 2020 at 19:47

_cQry := " SELECT C1_NUM, C1_EMISSAO, C1_SOLICIT, C1_ITEM, C1_PRODUTO, C1_DESCRI, C1_UM, C1_QUANT, C1_DATPRF, C1_OBS, C1_CC, C1_USER"
_cQry += " FROM "+RetSqlName("SC1")
_cQry += " WHERE C1_NUM = ‘" + Registro + "‘"
_cQry += " AND D_E_L_E_T_<>‘*‘"
TcQuery _cQry New Alias "TSC1"     

          If TSC1->(dbSeek(FWXFilial("SC1"))) //(dbSeek(cFiltra))
               
               RecLock("SC1", .F.) //Trava o registro para alteração , caso queira INCLUIR troque o .F. por .T.
               
                    SC1->C1_DESCRI := TSC1->C1_DESCRI // AQUI VAI O VALOR QUE VOCE QUER GRAVAR NO CAMPO
                    SC1->C1_OBS    := ""              // REPETI AQUI SOMENTE PARA VOCE TER UMA IDEIA PARA CADA CAMPO UMA LINHA COM A VARIAVEL
          
                         
               SE5-> (MsUnLock()) // AQUI VOCE DESTRAVA O REGISTRO CRIADO OU ALTERADO
          Endif     
          

caso ainda tenha duvida me add no skype que dou uma ajuda breno.matupa



Postado Por: INFOBRENO
Data Postagem: quinta-feira, 21 de maio de 2020 at 19:51

para percorrer toda sua query voce utiliza o comando

While (_cAlias)->(!EOF())   // faça enquanto nao for final do resultado

/// comandos

(_cAlias)->(dbskip()) // pula para o proximo registro

enddo





Postado Por: LUCASLOTT
Data Postagem: sexta-feira, 22 de maio de 2020 at 12:01

Bom dia, fiz da seguinte forma!

cUpdate := "SELECT "
cUpdate += "(CASE WHEN (COALESCE(SUM(B8_SALDO - B8_EMPENHO), ‘0‘) = ‘0‘) "
cUpdate += "THEN(‘‘) "
cUpdate += "ELSE (FORMAT(CONVERT(DATE,MIN(B8_DTVALID), 103), ‘dd/MM/yyyy‘)) "
cUpdate += "END)AS ‘DTVAL‘ "
cUpdate += "FROM SB8010 WHERE "
cUpdate += "B1_COD = B8_PRODUTO AND B1_MSBLQL = ‘2‘ "
cUpdate += "AND B1_TIPO IN (‘PA‘) "
cUpdate += "AND B1_RASTRO = ‘L‘ "
cUpdate += "AND B1_XDESCM not like ‘TERMOTECNICA‘ AND B1_XDESCM not like ‘ATIVO FIXO‘ "     
cUpdate += "AND B1_XDESCM not like ‘GOLDPAC‘ AND B8_LOCAL NOT IN (‘03‘,‘53‘,‘04‘,‘54‘) "
cUpdate += "AND B8_DTVALID > GETDATE() AND SB8010.D_E_L_E_T_ <> ‘*‘)"

TcQuery cUpdate New Alias "TSB8"
     
     While (TSB8)->(!EOF())
          If TSB8->(dbSeek(FWXFilial("SB8)))
               RecLock("SB1",.F.)
               SB1->B1_XDTVAL := TSB8->DTVAL
          SB8->(MsUnLock())     
     enddo //While



Postado Por: EMERSON.EN
Data Postagem: sexta-feira, 22 de maio de 2020 at 13:43

quase...
     cUpdate := "SELECT B1.B1_COD PRODUTO, "
     cUpdate += "(CASE WHEN (COALESCE(SUM(B8.B8_SALDO - B8.B8_EMPENHO), 0) = 0) "
     cUpdate += "THEN ‘‘ "
     cUpdate += "ELSE MIN(B8.B8_DTVALID) "
     cUpdate += "END) AS DTVAL "
     cUpdate += "FROM "+RetSQLName("SB1")+" B1 "
     cUpdate += "INNER JOIN "+RetSQLName("SB8")+" B8 ON B8.D_E_L_E_T_ = ‘‘ AND B8.B8_FILIAL = ‘"+FWXFilial("SB8")+"‘ "
     cUpdate += "AND B8.B8_PRODUTO = B1.B1_COD "
     cUpdate += "AND B8.B8_LOCAL NOT IN (‘03‘,‘53‘,‘04‘,‘54‘) "
     cUpdate += "AND B8.B8_DTVALID > CONVERT(VARCHAR(8), GETDATE(), 112) "
     cUpdate += "WHERE B1.D_E_L_E_T_ = ‘‘ AND B1.B1_FILIAL = ‘"+FWXFilial("SB1")+"‘ "
     cUpdate += "AND B1.B1_MSBLQL <> ‘1‘ "
     cUpdate += "AND B1.B1_TIPO IN (‘PA‘) "
     cUpdate += "AND B1.B1_RASTRO = ‘L‘ "
     cUpdate += "AND B1.B1_XDESCM not like ‘ATIVO FIXO‘ "   // like mesmo? geralmente usamos like com ‘%‘
     cUpdate += "AND B1.B1_XDESCM not like ‘TERMOTECNICA‘ " // aparentemente aqui poderia ser ‘=‘ no lugar de ‘like‘
     cUpdate += "AND B1.B1_XDESCM not like ‘GOLDPAC‘ "
     cUpdate += "GROUP BY B1.B1_COD "

     if select("TSB8") > 0 // se a area de trabalho estiver aberta
          TSB8->(dbCloseArea()) // fecha, pra poder abrir novamente com o mesmo nome
     endif
     TcQuery cUpdate New Alias "TSB8"
     TcSetField("TSB8","DTVAL","D",8,0) // indica que o conteudo de DTVAL é uma data.

     SB1->(dbSetOrder(1)) // seleciona a ordem por B1_FILIAL, B1_COD
     While TSB8->(!EOF())
          SB1->(dbSeek(FWXFilial("SB1")+TSB8->PRODUTO)) // procura na tabela de produtos o código que está posicionado na "query"
          if RecLock("SB1",.F.) // tenta travar o registro encontrado
               SB1->B1_XDTVAL := TSB8->DTVAL // substitui a data de validade da tabela de produtos pela da query
               SB1->(MsUnLock()) // destrava a SB1, porque ela é que foi travada
          endif
          TSB8->(dbSkip()) // vai para o próximo registro da "query"
     Enddo //While

     
     TSB8->(dbCloseArea()) // depois de terminar, pode fechar a query
     dbSelectArea("SB1") // e posicionar numa área de trabalho qualquer




Postado Por: LUCASLOTT
Data Postagem: sexta-feira, 22 de maio de 2020 at 17:36

Boa tarde.

Funcionou perfeitamente, apenas alterei do tipo D para C, pois criaram a variavel como caracter tamanho 10, isso não teria como saber pois eu não comentei kkk

Tudo certo agora, obrigado pela atenção de todos.




Imprimir Página | Fechar Janela