Página 1 de 1

Listar estrutura de um DBF e criar DBF com registros exemplo

Enviado: 21 Set 2007 18:15
por Pablo César
Fui motivado para abrir este novo tópico visto que muito colegas abrem seus tópicos com perguntas onde tem a necessidade de manipulação do seu BD e muitas vezes ficamos "boiando" sem saber a estrutura do seu BD. E aqui vai um exemplo para facilitar a vida deles pois eu acho que este tipo utilitário todo programador deve disponibilizar na pontas dos dedos.

Criar um PRG com nome STRU.PRG

Código: Selecionar todos

/*
        Incluir na compilacao:   WAPI.LIB + CT.LIB
      O WAPI.EXE dever  estar no diretorio corrente.
*/

Parameters dbffile, tto, dest
If (tto != Nil)
   tto:= Upper(tto)
EndIf
If dbffile=NIL .OR. (tto="TO" .AND. dest=Nil)
   ? "Uso: STRU <Dbf>                           (Mostra na tela)"
   ? "     STRU <Dbf> TO <Arquivo>              (Grava num arquivo)"
   ? "     STRU <Dbf> TO PRIN                   (Imprime na impressora)"
   ?
   ? "Observa‡„o: No parametro <Dbf> aceita <*> como curinga"
   QUIT
Endi
vtodos=dbffile
IF "*" $ vtodos
   IF vtodos=="*"
      vtodos="*.DBF"
   ENDIF
   VDBF:=DIRECTORY(vtodos)
ELSE
   VDBF:={{DBFFILE}}
ENDIF
FOR I=1 TO LEN(vdbf)
    DBFFILE=VDBF[I,1]
    If (At(".", dbffile) == 0)
       dbffile:= dbffile + ".DBF"
    EndIf
    If (dest != Nil)
       If (At(".", dest) == 0)
          dest:= dest + ".TXT"
       EndIf
    EndIf
    IF !FILE(dbffile)
       ?? "Arquivo "+DBFFILE+" n„o encontrado !"
       QUIT
    ENDIF
    Use (dbffile) New
    If ("" = dest .OR. dest = Nil)
       disp_stru(Nil, .F.)
    ElseIf (Left(Upper(dest), 4) = "PRIN")
       disp_stru(Nil, .T.)
    Else
       If (file(dest) .and. !"*" $ vtodos)
          vsn:= " "
          @ 24,00
          @ 24,00 Say Trim(padc("Sobre-escreve o arquivo: "+dest+" <S> ou <N> ?", 78)) Get VSN Picture "!" Valid vsn $ "SN"
          Read
          @ 24,00
          If (vsn = "S")
             Erase (dest)
          EndIf
       EndIf
       disp_stru(dest, .F.)
    EndIf
NEXT

Function DISP_STRU(Arg1, Arg2)
oldprintf:= Set(_SET_PRINTFILE)
oldprint:= Set(_SET_PRINTER)
oldcons:= Set(_SET_CONSOLE)
VPRIN:=GETDEFPRINTER()
IF ARG2=.T. .AND. EMPTY(VPRIN[1])
   ? "Nenhuma impressora definida."
   ARQG2:=.F.
ENDIF
If (Arg2)
   Set Printer To "$$$.$$$"
   Set Console Off
   Set Printer On
Else
   If ("" != Arg1 .AND. Arg1 != Nil)
      Set Printer To (Arg1) Additive
      Set Console Off
      Set Printer On
   Endif
EndIf
vtc:= FCount()
vlc:= Len(alltrim(Str(vtc)))
If (vlc < 3)
   vd:= 2
Else
   vd:= vlc
EndIf
? "+" + padc(" " + dbf() + ".DBF ", 26 + vd, "-") + "+"
? "| " + padr("N§", vd) + " Nome        Tipo Tam Dec|"
? "+" + Replicate("-", 26 + vd) + "+"
a:= 0
aeval((alias())->(dbstruct()), { |_1| QOut("| "+padr(strzero(++a,vlc,0),vd)+" "+pad(_1[1],10),"   "+_1[2],Str(_1[3], 3),Str(_1[4], 3)+" |") })
? "+" + PADC(" N§ Registros "+ALLTRIM(STR(LASTREC()))+" ",26+vd,"-") + "+"
Set Printer (oldprint)
Set Printer To (oldprintf)
Set Console (oldcons)
IF !PRINTFILE(VPRIN[1],"$$$.$$$","Estrutura do "+dbf())
   ? "N„o foi poss¡vel imprimir a estrutura do arquivo."
ENDIF
DELETE FILE("$$$.$$$")
Return Nil
Outra coisa que vejo que seria importante as vezes,´poder disponibilizar parte do BD com alguns exemplos. Claro que sempre e quando sejam apenas meia dúzia de registros e não contendo tanto campos (acho que as vezes pode ser simplificado). Por exemplo, eu precisei em duas ocasiões disponibilizar o BD também e para isso faço assim:

Código: Selecionar todos

IF !FILE("LANCNF.DBF")
   CAMPOS:={{"NF"      ,"N",010,000},;
            {"ITEM"    ,"N",003,000},;
            {"DATEMI"  ,"D",008,000},;
            {"FORN"    ,"N",003,000},;
            {"MOSTFORN","C",030,000},;
            {"PROD"    ,"N",013,000},;
            {"MOSTPROD","C",030,000},;
            {"GASET"   ,"N",003,000},;
            {"SET"     ,"C",030,000},;
            {"UNI"     ,"C",005,000},;
            {"QUANT"   ,"N",009,002},;
            {"VOL"     ,"N",003,000},;
            {"VALUNI"  ,"N",009,002},;
            {"VALTOT"  ,"N",009,002},;
            {"DATLANC" ,"D",008,000},;
            {"OBS"     ,"C",030,000} }
   DBCREATE("LANCNF.DBF",CAMPOS)
   USE LANCNF
   DADOS()
   APPEND FROM DADOS.TXT DELI
ENDIF


FUNCTION DADOS()
TEXT TO FILE("DADOS.TXT" )
1,1,20070101,2,"JURANDIR",3,"OLEO SOLUVEL",1,"FIACAO","BD",2.00,2,50.00,100.00,20070502,""
1,2,20070101,2,"JURANDIR",2,"ROLAMENTO",3,"TEXTIMA","PC",5.00,1,15.00,75.00,20070502,""
1,3,20070101,2,"JURANDIR",20,"TAMBOR PARA OLEO",1,"FIACAO","TB",1.00,1,100.50,100.50,20070502,""
2,1,20070101,1,"EDER",22,"BORRACHA",7,"ESCRITORIO TECNICO","CX",50.00,5,0.30,15.00,20070502,""
2,2,20070101,1,"EDER",21,"CANETA",7,"ESCRITORIO TECNICO","CX",50.00,2,0.50,25.00,20070502,""
ENDTEXT
RETURN NIL
Este exemplo mostra como disponibilizar alguns registros como exemplo e criaria o arquivo .DBF.
Útil principalmente quando é mais simples mostrar diretamente com os dados e nome dos campos, do que o uso das palavras.

Obs.: Esta mensagem foi re-editada para adaptar ao código fonte do STRU.PRG para que possa imprimir também em impressoras USBe substitui os caracteres gráficos por caracter simples de moldura (dessa forma poderá ser exibido em qualquer ambiente).

Enviado: 21 Set 2007 18:23
por Maligno
Outra coisa que vejo que seria importante as vezes,´poder disponibilizar parte do BD com alguns exemplos.
Acertou na mosca! :)

Enviado: 21 Set 2007 18:27
por Pablo César
E que achou Maligno ? Acho que nos meus dois exemplos anteriores, passou por alto (ninguém tinha notado). MAs acho que é muito útil não é mesmo. Só espero que o pessoal não exagere na quantidade de registros nem de campos. Com este tópico podemos fazer referência para instruir de como apresentar os BDs junto com as perguntas.

Enviado: 21 Set 2007 18:34
por Maligno
Ah, sim. Com um código novo, é sempre uma excelente idéia repassar um conjunto mínimo de dados para testes. Ajuda bastante no aspecto prático e também a clarear as idéias.

Enviado: 21 Set 2007 18:40
por Pablo César
Para poder disponibilizar parte dos dados na função DADOS (no TEXT/ENDTEXT) é só gerar assim:

USE ARQUIVO.DBF
COPY TO TXT_DBF.TXT DELI

Depois basta selecionar quatro ou cinco registros da sua preferência e colar na função DADOS().

Enviado: 21 Set 2007 18:44
por Maligno
Sim, gerar os dados eu sei. Apenas quis ressaltar a importância disso. :)

Enviado: 21 Set 2007 18:51
por Pablo César
Ahhh por supuesto colega que você deve saber, e até mais do que de um jeito (eu não tenho dúvida alguma disso). Eu aproveitei o embalo para exemplificar e que servisse para os outros também.

Dificil mesmo vai ser quando for campo MEMO... hihihi (brincadeirinha...)

Enviado: 21 Set 2007 19:02
por Maligno
Dificil mesmo vai ser quando for campo MEMO
Aí sim daria mais trabalho. Ainda bem que eu não uso. :)