Importando um arquivo texto sem delimitadores
O processo de importação de um arquivo texto no Protheus não é lá um processo muito simples, mas não impossível de se fazer, o mais fácil é quando temos um arquivo com delimitadores, seja usando ponto e vírgula (;), ou usando o pipe (|), barra (/), entre outros caracteres.
Agora importar um arquivo texto sem delimitadores, já torna o processo um pouco mais chato, mas também nada impossível de se fazer. Alguns colegas que estão começando sempre me perguntam, tem alguma forma mais fácil de se fazer? Digo que depende muito da lógica a ser usada, mas os comandos serão sempre os mesmo.
Neste artigo, irei demonstrar um exemplo de importação de arquivo texto sem delimitadores para que você possa utilizá-lo no seu dia a dia, mas para aqueles que fazem isso e tiver um exemplo mais fácil, compartilhe conosco, toda dica é bem vinda.
Primeiramente irei mostrar o formato do arquivo texto, neste exemplo será um bem simples. (Arquivo exemplo)
Tela inicial: colocarei todos os campos contidos no meu arquivo texto.
Utilizarei os componentes:
Say() = Exibe textos em uma tela de interface com o usuário
MsGet() = Permite que o usuário digite informações na tela, conforme a necessidade da aplicação.
TCBrowse() = Cria um objeto do tipo grade.
Button() = Criar um botão na tela para que o usuário interaja com a aplicação.
Desenhei a tela utilizando o programa GAIA 2010.
Para selecionar o arquivo, usarei a função cGetFile (Apresenta uma janela com os diretórios disponíveis, na estação e no servidor, e retorna o nome do item.) , para saber mais sobre esta função consulte o TDN (http://tdn.totvs.com/display/tec/cGetFile).
Após selecionar o arquivo e confirmá-lo, o arquivo é importado para a tela criada. Você poderia perfeitamente importar diretamente numa tabela.
Visualizando assim, parece tudo simples não é mesmo?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
#Include 'Protheus.ch' User Function exemplo3() /*Declaração das variáveis locais*/ Local oButton1 Local oButton2 Local oSim := LoadBitmap(GetResources(), "ENABLE") Local oNao := LoadBitmap(GetResources(), "DISABLE") Local oCEP Local oCidade Local oCNPJ Local oComplemento Local oContato Local oEmail Local oEmissao Local oEmpresa Local oEndereco Local oEntrega Local oMoeda Local oPagto Local oPedido Local oUF /*Declaração das variáveis privadas*/ Private oPedidos Private cPedido := Space(06) Private cCNPJ := Space(14) Private cCEP := Space(8) Private cEmpresa := Space(30) Private cEndereco := Space(100) Private cCidade := Space(30) Private cUF := Space(2) Private cContato := Space(30) Private cEmail := Space(200) Private dEmissao := CTOD("//") Private dEntrega := CTOD("//") Private cMoeda := Space(30) Private cPagto := Space(30) Private cComplemento:= Space(100) Private aPedidos := {} /*Declaração das variáveis estáticas*/ Static oDlg DEFINE MSDIALOG oDlg TITLE "Importando arquivo texto não delimitado" FROM 000, 000 TO 400, 500 PIXEL @ 003, 005 SAY oSay1 PROMPT "Pedido" SIZE 025, 007 OF oDlg PIXEL @ 011, 005 MSGET oPedido VAR cPedido SIZE 036, 010 OF oDlg PIXEL @ 003, 046 SAY oSay2 PROMPT "CNPJ" SIZE 025, 007 OF oDlg PIXEL @ 011, 046 MSGET oCNPJ VAR cCNPJ SIZE 061, 010 OF oDlg PIXEL @ 003, 112 SAY oSay3 PROMPT "Empresa" SIZE 025, 007 OF oDlg PIXEL @ 011, 112 MSGET oEmpresa VAR cEmpresa SIZE 131, 010 OF oDlg PIXEL @ 024, 005 SAY oSay4 PROMPT "Endereço" SIZE 025, 007 OF oDlg PIXEL @ 031, 005 MSGET oEndereco VAR cEndereco SIZE 101, 010 OF oDlg PIXEL @ 024, 112 SAY oSay5 PROMPT "Cidade" SIZE 025, 007 OF oDlg PIXEL @ 031, 112 MSGET oCidade VAR cCidade SIZE 110, 010 OF oDlg PIXEL @ 024, 227 SAY oSay6 PROMPT "UF" SIZE 014, 007 OF oDlg PIXEL @ 031, 227 MSGET oUF VAR cUF SIZE 016, 010 OF oDlg PIXEL @ 044, 005 SAY oSay7 PROMPT "CEP" SIZE 025, 007 OF oDlg PIXEL @ 051, 005 MSGET oCEP VAR cCEP SIZE 036, 010 OF oDlg PIXEL @ 044, 046 SAY oSay8 PROMPT "Contato" SIZE 025, 007 OF oDlg PIXEL @ 051, 046 MSGET oContato VAR cContato SIZE 061, 010 OF oDlg PIXEL @ 044, 112 SAY oSay9 PROMPT "E-mail" SIZE 025, 007 OF oDlg PIXEL @ 051, 112 MSGET oEmail VAR cEmail SIZE 131, 010 OF oDlg PIXEL //Usando o TCBrowse para gerenciar individualmente cada coluna oPedidos := TCBrowse():New(067, 005,238, 060,,,,oDlg,,,,,,,,,,,,.F.,,.T.,,.F.,,,) oPedidos:AddColumn(TCColumn():New(" " , {|| If(aPedidos[oPedidos:nAt,01],oSim,oNao) },,,,,,.T.,.F.,,,,.F., ) ) oPedidos:AddColumn(TCColumn():New("Codigo" , {|| aPedidos[oPedidos:nAt,02]},"@!",,,"CENTER", 025,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("Descrição" , {|| aPedidos[oPedidos:nAt,03]},"@!",,,"LEFT", 040,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("No.Serie" , {|| aPedidos[oPedidos:nAt,04]},"@!",,,"LEFT", 080,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("Qtde" , {|| aPedidos[oPedidos:nAt,05]},"@E 999,999,999.99",,,"RIGHT", 040,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("Valor" , {|| aPedidos[oPedidos:nAt,06]},"@E 999,999,999.99",,,"RIGHT", 040,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("Total" , {|| aPedidos[oPedidos:nAt,07]},"@E 999,999,999.99",,,"RIGHT", 040,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:AddColumn(TCColumn():New("Observação" , {|| aPedidos[oPedidos:nAt,08]},"@!",,,"LEFT", 120,.F.,.F.,,{|| .F. },,.F., ) ) oPedidos:SetArray(aPedidos) //Define um array para o browse oPedidos:bWhen := { || Len(aPedidos) > 0 } //Se o array estiver vazio, o browse fica desabilitado oPedidos:Refresh() @ 130, 005 SAY oSay10 PROMPT "Cond.Pagto" SIZE 035, 007 OF oDlg PIXEL @ 138, 005 MSGET oPagto VAR cPagto SIZE 113, 010 OF oDlg PIXEL @ 130, 122 SAY oSay11 PROMPT "Emissão" SIZE 025, 007 OF oDlg PIXEL @ 138, 122 MSGET oEmissao VAR dEmissao SIZE 041, 010 OF oDlg PIXEL @ 130, 169 SAY oSay12 PROMPT "Entrega" SIZE 025, 007 OF oDlg PIXEL @ 138, 169 MSGET oEntrega VAR dEntrega SIZE 041, 010 OF oDlg PIXEL @ 130, 214 SAY oSay13 PROMPT "Moeda" SIZE 020, 007 OF oDlg PIXEL @ 138, 214 MSGET oMoeda VAR cMoeda SIZE 030, 010 OF oDlg PIXEL @ 153, 005 SAY oSay14 PROMPT "Complemento:" SIZE 038, 007 OF oDlg PIXEL @ 160, 005 MSGET oComplemento VAR cComplemento SIZE 238, 010 OF oDlg PIXEL //Para o processamento, utilizarei a função Processa() //A função Processa() exibe um diálogo onde a execução //de um processo pode ser monitorada através da régua de progressão. @ 181, 155 BUTTON oButton1 PROMPT "Importar" SIZE 037, 012 OF oDlg ACTION Processa({|| Importar()},"Aguarde...") PIXEL @ 181, 207 BUTTON oButton2 PROMPT "Fechar" SIZE 037, 012 OF oDlg ACTION oDlg:End() PIXEL ACTIVATE MSDIALOG oDlg CENTERED Return //Função para importar o arquivo texto. Static Function Importar() Local cArquivo := cGetFile("Arquivo TXT (*.TXT) |*.TXT|","Selecione o Arquivo...",2,,.T.,GETF_LOCALHARD+GETF_NETWORKDRIVE) Local aItens := {} Local aFornece:= {} Local aRodape := {} Local nCont := 0 Local i := 0 Local nLinhas := 0 Local _aStr := {{"Texto","C",1000,0}} Local _cTmp := CriaTrab(NIL,.F.) Local nQtde := 0 Local nValor := 0 Local nTotal := 0 if !file(Alltrim(cArquivo)) Alert("Arquivo "+Alltrim(cArquivo)+" não existe!"+CRLF+"Abortando importação!") Return Endif //Criarei uma tabela temporária para armazenar cada linha do meu txt, poderia usar um array //mas irei motrar tambem como criar uma tabela temporária //dbCreate = Define uma nova tabela ou um novo arquivo do tipo tabela e sua estrutura (campos) dbCreate(_cTmp,_aStr) //Verifico se a área de trabalho está aberta, se estiver irei fechar, isso evita que o sistema //dê um erro informando que a área ja está aberta IF SELECT("TRB") # 0 TRB->(dbCloseArea()) ENDIF //DBUseArea = Abre uma tabela de dados na área de trabalho atual ou na primeira área de trabalho disponível. DBUseArea(.T.,,_cTmp,"TRB",.F.,.F.) //GetSrvProfString = Recupera o conteúdo de uma chave de configuração, do ambiente em uso, no arquivo de //configuração (.INI) do TOTVS Application Server. if AT(":\",cArquivo)>0 CpyT2S( cArquivo, GetSrvProfString("Startpath","") ) Else CpyT2S( cArquivo, GetSrvProfString("Startpath","") ) endif //Append From = Utilização do comando 'APPEND FROM ... SDF', para importação de dados de um arquivo texto Append From &cArquivo SDF //Vou para o inicio do arquivo TRB->(dbGoTop()) //conto quantas linhas eu tenho nLinhas:=TRB->(RecCount()) //Monto minha regua de processamento com a quantidade de linhas encontradas ProcRegua(nLinhas) //Limpo a variavel que irá receber os dados aPedidos:={} //Inicio a leitura da minha tabela, enquanto não for o final dela While TRB->(!Eof()) nCont++ If lEnd MsgInfo("Cancelado!","Fim") exit Endif IF nCont > nLinhas exit endif //IncProc = informa o texto que irá ser apresentado na tela de processamento IncProc("Lendo arquivo texto...Linha "+Alltrim(str(nCont))) //Recebo o conteudo do meu texto cLinha := ALLTRIM(UPPER(TRB->Texto)) if !empty(cLinha) /* Neste exemplo, o meu arquivo texto possui um campo inicial que identifica o que ele é: Linha que começa com 1 = Cabeçalho Linha que começa com 2 = Itens Linha que começa com 3 = Rodapé */ if Substr(cLinha,1,1)=="1" //aFornece[1][1] = PEDIDO //Tamanho: 6 //aFornece[1][2] = CNPJ //Tamanho: 11 //aFornece[1][3] = NOMEDAEMPRESA //Tamanho: 35 //aFornece[1][4] = ENDERECO //Tamanho: 30 //aFornece[1][5] = CIDADE //Tamanho: 18 //aFornece[1][6] = UF //Tamanho: 2 //aFornece[1][7] = CEP //Tamanho: 8 //aFornece[1][8] = CONTATO //Tamanho: 21 //aFornece[1][9] = EMAIL //Tamanho:100 aadd(aFornece,{Substr(cLinha, 2, 6),; Substr(cLinha, 8, 11),; Substr(cLinha, 22, 35),; Substr(cLinha, 58, 30),; Substr(cLinha, 89, 18),; Substr(cLinha,108, 2),; Substr(cLinha,110, 8),; Substr(cLinha,118, 21),; Substr(cLinha,140,100)}) Elseif Substr(cLinha,1,1)=="2" //aItens[1][1] = CODIGO //Tamanho: 6 //aItens[1][2] = DESCRICAO //Tamanho: 25 //aItens[1][3] = NUMEROSERIE //Tamanho: 22 //aItens[1][4] = QTDE //Tamanho: 10 //aItens[1][5] = VALOR //Tamanho: 10 //aItens[1][6] = OBSERVACAO //Tamanho:100 aadd(aItens,{ Substr(cLinha, 2, 6),; Substr(cLinha, 8, 25),; Substr(cLinha,34, 22),; Substr(cLinha,57, 10),; Substr(cLinha,67, 10),; Substr(cLinha,77,100)}) Elseif Substr(cLinha,1,1)=="3" //aItens[1][1] = PAGTO //Tamanho: 17 //aItens[1][2] = EMISSAO //Tamanho: 10 //aItens[1][3] = ENTREGA //Tamanho: 10 //aItens[1][4] = COMPLEMENTO //Tamanho: 75 //aItens[1][5] = MOEDA //Tamanho: 30 aadd(aRodape,{Substr(cLinha, 2,17),; Substr(cLinha, 20,10),; Substr(cLinha, 30,10),; Substr(cLinha, 40,75),; Substr(cLinha,116,30)}) Endif endif DbSkip() EndDo //Fecho a área aberta TRB->(dbCloseArea()) //Apago o arquivo temporario gerado para que não fique lixo no sistema Ferase(_cTmp+".DBF") //Começo a popular os campos e o browse if len(aFornece) > 0 M->cPedido := aFornece[1][1] M->cCNPJ := aFornece[1][2] M->cEmpresa := aFornece[1][3] M->cEndereco := aFornece[1][4] M->cCidade := aFornece[1][5] M->cUF := aFornece[1][6] M->cCEP := aFornece[1][7] M->cContato := aFornece[1][8] M->cEmail := aFornece[1][9] Endif if len(aRodape) > 0 M->cPagto := aRodape[1][1] M->cComplemento := aRodape[1][4] M->cMoeda := aRodape[1][5] //como o campo é do tipo data, irei transformar de //caracter para data usando o comando CTOD M->dEmissao := CTOD(aRodape[1][2]) M->dEntrega := CTOD(aRodape[1][3]) Endif //Inicio a leitura dos itens que irão popular o meu browse For i := 1 to len(aItens) IncProc("Inserindo item "+ Alltrim(aItens[i,1])+"...") //Convertendo texto para valores, utilizo a função VAL() nQuant := Val(Substr(aItens[i,4],1,8)+"."+ Substr(aItens[i,4],9,2)) nValor := Val(Substr(aItens[i,5],1,8)+"."+ Substr(aItens[i,5],9,2)) nTotal := nQuant * nValor aadd(aPedidos,{ .T.,; //01 - Legenda aItens[i][1],; //02 - Codigo aItens[i][2],; //03 - Descricao aItens[i][3],; //04 - No.Serie nQuant,; //05 - Quantidade nValor,; //06 - Valor nTotal,; //07 - Total aItens[i][6]; //08 - Observação }) Next //Populo o browse com os dados do array oPedidos:SetArray(aPedidos) //Elimino o arquivo texto que importei Ferase(GetSrvProfString("Startpath","")+cArquivo) Return |
Append From button dbCloseArea dbCreate dbGoTop dbUseArea Ferase GetSrvProfString Importa MsGet Processa ProcRegua RecCount SELECT TCBrowse texto