Programação

Criando arquivos temporários

Escritor por Vinícius Gregório

 

Olá!

 

Como desenvolvedores, nos deparamos com diversas situações onde precisamos armazenar dados temporariamente durante a execução de um determinado processo. Essa necessidade pode se apresentar quando estamos separando registros específicos enquanto trabalhamos com grandes volumes de dados, ou rotinas de importações de informações e validações de complexas de campos, rotinas de processamento de dados provenientes de múltiplas empresas, etc.

 

Em geral, sempre podemos pensar em outras formas de solucionar o mesmo problema porém, é bom saber como criar arquivos de dados temporários e trabalhar com eles. Outro grande benefício de utilizar esses trechos de código é a velocidade da busca dentro desses arquivos quando utilizamos índices 😉

 

Como criar um Arquivo de Dados Temporário no Protheus

 

No artigo de hoje vamos mostrar um exemplo de como criar e utilizar um arquivo de dados temporário. Existe uma série de funções e estruturas de código que são necessárias para que o procedimento funcione, portanto, é importante acompanhar com cuidado o código e a descrição das funções para entender como ele funciona.

 

Estruturas de Campos e Índices

 

Para criar a estrutura de uma tabela de dados, é necessário definir os seus campos. Essa definição é feita em um array, onde cada registro tem a seguinte estrutura (e representa um campo da tabela):

 

Primeira posição: nome do campo da tabela. Deve conter, no máximo, 10 caracteres.

Segunda posição: tipo do campo. C = Character/String, N = Numérico, D = Data, L = Lógico (Booleano)

Terceira posição: tamanho do campo.

Quarta posição: casas decimais (utilizado somente para campos numéricos)

 

Ex.:

 

aAdd(aCampos,{"CODIGO","C",06,0})

 

Outra forma de recuperar as especificações de um campo, é utilizar o dicionário de dados do Protheus e utilizar as informações de um campo parecido. Podemos fazer isso utilizando a função TAMSX3 (ela retorna um array com tipo e tamanho do campo informado):

 

aTamSX3	:= TamSX3("A1_COD")
aAdd(aCampos,{"A1_COD",aTamSX3[3],aTamSX3[1],aTamSX3[2]})

 

Para definir um índice, utilizamos também uma estrutura de array. Da mesma forma como os campos, cada registro no array irá representar um dos índices da tabela. Ex.:

 

aAdd(aInd,{CriaTrab(Nil,.F.),"CODIGO+A1_COD","Codigo+Codigo do Cliente"})

 

A estrutura desse array é a seguinte:

 

Primeira posição: nome do arquivo temporário para o índice. Mais a frente veremos o que é essa função CriaTrab

Fique atualizado, É GRÁTIS!
Cadastre o seu endereço de e-mail e fique por dentro de todas as atualizações da AcademiaERP.
Não enviamos spam.

Segunda posicao: nome dos campos que irão compôr o índice. Lembrando que esses nomes de campos tem que ser iguais ao existente na primeira posição dos registros do array aCampos;

 

Terceira posicao: descrição dos campos que forma o índice.

 

CriaTrab e IndRegua

 

Para criar efetivamente o arquivo temporário, utilizamos a função CriaTrab. Ela pode ser utilizada de duas formas: para recuperar um nome de arquivo disponível (ou seja, o nome será de um arquivo que não existe na pasta Protheus_DataSystem) ou para criar um arquivo de dados utilizando uma estrutura de campos fornecida.

 

Para recuperar somente um nome de arquivo disponível (como fizemos no array de índices), basta chamar a função, sem passar uma estrutura de campos e com o segundo parâmetro igual a falso (.F.). O segundo parâmetro da função é quem realmente determina se o arquivo será criado ou não.

 

Para criar um arquivo de dados, enviamos um array com a estrutura dos campos (conforme fizemos anteriormente) que queremos na tabela e passar o segundo parâmetro como verdadeiro (.T.)

 

cArqTrab	:= CriaTrab(aCampos,.T.)

//Seleciona o arquivo temporário como uma área de trabalho válida e atribui o Alias "ARQTMP"
dbUseArea(.T.,"DBFCDX",cArqTrab,"ARQTMP",.T.,.F.)

Agora, vamos criar o índice utilizando a função IndRegua:

dbSelectArea("ARQTMP")
//Após selecionada a área do arquivo temporário...
For nA	:= 1 to Len(aInd)
	//Cria os índices utiliando o comando IndRegua
	IndRegua("ARQTMP",aInd[nA,1],aInd[nA,2],,,OemToAnsi("Criando Índice Temporário..."))
Next nA

 

Perceba como envolvemos a chamada da função em um laço (For..Next). Isso porquê queremos criar um índice para cada registro no array a aInd. Essa função ainda exibe para o usuário uma mensagem enquanto o sistema gera os índices para a tabela.

 

Fonte de Exemplo

 

Para deixar mais claro o funcionamento dessas rotinas, criei um fonte de exemplo com todos os passos explicados em comentários. Além de criar o arquivo, codifiquei também uma função de teste que insere registros nessa tabela e depois os imprime na tela para o usuário:

 

#include "protheus.ch"
#include "topconn.ch"

/*
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±±
±±ºPrograma  ³XArqTmp       ºAutor  ³Vinícius Gregório   º Data ³  04/11/13   º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºDesc.     ³ Gera a estrutura dos arquivos temporários                      º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºUso       ³ AcademiaERP                                                    º±±
±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
*/
User Function XArqTmp()
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Declaração de variáveis³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Local aArea		:= GetArea()
Local lRetorno	:= .T.
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Nome do arquivo temporário³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Local cArqTrab	:= ""

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Arrays utilizados para a criação da tabela³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Local aInd		:= {}
Local aTamSX3	:= {}
Local aCampos	:= {}

//Nesse exemplo, o array aCampos terá a especificação de um campo da tabela em cada uma das suas posições

//criando campo com tipo e tamanho definidos manualmente, onde:
//primeira posição: nome do campo na tabela
//segunda posição: tipo do campo (C = caracter, N = Numérico, D = Data, L = Lógico)
aAdd(aCampos,{"CODIGO","C",06,0})

//criando campo com base em campo existente no dicionário de dados (SX3)
//a função TamSX3 retorna um array com as especificações do dicionário para o campo passado como parâmetro
aTamSX3	:= TamSX3("A1_COD")

//vc pode deixar o nome original do campo
aAdd(aCampos,{"A1_COD",aTamSX3[3],aTamSX3[1],aTamSX3[2]})

aTamSX3	:= TamSX3("A1_LOJA")

//ou pode dar o outro nome, desde que tenha a quantidade máxima de 10 caracteres
aAdd(aCampos,{"LOJA",aTamSX3[3],aTamSX3[1],aTamSX3[2]})

//Montando o array que irá definir o índice, onde cada registro no array irá representar um dos índices da tabela
//primeira posição: nome do arquivo temporário para o índice.
//segunda posicao: nome dos campos que irão compôr o índice Lembrando que esses nomes de campos tem que ser iguais
//ao existente na primeira posição dos registros do array aCampos
//terceira posicao: nome dos campos que formam o índice
aAdd(aInd,{CriaTrab(Nil,.F.),"CODIGO+A1_COD","Codigo+Codigo do Cliente"})

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³VG - 2013.05.24                ³
//³Gera arquivo temporário para   ³
//³armazenar os registros da ARQTMP³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
//Cria o arquivo temporário, passando para o CriaTrab o array com a estrutura de campos da tabela a ser gerada
//primeiro parâmetro: campos para criar o arquivo de trabalho
//segundo parâmetro: caso verdadeiro (.T.), cria o arquivo. Caso falso (.F.), somente retorna o nome disponível para o arquivo.
cArqTrab	:= CriaTrab(aCampos,.T.)

//Seleciona o arquivo temporário como uma área de trabalho válida e atribui o Alias "ARQTMP"
dbUseArea(.T.,"DBFCDX",cArqTrab,"ARQTMP",.T.,.F.)

dbSelectArea("ARQTMP")
//Após selecionada a área do arquivo temporário...
For nA	:= 1 to Len(aInd)
	//Cria os índices utiliando o comando IndRegua
	IndRegua("ARQTMP",aInd[nA,1],aInd[nA,2],,,OemToAnsi("Criando Índice Temporário..."))
Next nA

//chama uma função genérica pra testar nosso arquivo temporário
Teste()

RestArea(aArea)
Return lRetorno

/*
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±±
±±ºPrograma  ³XARQTMP   ºAutor  ³Vinícius Gregório   º Data ³  04/11/13   º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºDesc.     ³ Função genérica para testar nosso arquivo temporário       º±±
±±º          ³                                                            º±±
±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±±
±±ºUso       ³ AP                                                         º±±
±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ±±
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
*/
Static Function Teste()
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Declaração de variáveis³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dbSelectArea("ARQTMP")

RecLock("ARQTMP",.T.)
ARQTMP->CODIGO	:= "TESTE"
ARQTMP->A1_COD	:= "000001"
ARQTMP->LOJA		:= "01"
ARQTMP->(MsUnlock())

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
//³Imprime todos os registros armazenados³
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
dbSelectArea("ARQTMP")
dbGoTop()
Do While !EOF()

	MsgInfo("CODIGO: "+ARQTMP->CODIGO+" ,A1_COD: "+ARQTMP->A1_COD+" ,LOJA: "+ARQTMP->LOJA)

	dbSelectArea("ARQTMP")
	ARQTMP->(dbSkip())
EndDo

Return .T.

 

Para baixar o fonte de exemplo, clique aqui

 

Sobre o Autor

Vinícius Gregório

Tecnólogo em análise de sistemas da informação pela Faculdade IBTA (SP), empreendedor da área de TI e consultor Protheus especializado em desenvolvimento AdvPL. Trabalhou em diversos projetos com os módulos de Compras, Estoque/Custos, Faturamento, Contabilidade Gerencial, Field Service/Gestão de Serviços, Financeiro, Gestão de Contratos e Gestão de Projetos. Atua também como desenvolvedor de sistemas web e é usuário fanático de sistemas e softwares open source... (vinicius.gregorio@academiaerp.com.br)

4 comentários

Deixe um comentário

Dúvida?