Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Técnicas y Procedimentos
ÍNDICE ANALÍTICO
Creacion de Variables.................................................................................................8
la Declaracion........................................................................................................8
el Tipo de Variables................................................................................................8
Tipos Existentes.....................................................................................................8
Inicializacion..........................................................................................................9
Estandarizacion de Variables...................................................................................9
Creando una Variable Utilizando la Funcion CRIAVAR()..........................................10
Variables de Reportes...........................................................................................10
Otros cuidados.........................................................................................................15
Confrontando reportes y e consultas......................................................................15
Problemas con Looping de Programas....................................................................16
Manipulacion de Archivos Externos al Protheus......................................................17
Desarrollando Pantallas.........................................................................................18
Salvando Array’s standares...................................................................................19
Pontos de Entrada....................................................................................................20
Objetivo dos Pontos de Entrada.............................................................................20
Quando crear un Ponto de Entrada........................................................................20
Procedimentos para sua criación............................................................................21
Contabilizando.........................................................................................................22
La Funcion HeadProva..........................................................................................22
La funcion DetProva()...........................................................................................22
La funcion RodaProva().........................................................................................23
Actualizando SX (ATUSX)..........................................................................................24
Ejemplo de actualizacion en SX:...........................................................................24
Índices....................................................................................................................30
Creando y Borrando Archivos de trabajo (Temporales)..........................................30
Utilizando Querys en Protheus..............................................................................30
Notas Importantes - DBF contra SQL.....................................................................31
Control de Semáforo................................................................................................37
Existe un provervio chino que dice: “El Hombre no tropieza en montañas, tropieza en piedras,
arena, pequeños hoyos, pero nunca en una montaña”.
Esto nos pone a pensar que donde fallamos es exactamente en lo simple, en aquellos detalles
casi empreseptibles y que tienen un valor muy grande para todo. Avalemos del punto de vista
hunano; será tan difícil complacer a todos, seanos mas amigos, mas serenos a las decisiones y
compañeros unos de otros y trabajamos en equipo? Por que muchas veces no lo hacemos? Por
que insistimos en el individualismo y en el mal-hunor? No seria mas fácil, y hasta óbvio, estar
de buen hunor y dispuestos a trabajar en equipo, intercambiar conocimiento y discutir las
decisiones, pensar mas en todo sin que importen las partes que lo componen?
Seria mas interesante si al caminar por un parque, prestasemos mas atencion en los arboles, en
el camino, en las flores, el canto de los pajaros sin olvidar el objetivo del pase, sin perder la
nocion del tiempo y distancia, pero disfrutando mucho el paisaje, el detalle.
Ahora vamos trazar un paralelo con nuestro dia a dia. No seria mejor al reservarmos un fuente,
verificarlos com mas atencion:
Las condicionales? Finalmente muchas veces no probamos un ELSE.
Los filtros? Generalmente olvidamos intentar optimizar la ejecucion en SQL.
Los mensajes? Finalmente es tan comun encontrarnos con textos completamente sin sentido.
Las ayudas? Damos poca atencion a ellas y nos olvidamos que es la primera cosa que el usuario
toca.
Imaginen algunas ligas menos por causa de una simple docunentacion mas! Aquel punto de
entrada que creamos y no pensamos en los supuestos parametros que nuestro personal en
campo puede querer, o en el retorno mas adecuado para aquella funcion.
Recuerden tambien la docunentacion del nuevo campo; Ella realmente es necesária? Si la llave
del índice és imprescindíble, por que no creo un query? Al responder un BOPS, no seria mejor
que fuese su última argunentacion para el problema? Se esto quedar claro y bien resuelto no
tendremos mas aquella ocurrencia o duda. Se tuvieramos que explicar un proceso para alguien,
que lo hacemos de tal forma que no generamos incognitas.
Por que en vez de enfocar nuestro esfuerzos para “ matar” los BOPS, no valiadamos el fuente
para evitarmos NUEVOS BOPS? Al resolver una ocurrencia recuerde todos los puntos de
aplicacion de su actividad. Lo que eso ira a impactar en el servicio de otro? Sin hablar en
documentar en el Quark!
Vamos a traer el comportamiento del parque para nuestro trabajo también. Al programar vamos
atender a los detalles, seanos mas criticos, pensemos que aquella instrucción mas, significa
mucho para el sistema y que mas delante si se trata con descuido puede causar problemas.
Este convencido que, si actuamos de manera mas enfocada a nuestros propositos, el paseo o
mejor la programación, sera mucho mas entusiasta, productiva y con un margen de error menor.
Con ese comportamiento quienes ganan somos nosotros; Microsiga!. Solo asi tendremos mas
tiempo de irnos al parque en el fin de semana.
En fin, quiere una prueba de trabajo en equipo con un alto nivel de calidad y detalles; este
manuel, que fue construido en solo 2 dias, con una colaboracion de mas de 20 personas,
concentradas en sus objetivos, atendiendo cada uno con su tema. El Resultado? Un trabajo
excelente, un documento para ayudar a ser mejores y no equivocarnos en lo fácil!
De acuerdo con esta definicion, se pretende utilizar nuestro bien mas precioso en nuestro
trabajo, vamos a necesitar desarrollar algunos habitos:
Hacer un levantamiento de los programas que sufriran las consecuencias de las alteraciones
realizadas. Todos esos programas deberan ser probados junto con el programa alterado.
Antes de crear una funcion, consulte el Help Microsiga o los colegas de trabajo, pues esta funcion
yá puede haber sido creada.
Al crear una función, verifique de que en el encabezado haya informacion básica como:
descripcion dde la funcion, sintaxis, definicion de los parametros y autor. És comun al desarrollar
una funcion, utilizar otra yá lista como ejemplo, y este momento el “c opiar/pegar” nos hace
olvidar alterar estas informaciones.
Al realizar las pruebas, defina critérios. Antes de comenzar defina a donde quiere llegar. No basta
hacer sus alteraciones. El hecho de que sus alteraciones esten funcionando como lo preve, Esto
no garantiza la inexistencia de errores.
No limite la prueba de su alteracion en base a lo que utilizo durante el desarrollo, pues usted
creo el ambiente perfecto para que funcione.
Puede parecer un poco laborioso pasar por estos procesos en el reocrrido del desarrollo de el
sistema, pero si medidas como esta no fueron tomadas, lo que era extremadamente simple se
tornara extremadamente laborioso.
Que profesional no se ha topado con un codigo fuente que parezca estar escrito en otro dialecto
igual con todo el conocimiento adquirido en aquel lenguaje, este hecho generalmente ocurre por
la mala utilizacion de sintaxis compleja que no siempre significa un buen funcionamiento del
sistema.
Un profesional del área de informática no puso ningun modelo estandard para desarrollar sus
algoritmos, por eso es necesario la aplicación de etica profesional para que se puedan desarollar
algoritmos de manera simple y correcta, este concepto se basa en los siguientes aspectos :
Existen algunos errores que con un poco de atención, pueden ser evitados, tales como:
Verifique si la variáble está declarada antes de uso;
Al declarar una variáble, verifique cual es la necessidad de tener esa variable y cual el tipo de su
clase;
Classifique las funciones y los procedimentos conforme a necesidades, como por exemplo, la
declaracion de un array, defina o seu tamaño e no uso verifique se o elemento existe;
Salve a ordem e a área e o registro do archivo que será utilizadopara que no final do processo se
recupere estes valores;
Evite retornar da función antes de su final, o sea, cree preferencialmente un único retorno;
Valide simpre o retorno de punto de entrada;
Cuando por grabar un archivo que utiliza campos de otros archivos, posicione todos los archivos
e registros antes de iniciar a grabación,y describa o alias de campo;
Utilize de archivo CH las strings para localización;
Cuando posíbel utilize el lenguaje SQL, pues minimiza el tiempo de execución en muchos
procesos.
Todos sabienos o cuanto es difícil elaborar e manter una docunentación técnica actualizada,
ainda mas aqui na Microsiga, cuya dinâmica dos acontecimentos muchas veces impide
que eso sea viabilizado. Diante desse cenário, o que nos resta? Obviamente que pelo
menos los programas sean docunentados, bien docunentados.
Docunentar bien, no significa que tengamos que escribir decenas de lineas de comentários a
cada linea de código. Significa que los comentários tieden a pasar alguna información relevante.
Vemos comentários asi: “compara A con B” esó. es lo óbvio, la lectura de código que nos dice
eso. la docunentación debe se ater a conceitos, por exemplo: “Se A es mayor que B, el archivo
de saldos será actualizado, caso contrário el registro será regresado para que el saldo no
apaersca negativo.”. Esto si transmite alguna información.
Tambien se puede utilizar ese recurso para hacer lembretes a pasos importantes que, se formen
dederivados de lado, Pueden comprometer el funcionamento de las rutinas.
Por exemplo: “Al accionar esta función, o archivo XXX DEBE estar posicionado en el índice 1”.
No IDE do PROTHEUS existem opciones bastante interessantes para nos auxiliar nessa tarefa.
Experimente as opciones Inserir, Docunentación de cabeçalho e Inserir, Docunentación de
Explicación.
Existe ainda un tipo de docunentación que nem sempre é observada, é aquela inerente ao
próprio código. Programas cuyas variáveis são declaradas como nX, cVAR1, dAUX, nNUN, etc.,
são extremamente difíceis de entender e pior, manter. É conveniente que os nomes das variáveis
retratem seu uso ou destino. Por exemplo: dDataDeS ou dDataDeE. Segundo as convenciones da
Microsiga, variáveis do tipo DATA devem ser iniciadas pela letra “d”. Assim “Data”, no acrescenta
nada ao entendimento do que a variável representa. Nos sobrou o “dES” e o “dEE” para informar
para que diados serve a bendita variável. Será salida, solución, saldo? Entrada, Estorno,
Estoque? Que tal isso: dSeguro e dEntrega?
Enfim, como fue dito, no é preciso escrever un livro a cada programa, basta ser objetivo e se
colocar na posición de quem no coñece o programa tão pouco o assunto. Algun dia você mesmo
poderá estar nessa posición.
O cabeçalho do programa é utilizado para identificar informaciones gerais sobre a rotina, seu
autor, data, entre outras informaciones. É importante que esteja preenchida de forma correta e
atualizada. Lembre-se de que nada adianta un cabeçalho que no informe nada ou pior ainda,
com informaciones errôneas.
Lembre-se que un bom livro começa com un bom prefácio, e un bom programa começa com un
cabeçalho útil e legível.
CRIACIÓN DE VARIÁVEIS
A declaración
O tipo de variável
A función CRIAVAR()
A inicialización
Padronización de variáveis
A Declaración
Deve ser feita sempre no início da rotina que for utilizá-la, como no exemplo:
Function a910VerCod()
Return
O Tipo de Variável
O tipo de variável serve para identificar a utilización que a misma terá no decorrer da rotina.
Toda variável deve estar tipada durante sua criación. Quando programamos nativamente em “C”,
Esto se torna obrigatório. Devemos fazer o mesmo no AP5, pues Esto demonstra que a variável
fue conscientemente declarada.
Tipos Existentes
PUBLIC: Esta variável será inicializada em un valor lógico falso (.F.) até que sea atribuído un
valor específico a ela. Esta variável permanece definida por toda a duración da aplicación e pode
ser vista (assim como usada, alterada e avaliada) por qualquer función. Esta variável gera un
token (indicación) na tabela de símbolos, Esto significa que o módulo principal conterá símbolos
para esta classe de variável, o que, por sua vez, ocupa mas espaço de memória. Deve-se evitar a
utilización deste tipo, a no ser em casos extremos.
PRIVATE: Esta variável será inicializada em valor nulo (NIL) e una vez declarada, permanecerá
assim durante toda a duración do fluxo da función, até que este volte ao procedimento inicial que
a chamou. Em essência, una variável de memória PRIVATE inicializada logo no início do Protheus,
agirá como un variável PUBLIC. Esta variável pode ser vista por una sub-rotina da función e
modificada de maneira correspondente. Esta variável também gera un token na tabela de
símbolos comentada acima.
LOCAL: Esta variável de memória será inicializada com valor nulo (NIL) e só é visível dentro da
función que a inicializa, mesmo que esta última, conteña funciones incorporadas a seu conteúdo.
Este tipo de variável é o mas adequado a ser utilizado em funciones, pues no gera símbolos na
tabela de símbolos, por conseqüência ocupa pouco espaço de memória e, o compilador avalia as
variáveis LOCAL e STATIC mas rapidamente que os otros tipos (PUBLIC e PRIVATE). Cuidado
para no sucunbir à teoria de que se pode obter economia de memória, mudando qualquer
referência PRIVATE para una referência LOCAL. Se você fizer isso, as funciones Pueden no
funcionar corretamente, embora funcionassem na versão anterior às alteraciones.
STATIC: A variável STATIC é idêntica à classe de armazenamento LOCAL, com una exceción.
Una variável STATIC é retida dentro de sua sub-rotina, mesmo depues que o fluxo da función a
teña deixado. Esto é particularmente útil para funciones independentes tipo “ caixa-preta”, que
contém seu próprio conjunto de variáveis exclusivas e devem manter esses valores de interación
em interación.
Inicialización
Quando no atribuímos neñun valor a una variável no momento de sua declaración, corremos o
risco de utilizá-la com valor “NIL” e causar erros fatales. Por isso, a inicialización de una variável
é de extrema importância.
Padronización de Variáveis
É importante que ao lermos o nome de una variável, possamos saber se o seu tipo é nunérico,
caracter, data ou lógico. O nome da variável de get no deve coincidir com una variável de outro
programa, pues toda variável de get possui un help específico.
Exemplo:
a variável DBaixa (get da baixa no programa de Títulos a Receber), já possui un texto help que
indica seu conteudo e no deverá ser criada outra variável para outra finalidade com este mesmo
nome.
N Nunéricas
L Lógicas
D Data
C Caracter
A Array (matriz)
O Objeto
U Sem definición
Esta función cria una variável, retornando o valor do campo, de acordo com o dicionário de
dados. Avalia o inicializador padrão e retorna o conteúdo de acordo com o tipo de dado definido
no dicionário.
Sintaxe
uRet := CriaVar(cCampo,lIniPad,cLado)
Onde :
Variáveis de Relatórios
Na criación de un relatório algunas variáveis e seus tipos são convencionados para a utilización
da biblioteca de funciones de relatório.
Como no mesmo archivo de dados, poderemos ter registros de várias filiais, desta forma ficará
garantido o posicionamento no primeiro registro da filial corrente.
If ! SB1->(dbSeek(xFilial("SB1")))
// No achei o registro
Endif
Mesmo que sea óbvio a existência do registro, faça o teste pues o programa deve prever que a
base de dados no é tão confiável como deveria, e un alerta ajuda a identificar estes casos. Em
casos de relatórios, atentar-se para imprimir a mensagem de forma consciente.
Se for executada a función RECLOCK(cAlias, .F.), para alteración del registro actual, en un
archivo no estado de EOF() (caso falhe un DBSEEK() ) será abortado o programa e gravado un
archivo texto de nombre MSRLOCK.EOF que podrá ser usado para averiguaciones.
El comando SOFTSEEK determina si será usada una busca relativa durante un procedimiento en
un banco de dados. Se este comando estiver em ON, e for utilizada una función DBSEEK(), e neñ
una correspondência for encontrada, o ponteiro de registro ficará no próximo registro do índice
que posea un valor mas alto que la expresion utilizada esta función. Este comando deberá ser
utilizado com a máxima atención, pues caso este ligado, podrá localizar un registro errado.
Cuanto ao comando DO WHILE no esquecer de incluir a condición referente a filial, cuando esta
lectura for de registros de una filial). Exemplo :
dbSelectArea("SB1")
dbSeek(xFilial("SB1"))
Ao crear una función que irá desposicionar registros, use a función GETAREA() e RESTAREA(),
para voltar tudo à posición original. Exemplo:
Dbselectarea("SD1")
aAreasd1 := Getarea() // Almacena el ambiente de archivo SD1
SD1->(dbsetorder(3))
Función Posicione
Puedenos también buscar una información em determinado campo usando apenas una función.
Sintaxe:
Exemplo:
De esta forma, será efectuada una busca no SB1, na ordem 1, chave da busca xFilial("SB1") +
cCodigo e será retornado o conteúdo do campo "B1_DESC". Note que esta función, no restaura a
posición original do archivo alvo (no caso SB1).
É necessário colocar a FILIAL do archivo na chave passada como parâmetro, caso ela exista na
chave do indice.
Función Existcpo
Sintaxe :
ExistCpo(cAlias,cChave,nOrdem)
Exemplo :
ExistCpo("SB1", cCodigo, 1)
Desta forma, será efetuada una busca no SB1, na ordem 1, clave cCodigo. que será retornado se
a clave fue encontrada o no (.T. ou ,F,). Em este caso no és necessário pasar a filial. Ela será
inserida automaticamente na chave de pesquisa pela función.
Nos relatórios devemos analisar que a función “SetPrint”, possibilita efectuar filtros , escolha da
ordem e geración en disco ou impresora , no final dos programas de relatório debemos
restaurar a orden original de archivos e limpar o filtro e desactivar la impressora.
//Término de relatorio
dbSelectArea("SRA")
Set Filter to
dbSetOrder(1)
If aReturn[5] = 1
Set Printer To
Commit
ourspool(wnrel)
Endif
MS_FLUSH()
OTROS CUIDADOS
Un dos cuidados que debemos tener cuando la crreacion de relatórios contendo valores é la
utilización de subtotales e totales, a fin de evitar errores que pueden ser desastrosos durante la
toma de decisión errada debido a valores errados.
Cuando elaboramos un sistema, existem muchos relatórios que generan datos para otros
relatórios e consultas.
Debemos tomar cuidado para que no acontezcan diferências de informaciones de uno para o
otro, como por exemplo, en caso de valores.
Un buen exemplo de eso, és la rutina de impresion de folha de pagamento. Este relatório exibe
informaciones que son utilizadas em otros relatórios, tales como, valores para o FGTS, guia de
recolhimento de impuestos.
Una solución para que no se ocurra una diferencia de valores, seria utilizar una única función o
rutina de procesamento. Esto evitaria que ao se alterar o sistema, por motivo de lei ou outro
cualquer, el programador alterace por exemplo las rutinas de relatório de folha de pagamento e
guia de impustos e esquecesse de alterar por exemplo à rotina de relatório de FGTS.
Este és un tipo de no conformidade simples de ser evitada e que pode causar problemas sérios
para los usuários além de ser de dificil argunentación quando nos questionado, pues evidencia
falta de atención ou critério na manuteción ou falta de conocimiento sobre o funcionamento do
sistema.
O Protheus utiliza a tecnologia Cliente/Servidor. Esto significa que el aplicativo no séa mas
executado individualmente en cada máquina, ele será executado no servidor de aplicacion. Até a
versão 4.07 un programa travado significava que apenas a estación estava comprometida (o
executáble estaba em la memória de estación). Con o Protheus, todo o processamento está no
Server es cuando el programa está en looping estaremos gradativamente “usando todo a CPU del
Server” e consecuentemente parando todo el processamento.
Se ao desenvolvermos una rutina de la misma entrar en looping (tiver apenas una entrada e no
tiver una salida de procesamento), este processamento utilizará todos los recursos del servidor
comprometindo (reduciendo drasticamente el performance de aplicacion), ou até impedindo, o
uso do aplicativo por todos os demas usuários.
Se isso acontecer en una empresa onde existem apenas 5 usuários, o administrador de red podrá
reiniciar el servidor, porém onde existe un número consideráble de usuários poderá haver un
prejuízo para a empresa que utiliza nosso sistema.
Exemplo:
dbSeek(xFilial(“SE1”)+DTOS(dDtIni))
Do While SE1->(!Eof())
…
…
---------- Falta un DbSkip()
Enddo
No exemplo acima, a rotina ficará em looping (pues falta un comando de salida da rotina, un
DbSkip() seria o mas apropriado), utilizando todos os recursos de processamento do servidor,
fazendo com que o mesmo pare de funcionar.
Outro exemplo:
aCampos := {}
Do while .T.
Aadd(aCampos, “Teste”)
Enddo
No exemplo acima o caso é ainda mas crítico, pues além utilizar todo o recurso de
procesamiento del servidor, en dado momento habrá una queda del aplicativo, debido a
limitación de variáble tipo Array, creada acima. E quando este limite for ultrapasado, o
Os archivos que poderão ser copiados deverão estar necessariamente embaixo do RootPath na
configuración do Server, Esto é, o diretório DOCS do exemplo abaixo deverá ser sub-diretório do
RootPath.
Desenvolvendo Telas
A aparência e objetividade das telas nun sistema é base fundamental da interface Sistema x
Usuário.
O AP5 já cria, automaticamente, a grande parte das telas de un módulo, tales como a Browse, a
GetDados e Enchoice.
Algunas outras telas necessitam de construción “manual”, ou sea, com a utilización de comandos,
tales como “SAY” , “GET” e “LABEL”, na Dialog.
Procure sempre colocar em tela as informaciones que mas se objetivam com o assunto
abordado.
Sempre que possível, dê preferência aos campos obrigatórios primeiro. Isso facilita a digitación
do usuário, que no precisará passar de campo em campo (no caso de estar utilizando a tecla
<TAB>) até chegar ao campo deseado. A ordem dos campos também é importante para a fácil
localización das informaciones.
Quando o volune de informaciones é muito grande, divida os campos em folders, ou sea, pastas,
agrupando os campos em assuntos. Isso irá deixar a tela menos poluída e evitará que o usuário
navegue por una tela só. Para fazer essa facilidade, preencha o campo X3_FOLDER, no SX3, com
un número, agrupando-os de acordo com a tipo de información e no SXA, com o ALIAS do
archivo em pauta, a ordem, que equivale ao nunero informado no X3_FOLDER e a descrición nos
três idiomas. Essa descrición que será a información contida na pasta do folder. Exemplo: Os
campos SZ1_ENDER, SZ1_NUN e SZ1_BAIRRO devem estar com o campo X3_FOLDER
preenchido com o conteúdo “1”. No SXA, o XA_ALIAS deverá ser SZ1, o XA_ORDEM = “1”
(mesmo valor preenchido no X3_FOLDER), no XA_DESCRIC, “Endereço Residencial” e, nos
demas, o mesmo texto em otros idiomas.
O Folder, além de agrupar e facilitar a procura pelos campos, evita a rolagem vertical da tela,
facilitando a visualización das informaciones.
Evite tela com muitos botões. Isso poderá confundir o usuário e induzi-lo ao erro. Utilize telas
sequenciais, coñecidas como Wizard (semelhante aos de instalación de un software). Dessa
forma, o usuário ficará mas atento aos fatos, dificultando o erro. Mas cuidado: no faça disso una
incansável sequência de telas, pues isso acabará desmotivando o usuário a utilizar o sistema.
Enfim, as telas devem ser limpas e objetivas, de tal forma que impeça o usuário de sair de seu
objetivo final. Todo curioso irá apertar todos os botões da tela ou preencher todos os campos
com qualquer tipo de información. Portanto, esteja atento a tamaño dos labels, para que os
mesmos no excedam o tamaño da caixa de diálogo definida. Isso, além de no ser estético,
prejudica o entendimento da información.
Quando temos Janelas que necessitem apresentar mas de una getdados, devemos salvar os
elementos, acols, aheader e n, da tela anterior para apresentar una nova janela.
aColsAnt := aClone(Acols)
aHeaderAnt := aClone(aHeader)
nElemAnt := n
E para restaura-las:
aCols := aClone(aColsAnt)
aHeader := aClone(aHeaderAnt)
n := nElemAnt
PONTOS DE ENTRADA
Dentro dos processos operacionais dos programas é possível crear “aberturas” que possibilitam a
execución de processos distintos a partir de una rotina do sistema.
Deixar o sistema flexivél , pues isso permite una grande variedade de desenvolvimento pelos
nossos analistas de suporte de acordo com a necessidade de cada tipo de cliente/implantación.
Permitir que o sistema sea o mas abrangente possível de acordo com cada tipo de segmento de
negócio.
O ponto de entrada tem resultado quando permite que un processo possa ser modificado, desde
que ele no sea crítico para o sistema.
Ele é útil em processos que Pueden ser diferentes de acordo com o tipo de negócio de cada
empresa ou estratégia adotada.
Function TMKA010()
If lTMKMCL
lRetorno := Execblock(“TMKMCI”,.F.,F.,{aValor}) // aValor é un array que seria
recebido pelo usuario em PARAMIXB
Endif
Return( lRetorno )
Avaliar com critério a criación do Ponto de Entrada, pues é importante localiza-lo nun ponto que
sea útil, no redudante e que realmente dê condiciones de atender ao solicitante.
O Ponto de entrada no é una ferramenta de correción de eventuais falha do sistema e sim para
ajudar no desenvolvimento de negócios específicos.
Docunentar no QUARK com nome,momento no qual o momento em que ele é disparado,
parametros que ele envia,retorno esperado (se houver) e o que ele executa com o retorno
CONTABILIZANDO
A contabilización de registros em un sistema ERP é necessário toda vez que houverem operaçoes
envolvendo valores na empresa, como por exemplo, a emissão de una nota fiscal, un
recebimento de diñeiro, un pagamento na folha, entre otros.
Para quem está programando é fundamental que este conceito esteja bastante sidimentado.
Existem três funciones que deverão ser utilizadas, para que sea criado un archivo texto,
contendo as informaciones a serem contabilizadas.
A Función HeadProva
Este función cria o cabeçalho da contabilización. É tratada de forma diferenciada para os módulos
SIGACON e SIGACTB.
Sintaxe:
ñdlPrv := HeadProva(cLoteAtf, cNomProg, Substr(cUsuario,7,6), @archivo, .T.)
Onde:
ÑdlPrv Variável que conterá o nun. (Handle) do archivo (.LAN) criado.
cLoteAtf Código do lote do módulo (Ex.: Ativo Fixo: “8866”)
cNomProg Nome do Programa (Ex.: “ATFA060”)
cUsuario Usuário archivo: nome do archivo (Ex.: cArchivo := ‘ ‘)
A función DetProva()
Em primeiro lugar, deve-se estar posicionado no registro, que contém o valor à ser contabilizado
Sintaxe:
ExpN1 := DetProva(ExpN2,ExpC1,ExpC2,ExpC3)
A función RodaProva()
Sintaxe:
RodaProva(ExpN1, ExpN2)
No Final, ou sea, após todos registros serem processados utilizar a función CA100INCL(), cujo
objetivo é ler o archivo gerado (.LAN), e gerar os lançamentos no archivo SI2 (Lançamentos
contábeis).
Exemplo:
Onde:
cArchivo Nome do archivo
ñdlPrv Nunero do Header
nOpcx Nunero da Opcao escolhida
cLoteContabil Nunero do Lote
lDigita Se Mostra ou nao
lAglut Se Aglutina ou no
cOnLine Determina se sera On Line ou pelo cProva
ATUALIZANDO SX (ATUSX)
Em una atualización de versão, o sistema irá fazer una compatibilización de dados com os
archivos já existentes e os atualizará com base nos SX’s. Ao desenvolver una rotina que exige
un novo campo, por exemplo, este deverá ser criado no ATUSX, caso contrário gerará una no
conformidade comprometendo todo o trabalho da atualización e o bom andamento do trabalho.
Todo os campos, perguntas, índices, parâmetros novos deverão estar no ATUSX , pues estes
são os padrões do Protheus.
Criación de Índice no Cadastro de Funcionários- Supoñamos que sea necessário un índice por
Data de Admissão. Neste caso utilizaremos o SINDEX , onde deverão ser alimentados
basicamente o Alias (SRA), a ordem , a chave de indexación (RA_ADMISSA) e sua descrición em
Português. As descriciones referentes às outras línguas deverão ficar a cargo do departamento
de traduciones. Nuna atualización de versão, o sistema enxergará a existência deste índice pelo
SINDEX e o disponibilizará para utilización.
Ao final da manutención dos archivos SX’s, abre-se una janela onde deve ser docunentado todas
as alteraciones efetuadas da forma mas clara e precisa possível. Esta docunentación é de
extrema importância para que se teña un controle dos archivos customizadores padrões e
garantem un perfeito funcionamento do Protheus.
Esta tabela contém as perguntas, os valores armazenados e a última resposta utilizada para
processamento, impressão de relatórios , etc.
Armazena os Paths dos archivos possibilitando que estes possam ser distribuídos em diversos
drives ou diretórios.
SX6 - Parâmetros
SX7 – Gatilhos
Armazena sequencias alfanunéricas que deverão ser controladas por un semáforo. Un exemplo
clássico seria a nuneración de pedidos de venda, em que vários usuários poderiam estar
utilizando o mesmo número de pedido.
O que é
Quando usar
Quando temos una operación em Banco de Dados que necessite que várias inclusões,
alteraciones ou exclusões só sean efetuadas quando todas as operaciones teñam sido realizadas
com sucesso, garantindo com isso que no sea atualizada parcialmente una tabela ou que atualize
una tabela e no atualize outra tabela relacionada.
Como usar
Para definir una transación, deve-se utilizar os comandos BEGIN TRANSACTION e END
TRANSACTION para definir inicio e fim de una transación respectivamente. Todas informaciones
à serem gravadas no Banco devem estar dentro de una única transación sean elas provenientes
de una ou várias tabelas.
Deve-ser evitar utilizar laços (WHILE, FOR) dentro de una transación, pues a área de LOG do
banco é limitada, e se o volune de informaciones ultrapassarem este limite, ocasionará o
travamento do banco de dados. O tamaño da transación deve-ser ser coñecido pelo programdor.
Em suna, para exemplificar, devemos controlar a transación de una nota e no de un conjunto
ilimitado de notas.
Onde no usar
O controle de transación jamas deverá ser utilizado durante processo que envolvam interface
(telas com entrada de dados). O controle deve-se resunir apenas ao processo de gravación. Entre
un início de transación (Begin Transaction) e un final (End Transaction) Todos os registros a
serem gravados ficam “locados” até o final da transación. Caso teñamos una tela após o BEGIN e
antes do END dependeremos do usuário para efetuar a liberación da transación, fato este que
causaria enormes problemas para o usuário.
Outro lugar que no deve-se ter o controle de transación refere-se a rotinas de reprocessamentos
ou recálculos, onde as informaciones Pueden ser regerados durante este processo ou onde
possamos ter un grande número de locks.
BEGIN TRANSACTION
ExpN1 :=FuncGrava()
END TRANSACTION
Caso exista una transación dentro de una outra a segunda será automaticamente ignorada,
fechando-se a transación principal quando da chamada do comando END TRANSACTION.
Este recurso cria novas e infinitas possibilidades para modificar a maneira pela qual escrevemos o
código de una función e a maneira pela qual Puedenos resolver problemas complexos. Ele ajuda
a facilitar a manutención do código, e a implementación de normas.
Estes comandos são traduzidos, analisados e modificados antes que o compilador comece a
trabalhar para gerar un archivo objeto. O responsável por esta tradución é o pré-processador que
é un tradutor inteligente que atua antes da geración do código objeto.
Em sua maioria, Esto se resune a encontrar os comandos no código fonte e traduzi-los para
instruciones e funciones equivalentes que se acham no corpo da función ou no conteúdo de
archivos .CH (archivos de cabeçalho). Este tipo de archivo (.CH), contém diversos comandos que
serão utilizados por todas as funciones que conteñam a instrución “include” em seu código.
Estes mesmos comandos poderiam estar embutidos na función, mas para facilitar a manutención,
un único archivo .CH, pode ser incluído (comando include) em várias funciones ao mesmo tempo.
No há a necessidade de colocar o comando include em cada función. Una única mención ao .CH
no archivo .PR?, servirá ao propósito de todas as funciones nele embutidas.
Estes comandos são diretivas do pré-processador e começam sempre com o caracter “#”
diretamente à sua frente e devem estar escritos em caracteres tipo caixa alta. Os mas utilizados
no Protheus são:
#DEFINE
#IFDEF, ou #IFNDEF
#ELSE
#ENDIF
#INCLUDE
Cada un destes comandos pode ser colocado em qualquer parte do archivo fonte, que será lido
pelo pré-processador. No entanto, para facilitar a visualización da existência destes comandos e
manutención da función, estes comandos devem ser colocados no início do fonte.
#DEFINE _TESC 27
#DEFINE _LESC lastkey()
if _nLastkey == _TESC
RETURN
Endif
if _LESC == _TESC
RETURN
Endif
Esta diretiva é muito útil quando temos un valor constante várias vezes repetido dentro do código
fonte, que poderá ser alterado com freqüência no decorrer da vida útil da función.
Esta diretiva do pré-processador permite que você prepare aplicaciones para compilación
condicional, ou em outras palavras, se a <constante>, definida anteriormente via diretiva
DEFINE ou pelo Protheus fue definida (IFDEF), as <instruciones> serão incorporadas ao código
objeto e as <outras instruciones>, serão desprezadas. Mas se a <constante> no fue definida
<IFNDEF> as <instruciones> serão incorporadas e as <outras instruciones> serão desprezadas.
#INCLUDE “<ARCHIVO>”
Una instrución INCLUDE diz ao pré-processador para inserir o conteúdo de outro archivo em un
local determinado dentro da función. Este archivo especificado, deve focalizar outras instruciones
do pré-processador que possam ser comuns a diversos módulos da rotina.
Uso de Strings
Para que o sistema possa ser utilizado em otros países com línguas diferentes ao invés de
inserirmos diretamente os textos no fonte do relatório utilizamos o recurso de strings, onde
através de un include acessaremos o texto em três línguas diferentes (Português, Español e
Inglês) dependendo da forma da compilación.
É convencionado que o nome do include sea o mesmo nome do fonte do relatório para que a
manutención deste relatório sea o mas simples possível.
Exemplo:
Relatório FABR001.PRW
Include FABR001.CH
ÍNDICES
A utilización de índices para a pesquisa deve ser bien analisada a fim de evitar lentidão ou
processamentos redundantes nos relatórios.
Os índices ajudam a otimizar as pesquisas e laços de processamentos, por Esto no devem ser
subtilizados ou utilizados de forma errônea.
Caso a necessidade do relatório exija una otimización que no é possível obter com os índices
padrões do sistema é possível crear índices temporários através da función Indregua tornando
assim os relatórios mas ágeis e bien estruturados.
Caso o programa que crie un archivo de trabalho e no o apague no final de seu processamento,
este ficará ocupando espaço em disco no ambiente de trabalho. Esto poderá gerar problemas
futuros para o cliente. Por Esto, é fundamental, que após sua utilización o mesmo sea
descartado.
Puedenos utilizar querys no Protheus quando acessamos bancos de dados via TopConnect.
A princípio no existen diferencias na programación na versão SQL, já que pelo próprio fato de ser
una linguagem interpretada, o sistema é quem se encarrega de executar os comandos e
funciones adequadamente no ambiente em que trabalha. Mas é importante manter algunas
informaciones em mente ao programar para o ambiente SQL.
Deve-se lembrar que estamos trabalhando com un banco de dados relacional, que se utiliza de
tabelas ao invés de archivos, e onde o sistema no tem acesso aos dados de forma nativa e sim
através do Top Connect. Essa forma de acesso adiciona ao sistema algunas das características e
vantagens oferecidas pelo SGBD em uso (por exemplo, o Oracle, MSSQL Server ou o DB2) como
por exemplo segurança e integridade referencial, e as imensas facilidades da linguagem SQL,
mas por outro lado tem-se também as implicaciones da conversão dos comandos no padrão
xBase para a perfeita compreensão no ambiente SQL.
Imagine a montagem de una expressão de filtro para un índice condicional. Tome a seguinte
expressão como exemplo: "DTOS(E1_VENCTO) >= DTOS(mv_par01)". Em un ambiente
padrão xBase, como o NTX ou o ADS, pode-se utilizar variáveis sem qualquer problema em una
expressão de filtro pues a misma será avaliada registro a registro durante a montagem do índice.
Mas no ambiente SQL, o filtro nada mas é do que una tabela temporária, onde estão
selecionados apenas os registros conforme a condición indicada. A seleción de dados em tabelas
pelo SQL é mas rápida, mas em conpensación o SGBD no tem como recoñecer a variável
informada na expressão. Ela existe apenas no sistema ou, mas especificamente, no seu
programa. Por isso, deve-se substituir a expressão anteriormente exemplificada pela seguinte
(que também funcionaria perfeitamente em un ambiente xBase): "DTOS(E1_VENCTO) >=
‘"+DTOS(mv_par01)+"’". Esta expressão é melhor que anterior simplesmente porque no se
utiliza da variável e sim do conteúdo da misma, o que pode ser compreendido em qualquer
ambiente. Toda essas explicaciones são válidas, da misma maneira, a filtros criados através do
comando SET FILTER.
Ainda existem otros detalhes a se considerar quando se trabalha com índices em un ambiente
SQL. É que na verdade no existem índices condicionais nesse ambiente. O filtro é criado
independente do índice. Então, você pode crear un INDREGUA com un filtro e mudar a ordem,
mas o filtro permanecerá ativo, em qualquer ordem. Do mesmo modo, no se pode manter dois
índices, com filtros diferentes, pues un filtro sobrescreveria o outro.
Outro ponto de atención deve ser a función xBase chamada DBSETINDEX. Pueden ocorrer alguns
erros ao tentar-se utilizar essa función para abrir un índice de trabalho criado. Por esses motivos
e pelo fato de tornar o processamento mas lento deve-se evitar ao máximo o uso de índices de
trabalho no ambiente SQL.
Da misma maneira que a funcão DBSETINDEX, os comandos COPY TO e APPEND FROM também
devem ter una atención especial. No ambiente SQL esses comandos são executados entre una
tabela e un archivo DBF (e vice-versa) ou entre dois archivos DBF. Por exemplo, o comando
COPY TO pode ser usado para copiar os dados da tabela ativa para un DBF local e o comando
APPEND FROM pode ser usado para importar os dados de un archivo local para a tabela ativa. Os
dois Pueden ser usados entre dois archivos, mas nunca pode-se usar, por exemplo, o comando
APPEND FROM para importar os dados de una tabela para outra.
O Sistema permite a criación de várias Filiais para una misma empresa cadastrada, de modo que
Filiais da misma empresa compartilhem ou no as mismas informaciones como Cadastro de
Produtos, Clientes, etc.
Este tratamento é feito internamente através dos campo XX_FILIAL obedecendo a seguinte
regra:
Archivos Compartilhados
Quando o archivo esta configurado para trabalhar no modo compartilhado (X2_MODO = ‘C’), este
campo será gravado com “ “ ( espaços ).
Deste modo o registro ficara disponível para todas as Filiais.
Archivos Exclusivos
Quando o archivo esta configurado para trabalhar no modo exclusivo ( X2_MODO= ‘C’ ), esta
campo será gravado com o código da Filial Atual.
Deste modo o registro focara disponivel apenas para a Filial que o gravou.
Para que o registro realmente fique disponível ou no para suas respectivas Filiais , TODAS as
rotinas que manilpulam registros diretamente na base de dados deverá verificar a Filial através
da Función xFilial() , alem dEsto a maioria dos índices possuem o campo FILIAL na
chave :
Por exemplo :
DbSelectArea(“SA1”)
DbSeek(xFilial(“SA1”)+cCodCli+cLoja)
Índice do SA1 :
A1_FILIAL+A1_COD+A1_LOJA
Ou un processamento no archivo :
Sendo o campo FILIAL parte da chave de Todos os índices do sistema, este procedimento
garante que a utilización dos registros será exclusiva da Filial que criou os mesmos no caso do
archivo ser Exclusivo, ou disponível para todas as Filiais quando o mesmo estiver configurado
como Compartilhado.
Jamas use un campo filial de una tabela para executar un dbSeek() em outra tabela. Pues una
tabela poderá ser compartillhada (campo filial em branco), enquanto que a outra poderá ser
compartilhada (campo filial preenchido).
A variável cFilAnt contém a filial que o usuário está operando, e a variável cEmpant contém a
empresa e a filial
Nos sistemas Microsiga, a filtragem dos dados em ambiente Code Base os “DBFs” é feita de
maneira geral pela Función INDREGUA(Params,) , o que de forma geral no impede o uso de
instruciones como SET FILTER TO, DBSETFILTER(), DBFILTER() ou qualquer outro comando de
sintaxe xBase. A INDREGUA() é una función interna que reúne vários atrativos e facilidades para
o seu uso, entre elas a possibilidade de se indexar e filtrar os registros através dos parâmetros
fornecidos, ela também é preferencialmente usada para que o código fique mas “limpo” e de fácil
interpretación pues dentro de sua estrutura reúne una série de comandos de indexación e
filtragem que agiliza o processo de criación de índices e filtros em archivos de trabalho com
menos lineas de código, vejamos o Exemplo :
Chaves Primárias
Sua función é garantir unicidade. Em toda relación, por definición, tem-se una ou mas chaves
candidatas. Dessas chaves, una será primária e se houver mas de una na relación, essas outras
serão definidas como chave alternada.
Chaves Estrangeiras
É un atributo cuya función é permitir relacionamento. Em una tabela na qual o atributo é chave
externa ou estrangeira, em outra, o atributo deve ser chave primária, e os valores dos campos
são necessários.
Integridade Referencial
Todos os valores da chave estrangeira tem, obrigatoriamente, que ter valor correspondente na
chave primária que se relaciona; mas nem todos os valores encontrados na chave primária,
precisam ter seus correspondentes na chave estrangeira que se relaciona. Por exemplo, na tabela
de clientes, o campo A1_COD (código do cliente), vai estar relacionado com outra tabela que
indica quais são os pedidos de venda colocados. Desta forma, nem todos os clientes precisam ter
pedidos de venda colocados; mas, necessariamente, todos os pedidos de venda precisam de un
cliente.
Como o PROTHEUS fue projetado para o ambiente SQL, onde a integridade referencial das
tabelas é definida no próprio banco de dados através de regras internas, devemos tomar algunas
precauciones com esse tópico:
Verificar a integridade dos cadastros com todas as tabelas relacionadas: no pode-se excluir o
código do cliente se existe un pedido de vendas em aberto para esse cliente, deve-se verificar
todas as tabelas relacionadas antes de atualizar a base de dados.Além disso na inclusão de
cadastros devemos utilizar as funciones existchav e existcpo para garantir que as informaciones
de chave no sean repetidas e que o acesso a tabelas externas sea validado de maneira
consistente.
A cada dia estamos criando rotinas com interface automática para melhorar a entrada de dados
via otros equipamentos, tales como coletores de dados, interface de otros softwares, etc. Porém,
para nossa própria portabilidade e utilización de rotinas padronizadas, temos adotado o próprio
programa standard, contudo sem interferencia do usuário (digitador). Para tal, criamos un
mecanismo onde todos os programas que necessitem desta regra devem ser capazes de “inserir”
dados de forma automática. Abaixo mostraremos como proceder :
Tome como exemplo o MATA250.PRX . O vetor aRotAuto é passado para o programa citado. Se
este vetor contiver elementos, significa que será utilizada a Rotina Automática. Este vetor deve,
quando da utilización das rotinas automáticas, conter os dados mínimos necessários para a
atualización dos archivos.
Onde
CCampo é o campo a ser atualizado,
Conteúdo é o conteúdo que cCampo vai receber
Validación é a validación que cCampo vai receber.
Observación: A Validación pode ser una función ou un valor ‘NIL’. Se for ‘NIL’, as validaciones a
serem utilizadas para o respectivo campo serão as existentes no SX3. Se as validaciones no
forem as do SX3, elas devem ser passadas nuna función.
Exemplo,
Para o processo de inclusão simples, sem getdados, a variável padrão a ser utilizada nos
programas chama-se aRotAuto, e para processo de inclusão com cabeçalho e itens, as variáveis a
serem utilizadas são: aAutoCab para o cabeçalho, e aAutoItens para os itens da getdados.
Para una inclusão simples, tomar como exemplo o MATA250.PRX. Para una inclusão com
cabeçalho e ítem, tomar como exemplo o CONA050.PRX.
CONTROLE DE SEMÁFORO
São elas :
CONFIRMSXE Confirma o número sugerido. Esta función deve ser chamada quando da
confirmación da gravación do registro.
A atualización do Source Safe é a última, e mas crítica, etapa do processo de alteración dos
programas. Para que ela sea feita com a máxima segurança algunas etapas devem ser
observadas. A seguir:
Após as alteraciones será necessária una análise meticulosa de tudo o que fue alterado para
avaliar qual o impacto que estas poderão causar no programa em que foram executadas e nos
programas correlacionados;
Deverão ser efetuados o maior número de testes onde deverão ser prevEstos o maior número de
situaciones possíveis e prováveis. Os testes deverão ser simulados em base equivalente à
instalada no cliente e para as novas versões, em una nova base que poderá ser gerada através
do ATUSX;
Feita a análise, os testes e antes de atualizar definitivamente o Source Safe o programa alterado
deverá ser comparado com o constante no Source Safe para verificar se as alteraciones foram
realmente feitas no programa que fue reservado e, só então o programa poderá ser “Baixado”.
Após a “Baixa”, e para garantir que o atualización do Source Safe fue feita corretamente, o
programa atualizado deverá ser novamente comparado. E é claro que se todas as etapas
anteriores, principalmente a 1 e 2 , foram cunpridas essa no passará de una medida de
segurança.
LOCALIZACIONES
A Microsiga atua hoje em 13 países e Esto faz com que praticamente todas as alteraciones
executadas no sistema reflitam em todos os países (exceto quando no for necessário tal
procedimento).
A fim de evitar os inconvenientes citados no ponto anterior, existem procedimentos que devem
ser adotados no nosso dia a dia e repassado para aqueles funcionários que se acoplam a nossa
equipe. Estes são (entre parêntesis os problemas que seriam reduzidos usando os
procedimentos) :
Como o sistema permite que a emissão de relatórios possa ser programada (schedule) é
fundamental que se utilize as rotinas padrões para a emissão dos mesmo. O controle do
schedule é feito pela función SetPrint. Sendo assim, no é suportado interface com data entry
durante o processo de relatório, vEsto que Esto inviabilizará a utilización do mesmo. A no ser en
relatórios específicos e que sean inviáveis a utilización de shedule (ex. Impresion de Cheques)
este procedimento deverá ser adotado corretamente.
Caso exista alguna entrada de dados que sea possível ser assunida qualquer valor apenas no
schedule deve-se adotar o seguinte procedimento :
Usar a variável __cInternet, que se estiver com valor .T. (Verdadeiro) estamos no processo de
schedule.