Olá! Hoje vamos abordar um assunto recorrente nos e-mails de dúvidas que recebemos dos nossos leitores: como passar parâmetros em agendamentos no Protheus.
Vamos retomar o exemplo utilizado no artigo anterior sobre o tema Agendamentos e expandir o material com um vídeo detalhado com a execução de um exemplo. Caso não tenha lido o artigo anterior ou nunca realizou um agendamento no TOTVS Protheus anteriormente, veja o artigo no link abaixo:
Além de focar em um assunto de dúvidas, esse artigo também é especial por outro motivo: é o nosso quinquagésimo artigo. Ou seja, a AcademiaERP já conta com 50 artigos de conteúdos variados sobre o sistema TOTVS Protheus. Estamos preparando alguns conteúdos especiais para celebrar esse número. Aguardem novidades!
Fonte de Exemplo
Para começar o nosso estudo, vamos resgatar o mesmo fonte utilizado no primeiro artigo sobre agendamentos de tarefas:
#INCLUDE "Protheus.ch" #INCLUDE "TbiConn.ch" User Function XTESTE(aXEmpFil) DEFAULT aXEmpFil := {"99","01"} //PREPARE ENVIRONMENT EMPRESA aXEmpFil[1] FILIAL aXEmpFil[2] FUNNAME FunName() TABLES "SM0" ConOut("FUNCIONOU!") //RESET ENVIRONMENT Return .T.
Vamos aproveitar a estrutura desse programa e alterá-lo para recebermos mais alguns parâmetros:
#INCLUDE "Protheus.ch" #INCLUDE "TbiConn.ch" User Function XTESTE(aParametros) DEFAULT aParametros := {"99","01","FUNCIONOU!"} //PREPARE ENVIRONMENT EMPRESA aParametros[1] FILIAL aParametros[2] FUNNAME FunName() TABLES "SM0" ConOut(aParametros[3]) //RESET ENVIRONMENT Return .T.
Dessa forma, além de enviar a Empresa e Filial para a rotina agendada, enviaremos também as variáveis que serão utilizadas internamente na função.
Como passar parâmetros no Agendamento:
Com base nesse programa simples de impressão do conteúdo, vamos realizar as alterações necessárias para recebermos parâmetros na assinatura da função. Mas antes, vamos alterar o agendamento da rotina:
A única mudança no agendamento é que estamos passando parâmetros diretamente na chamada da função, no campo Rotina*: os parâmetros estão separados com vírgula e são três variáveis com conteúdo texto. Ao deixar o agendamento ser executado, percebemos que o texto é impresso corretamente no console:
Como receber esses parâmetros na sua rotina:
Para receber os parâmetros em uma rotina agendada é muito simples e, ao mesmo tempo, um pouco estranho O.ô . Enviamos os parâmetros na chamada da função durante o cadastro do agendamento porém, dentro da rotina, definimos que esses valores virão através de um array. Podemos ver isso na assinatura da função abaixo:
User Function XTESTE(aParametros)
Dessa forma, quando enviamos os valores:
U_XTESTE("99","01","NOVA VERSAO")
A nossa função irá receber:
aParametros[1] := "99" aParametros[2] := "01" aParametros[3] :="NOVA VERSAO"
Ou seja, quando trabalhamos com tarefas agendadas, podemos enviar a quantidade necessária de valores para a utilização dentro do nosso código. Isso é muito importante não só para definirmos como a nossa rotina irá se comportar em cada agendamento (passar datas para filtros, opções de execução, códigos de registros da base de dados para buscas…) mas também para fazer a carga completa do ambiente do TOTVS Protheus para habilitar determinadas funções.
Perceba que, quando entramos pelo TOTVS Smartclient, logo após a tela de Autenticação do Usuário, parametrizamos o ambiente definindo Database, Unidade de Negócio, Empresa, Filial e Módulo:
Com essas informações, o TOTVS Protheus inicializa algumas variáveis públicas do sistema, além de abrir as tabelas de dicionários de dados para a empresa e filial selecionadas. Essa operação é chamada de Preparação do Ambiente e todas as rotinas abertas após esse processo (através do menu por exemplo) se utilizam das configurações feitas anteriormente para trabalhar com os dados do sistema.
Quando executamos uma rotina agendada, por não haver a possibilidade de exibição de uma tela de login, encaramos algumas restrições:
1- Não utilizar telas em nossa rotina: embora seja possível criar rotinas que possam exibir telas de mensagem mesmo sem passar pela tela de autenticação, não existe vantagem alguma em criar um agendamento de rotina se vamos esperar uma ação do usuário. Perde o sentido!
2- Como não temos autenticação do usuário, não temos o processo de Preparação do Ambiente e isso gera efeitos diversos em nossas rotinas. Desde reparar que, internamente, algumas das funções utilizam o dicionário de dados internamente até não podermos acessar as tabelas do sistema corretamente. Para corrigir esse problema, podemos preparar o ambiente utilizando a diretiva Prepare Environment/Reset Environment:
PREPARE ENVIRONMENT EMPRESA aXEmpFil[1] FILIAL aXEmpFil[2] FUNNAME FunName() TABLES "SM0" //Qualquer comando que for colocado aqui dentro, será executado dentro dessa configuração de ambiente RESET ENVIRONMENT
Esse comando recebe como parâmetros qual empresa, qual filial, o nome da função que está em execução (que pode ser recuperado através da função FunName() ) e quais as tabelas que serão abertas. Após a execução desse comando, utilizamos o comando Reset Environment para encerrar a execução desse ambiente.
Assim como enviamos o texto que será impresso no console, enviamos também, nos dois primeiros parâmetros, a empresa e a filial que será aberta:
U_XTESTE("99","01","NOVA VERSAO")
Dessa forma, podemos criar agendamentos diferentes para cada empresa / filial do sistema. Ainda, poderíamos enviar outros parâmetros que influenciariam na execução da rotina:
//Exemplo da chamada da rotina no cadastro de agendamento //U_XTESTE("99","01",1) #INCLUDE "Protheus.ch" #INCLUDE "TbiConn.ch" User Function XTESTE(aParametros) DEFAULT aParametros := {"99","01","FUNCIONOU!"} PREPARE ENVIRONMENT EMPRESA aParametros[1] FILIAL aParametros[2] FUNNAME FunName() TABLES "SM0" If aParametros[3]==1 ConOut("NOVA VERSAO") Else ConOut("FUNCIONOU!") EndIf RESET ENVIRONMENT Return .T.
Conclusão
Conforme mencionamos anteriormente, existem diversas aplicações úteis para rotinas agendadas e poder passar parâmetros para elas permite que você crie uma única rotina que irá se adequar a diferentes situações. Abaixo seguem alguns exemplos comuns de rotinas que podem ser desenvolvidas dessa forma:
- Envio de e-mails de cobrança para clientes;
- Atualização de registros em tabelas no sistema a partir de arquivos de dados disponibilizados em um diretório do servidor;
- Envio de relatórios de faturamento da empresa;
- Avisos de Orçamentos/Pedidos/Chamados/Contratos/etc pendentes de aprovação;
- Carga e expurgo de dados em tabelas temporárias
- …
São diversas aplicações e, como você já pode ter imaginado, para cada uma delas você pode aplicar parâmetros de data, código de registro na tabela, código de usuário, flags, etc. Abaixo segue um vídeo de exemplo do artigo:
OBS: se você está atrás de maiores informações sobre como utilizar a função SchedDef(), dê uma olhada no vídeo no Youtube 🙂
Se gostaram do artigo, aproveite pra dar uma nota no conteúdo e, se ficaram com alguma dúvida, basta deixar um comentário abaixo.
Ótimo artigo Vinícius! Obrigado por compartilhar!
Também mantenho um blog sobre o Protheus e sei como é trabalhoso ficar fazendo posts regurlarmente, trabalhão 🙂 Mas é bem legal 🙂
Vlw Vinícius! Até mais!
George
http://www.userfunction.com.br
Vinícius, boa tarde!
Excelente artigo, só uma duvida eu tenho a necessidade de agendar a rotina de Lotes de Cobrança, seria possível realizar o agendamento da mesma?
Forte Abraço
Boa tarde Ted!
Teoricamente, sim. Não conheço especificamente o código dessa rotina para dizer se ela já foi feita pensando em ser utilizada como agendament. Porém, sempre podemos criar uma rotina personalizada ou tratar a rotina com pontos de entrada para que ela possa ser utilizada assim. É necessário pesquisar e analisar o fonte da rotina para identificar como proceder 😉
Abraços