No artigo de hoje, vou mostrar como chamar uma função com StartJob para atualizar registros.
Imagine um cenário, onde o usuário que está usando o sistema, não tem privilégio para alterar o cadastro, e você precisa fazer a alteração naquele momento via ExecAuto, como fazer?
A forma é simples jovens, basta usar a função StartJob, com ela irá ser criado uma nova thread acionando uma User Function, ai nessa função nós podemos fazer a atualização.
Os parâmetros que a StartJob recebe são:
- 1º Qual é o nome da User Function que será executada (entre aspas)
- 2º Qual é o ambiente que será criado a Thread
- 3º Se irá esperar finalizar (.T.) ou não (.F.)
- 4º em diante, são parâmetros que você pode enviar para sua User Function
Além disso, o Return da função acionada também retorna para o StartJob, então você pode fazer por exemplo um array (no nosso exemplo, será um array de duas posições, a primeira se deu certo ou errado, e a segunda a mensagem).
Uma informação importante, é que não use esse recurso com o SIGAADV, pois ele não irá conseguir acionar o StartJob. Então opte preferencialmente pelo SIGAMDI.
Abaixo o código fonte de exemplo:
//Bibliotecas #Include 'TOTVS.ch' /*/{Protheus.doc} User Function zFuncTST Função que mostra a pergunta se deseja alterar o cadastro @type Function @author Atilio @since 24/06/2021 @version version /*/ User Function zFuncTST() Local aArea := GetArea() Local dDtVencto := Date() Local aRetorno := {.T., ""} //Se a pergunta for confirmada If MsgYesNo("Deseja atualizar a data de fim do contrato?", "Atenção") //Aciona a função de alteraçaõ aRetorno := StartJob("U_zAltFunc", GetEnvServer(), .T., cEmpAnt, cFilAnt, SRA->RA_FILIAL, SRA->RA_MAT, dDtVencto) //Se houve erro, será exibido If aRetorno[1] AutoGrLog(aRetorno[2]) MostraErro() EndIf EndIf RestArea(aArea) Return /*/{Protheus.doc} User Function zAltFunc Função de Execauto para alteração de funcionário @type Function @author Atilio @since 24/06/2021 @version version /*/ User Function zAltFunc(cParEmp, cParFil, cParFilMat, cParMatric, dParVencto) Local aArea Local aRet := {.T., ""} //[1] Houve Falha (.T. = Sim, .F. = Não); [2] Texto de observação Local aDados := {} Local nAux Local aLogAuto := {} Local cLogTxt := "" //Abaixo o usuário e senha que serão usados para realizar a alteração //O ideal aqui é encapsular essa senha em um parâmetro ou txt, para não deixar chumbada no fonte //Deixar chumbado é uma péssima prática, apenas estamos usando para exemplificar, cuidado, não deixe chumbado essas informações! //Aqui poderia ser algo como MemoRead(), GetMV() não daria pois precisa carregar o dicionário primeiro, há não ser que você passe a senha por // parâmetro direto na chamada da user function, por exemplo, cParPass ali após dParVencto Local cUsuario := "UsuarioRH" Local cPass := "Senha123" //Variáveis de controle do ExecAuto Private lMSHelpAuto := .T. Private lAutoErrNoFile := .T. Private lMsErroAuto := .F. //Prepara o ambiente da empresa If Select("SX2") == 0 RpcSetEnv(cParEmp, cParFil, cUsuario, cPass, "GPE") EndIf aArea := GetArea() //Monta o array do Execauto aAdd(aDados, {"RA_FILIAL", cParFilMat, Nil}) //Filial aAdd(aDados, {"RA_MAT", cParMatric, Nil}) //Matrícula aAdd(aDados, {"RA_DTFIMCT", dParVencto, Nil}) //Data do fim do contrato aAdd(aDados, {"RA_VCTOEXP", dParVencto, Nil}) //Data de vencimento de experiência aAdd(aDados, {"RA_VCTEXP2", dParVencto, Nil}) //2ª Data de vencimento de experiência //Executa a alteração do funcionário MSExecAuto({|x, y, k, w| GPEA010(x, y, k, w)}, Nil, Nil, aDados, 4) //Se houve erro If lMsErroAuto //Pegando log do ExecAuto aLogAuto := GetAutoGRLog() //Percorrendo o Log e incrementando o texto For nAux := 1 To Len(aLogAuto) cLogTxt += aLogAuto[nAux] + CRLF Next aRet[1] := .T. aRet[2] := cLogTxt Else aRet[1] := .F. aRet[2] := "Alteração realizada com sucesso!" EndIf RestArea(aArea) Return aRet
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Documentação top.
Exemplo excelente.
Opa, muito obrigado pelo comentário mister Súlivan.
Um grande abraço.
Bom dia Daniel, estou testando este exemplo mas esta dando erro, ele não esta adicionando nada dentro aRetorno
Eu modifique conforme abaixo.
aRetorno := StartJob(“U_zAltFunc”, GetEnvServer(), .T., cEmpAnt, cFilAnt, SE2->E2_FILIAL)
Bom dia, tudo joia?
Certo, dentro da função que é acionada pelo StartJob (no seu trecho zAltFunc), adicione alguns comandos para mapear onde ela esta.
Por exemplo, a cada 5 linhas dentro da zAltFunc, coloque algo +- assim:
—
MemoWrite(“Passei pela linha x”, “\spool\tmp.txt”) //onde o x você vai colocando o número da linha no fonte
—
Feito isso, rode novamente a rotina, e veja dentro da Protheus Data, dentro da pasta spool, esse arquivo tmp.txt em que linha que ele parou.
Dessa forma, vai funilando para encontrar em qual trecho que está ocasionando o erro.
Outra forma também, é abrir o arquivo console.log da pasta AppServer onde você está conectado no VSCode e debugando, e ver onde tem a mensagem de ERROR dentro do arquivo.
Tenha um ótimo e abençoado fim de semana.
Um grande abraço.