Olá pessoal…
Hoje vou mostrar uma rotina que foi desenvolvida, que ao informar algum conteúdo especial em algum campo, esse conteúdo é retirado (como acentos e outros caracteres).
Primeiramente, quero agradecer ao meu amigo Rafael Achôa, que me ajudou no desenvolvimento da rotina.
Foram desenvolvidas 2 rotinas, a primeira que substitui realmente os caracteres, a u_zLimpaEsp(), que pode ser colocada na validação de usuário de qualquer campo.
A segunda rotina, é uma rotina de atualização de campos, a u_zCarEspec(), que ao mesmo tempo, desabilita o parâmetro MV_ACENTO, e em seguida atualiza vários campos para não aceitar os caracteres especiais (adicionando o u_zLimpaEsp). Essa rotina pode ser executada no Fórmulas.
Abaixo o código fonte desenvolvido.
//Bibliotecas #Include "Protheus.ch" /*/{Protheus.doc} zLimpaEsp Função que limpa os caracteres especiais dentro de um campo @type function @author Atilio / Achoa @since 25/04/2016 @version 1.0 @param lEndereco, Lógico, Define se o campo é endereço (caso sim, o traço e vírgula serão ignorados) @example u_zLimpaEsp() /*/ User Function zLimpaEsp(lEndereco) Local aArea := GetArea() Local cCampo := ReadVar() Local cConteudo := &(cCampo) Local nTamOrig := Len(cConteudo) Default lEndereco := .F. //Retirando caracteres cConteudo := StrTran(cConteudo, "'", "") cConteudo := StrTran(cConteudo, "#", "") cConteudo := StrTran(cConteudo, "%", "") cConteudo := StrTran(cConteudo, "*", "") cConteudo := StrTran(cConteudo, "&", "E") cConteudo := StrTran(cConteudo, ">", "") cConteudo := StrTran(cConteudo, "<", "") cConteudo := StrTran(cConteudo, "!", "") cConteudo := StrTran(cConteudo, "@", "") cConteudo := StrTran(cConteudo, "$", "") cConteudo := StrTran(cConteudo, "(", "") cConteudo := StrTran(cConteudo, ")", "") cConteudo := StrTran(cConteudo, "_", "") cConteudo := StrTran(cConteudo, "=", "") cConteudo := StrTran(cConteudo, "+", "") cConteudo := StrTran(cConteudo, "{", "") cConteudo := StrTran(cConteudo, "}", "") cConteudo := StrTran(cConteudo, "[", "") cConteudo := StrTran(cConteudo, "]", "") cConteudo := StrTran(cConteudo, "/", "") cConteudo := StrTran(cConteudo, "?", "") cConteudo := StrTran(cConteudo, ".", "") cConteudo := StrTran(cConteudo, "\", "") cConteudo := StrTran(cConteudo, "|", "") cConteudo := StrTran(cConteudo, ":", "") cConteudo := StrTran(cConteudo, ";", "") cConteudo := StrTran(cConteudo, '"', '') cConteudo := StrTran(cConteudo, '°', '') cConteudo := StrTran(cConteudo, 'ª', '') //Se não for endereço, retira também o - e a , If !lEndereco cConteudo := StrTran(cConteudo, ",", "") cConteudo := StrTran(cConteudo, "-", "") EndIf //Adicionando os espaços a direita cConteudo := Alltrim(cConteudo) cConteudo += Space(nTamOrig - Len(cConteudo)) //Definindo o conteúdo do campo &(cCampo+" := '"+cConteudo+"' ") RestArea(aArea) Return .T. /*/{Protheus.doc} zCarEspec Script para atualização de campos que terão sua validação de usuário alterada @type function @author Atilio @since 25/04/2016 @version 1.0 /*/ User Function zCarEspec() Local aArea := GetArea() Local aTexto := {} Local aBotoes := {} Local lContinua := .F. //Adicionando textos da rotina aAdd(aTexto, 'Esta rotina tem por objetivo atualizar campos para ') aAdd(aTexto, 'não aceitar caracteres especiais em cadastros.') aAdd(aTexto, '') aAdd(aTexto, 'Será atualizado:') aAdd(aTexto, 'Parâmetro MV_ACENTO') aAdd(aTexto, 'Tabelas SA1, SA2, SA4 e SB1') //Adicionando os botões da rotina aAdd(aBotoes, {1, .T., {|| lContinua := .T., FechaBatch()}}) aAdd(aBotoes, {2, .T., {|| lContinua := .F., FechaBatch()}}) //Mostra o batch esperando interação do usuário FormBatch("Atualização de campos", aTexto, aBotoes) //Se for para continuar o processamento If lContinua Processa({|| fAtualiza()}, "Processando...") EndIf RestArea(aArea) Return /*---------------------------------------------------------------------* | Func: fAtualiza | | Autor: Daniel Atilio | | Data: 25/04/2016 | | Desc: Função que atualiza os dados | *---------------------------------------------------------------------*/ Static Function fAtualiza() Local aAreaX3 := SX3->(GetArea()) Local aCampos := {} Local aCamposEnd := {} Local cValidUsr := "" Local nAtual := 0 DbSelectArea('SX3') SX3->(dbSetOrder(2)) // X3_CAMPO ProcRegua(3) //Campos normais aAdd(aCampos, 'A1_NOME') aAdd(aCampos, 'A1_NREDUZ') aAdd(aCampos, 'A1_BAIRRO') aAdd(aCampos, 'A1_MUN') aAdd(aCampos, 'A2_NOME') aAdd(aCampos, 'A2_NREDUZ') aAdd(aCampos, 'A2_BAIRRO') aAdd(aCampos, 'A2_MUN') aAdd(aCampos, 'A4_NOME') aAdd(aCampos, 'A4_NREDUZ') aAdd(aCampos, 'A4_BAIRRO') aAdd(aCampos, 'B1_DESC') //Campos de endereço aAdd(aCamposEnd, 'A1_END') aAdd(aCamposEnd, 'A2_END') aAdd(aCamposEnd, 'A4_END') //Atualiza o MV_ACENTO para não aceitar acentuação no sistema IncProc("Atualizando parâmetro...") PutMV('MV_ACENTO', 'N') //Percorrendo os campos normais IncProc("Atualizando campos normais...") SX3->(DbGoTop()) For nAtual := 1 To Len(aCampos) //Se conseguir posicionar If SX3->(DbSeek(aCampos[nAtual])) cValidUsr := Alltrim(SX3->X3_VLDUSER) //Se já tiver, pula o campo If "U_ZLIMPAESP" $ Upper(cValidUsr) nAtual++ Loop EndIf //Se tiver conteúdo, adiciona .And. no valid If !Empty(cValidUsr) cValidUsr += ".And." Endif //Definindo a expressão cValidUsr += "u_zLimpaEsp()" //Atualiza no banco RecLock('SX3', .F.) X3_VLDUSER := cValidUsr SX3->(MsUnlock()) EndIf Next //Percorrendo os campos de endereço IncProc("Atualizando campos de endereço...") SX3->(DbGoTop()) For nAtual := 1 To Len(aCamposEnd) //Se conseguir posicionar If SX3->(DbSeek(aCamposEnd[nAtual])) cValidUsr := Alltrim(SX3->X3_VLDUSER) //Se já tiver, pula o campo If "U_ZLIMPAESP" $ Upper(cValidUsr) nAtual++ Loop EndIf //Se tiver conteúdo, adiciona .And. no valid If !Empty(cValidUsr) cValidUsr += ".And." Endif //Definindo a expressão cValidUsr += "u_zLimpaEsp(.T.)" //Atualiza no banco RecLock('SX3', .F.) X3_VLDUSER := cValidUsr SX3->(MsUnlock()) EndIf Next RestArea(aAreaX3) Return
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Top, Atílio!
Funcionando perfeitamente aqui na Jolie Café!
Abraços,
Ahooo Achôa san.
Um grande abraço jovem.
Valew Daniel féra como sempre, o Achôa é gente boa hem… Parabéns pelo post…
Ahooo Robs, valeu brother.
Aquele abraço.
Parabéns Atílio !
Quando se propaga conhecimento, o propagador jamais será esquecido. Continue assim, com esse espírito de compartilhar conhecimento.
Grande Carlos.
Muito obrigado jovem.
Um grande abraço.
Muito top, mas quando coloco na validação do usuario do campo B1_COD, no debug faz corretamente mas salva com espaço, teria algo a mais a ser feito?
Como o cadastro de produto foi para MVC, talvez pode ser por isso.
Tente utilizar a FWFldPut, olhe o exemplo 2 nesse link – https://terminaldeinformacao.com/knowledgebase/fwfldput/
Showwww muito bom, resolvi um problema com as APIs que alguns cadastros tinha caracteres como “” isso quebrava o meu JSON, parabéns por disponibilizar esse conhecimento.
Opa, eu que agradeço pelo comentário jovem.
Grande abraço.
Boa tarde, Alguem em 2022 conseguiu usar o fonte? deu erro na linha 19 no meu
Bom dia Tiago.
Você consegue nos disponibilizar como você testou o fonte? Se foi em um valid de usuário de campo, valid de pergunta, direto em um dialog?
Se possível nos mande um doc do word detalhando o procedimento que fez para testar.
Ficamos no aguardo.
No inicializador de usuário, como eu teria declarar lá para chamar a função?
Bom dia Caio, tudo joia?
No caso, você quer mesmo usar em um Inicializador? Pois só vai ser acionado se o usuário clicar em incluir (campo real) ou nas outras opções se for um campo virtual. Nesse artigo eu explico um pouco sobre o conceito de inicialização dos campos: https://terminaldeinformacao.com/2021/07/07/para-que-serve-e-como-criar-um-ini-padrao-de-campo/
Dito isso, essa rotina de tirar caracteres foi pensada em ser usada na validação do campo (X3_VLDUSER), onde ao usuário preencher uma informação e dar um -enter- ou -tab- automaticamente os caracteres serem alterados. Então para isso, basta você ir no campo e na Validação de Usuário, você colocar a chamada dela: u_zLimpaEsp()
Agora se realmente você tem um cenário de campo Virtual onde você precisa sempre que o usuário clicar em visualizar ou alterar, você fazer essa tratativa, ai você precisaria adaptar a rotina, para que ela não lesse do ReadVar() , mas sim do conteúdo que você esta inicializando.
Ah e se quiser também, no nosso curso de Configurador, nós explicamos sobre Contexto, Inicialização, Validação e Modo de Edição de campos nas aulas 22 a 25 – https://terminaldeinformacao.com/2022/03/14/curso-configurador-sigacfg/
Um grande abraço.