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 |