Alterar campo de um DBF via sistema

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Alterar campo de um DBF via sistema

Mensagem por gilbertosilverio »

Olá amigos,

Uso um rotina a muito tempo, quando necessito acrescentar campos em um DBF, hoje surgiu a necessidade de aumentar o valor de um campo, no caso, aumentar o campo BASEST - N - 15 - 4 para BASEST - N - 25 - 9.

Fiz isso manualmente, mais tentei de varias maneiras alterar via sistema e não consegui.

A rotina que uso para alterar, ate me deu a opção de incluir o campo dentro do DBF, que que ficou em duplicidade o campo e creio que daria problema em execução.

Código: Selecionar todos

Function INCLUIR_DADOS_NO_DBF() // usado para acrescentar um campo em um arquivo
    Local A1:={}, vPATH := curdrive()+':'+"\"+curdir()+[\]
    PRIVATE xARQUIVO:= vPATH+'ENTRADA.DBF'
    set deleted off
    DBCLOSEALL()
    DBUSEAREA( .t., "DBFNTX", [xNTRADA], [xNTRADA])
    a1 := xNTRADA->(dbstruct())
    if fieldPos( [BASEST] ) != 0
       nOPT:=0
       ALERTVER([Ja existe o registro BASEST no arquivo em xNTRADA.DBF])
    else
       aadd(a1, {'BASEST',    'N', 25, 9})
       aadd(a1, {'VLRST',     'N',  25, 9})

       dbcloseall()

       dbcreate(xARQUIVO, a1, [DBFNTX])

       dbusearea(.t.,[DBFNTX], [ENTRADA.DBF], [ENTRADA])
       append from xNTRADA

       dbcloseall()
       FRename( 'xNTRADA.DBF', 'xNTRADAOLD.DBF')
       INKEY(0.2)
       FRename( 'ENTRADA.DBF', 'xNTRADA.DBF'   )
    endif
    set deleted on
    SAIR()
return nil

Alguém tem essa rotina, para incluir, excluir e alterar campos do DBF de uma maneira pratica.

Grato.
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
frazato
Usuário Nível 3
Usuário Nível 3
Mensagens: 219
Registrado em: 08 Jul 2004 07:45

Alterar campo de um DBF via sistema

Mensagem por frazato »

Bom dia!
uso basicamente igual a vc, mais tenho uma matriz com todas as estruturas do banco, e através de um parâmetro no sistema faço a verificação de alguma diferença no bdf, caso tenho crio e importo do antigo, tem funcionado a bastante tempo.

Frazato

Código: Selecionar todos

----------------------
FUNCTION DBFS_1()
        MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA ")
//----- TABCONFG.JAF CONFIGURACAO DO SISTEMA
        CARQCDX := "TABCONFG"+TIPODRIVER
        CARQDBF := "TABCONFG.JAF"
        MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)


         ESTRUTURA := { { "TAB_CODI" ,  "C" ,  4, 0 },;
                        { "TAB_NOME" ,  "C" , 30, 0 },;
                        { "TAB_CONT" ,  "C" , 60, 0 } }

         AADD(LISTADBF,{CARQCDX,CARQDBF})

         Ver_Dbf('TABCONFG.JAF',ESTRUTURA)

         IF ! FILE("TABCONFG.JAF")
                 DBCREATE("TABCONFG.JAF", ESTRUTURA )
                 MSG("AGUARDE.... CRIANDO "+CARQDBF)
                 USE TABCONFG.JAF
                 INDEX ON TAB_CODI TAG TABCONF1 TO TABCONFG
                 INDEX ON TAB_CONT TAG TABCONF2 TO TABCONFG
           ELSEIF ! FILE("TABCONFG"+TipoDriver)
                 USE TABCONFG.JAF
                 MSG("AGUARDE.... CRIANDO "+CARQCDX)
                 INDEX ON TAB_CODI TAG TABCONF1 TO TABCONFG
                 INDEX ON TAB_CONT TAG TABCONF2 TO TABCONFG
         ENDIF

//----- MENUJAF.JAF MENU DO SISTEMA USO SISTEMA.EXE

     CARQCDX := "MENUJAF"+TIPODRIVER
     CARQDBF := "MENUJAF.DBF"
     MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)

     ESTRU   := {}


      ESTRU       := { {"FUNCAO_001" , "C" , 20,0 },;
                       {"NRO_ACESSO" , "C" , 03,0 },;
                       {"MSG_000001" , "C" , 40,0 },;
                       {"TITULO_001" , "C" , 30,0 },;
                       {"TIPO_MENU"  , "C" ,  2,0 } }
       AADD(LISTADBF,{CARQCDX,CARQDBF})

       Ver_Dbf('MENUJAF.DBF',ESTRU)

       IF ! FILE("MENUJAF.DBF")
            CLOSE ALL
            MSG("AGUARDE.... CRIANDO "+CARQDBF)
            DBCREATE("MENUJAF.DBF",ESTRU )
            USE MENUJAF
            INDEX ON TITULO_001 TAG MENU TO MENUJAF
       ENDIF

//------ ARQUIVO DE MONITORAMENTO USUARIO NO SISTEMA
      CARQCDX := "MONITOR"+TIPODRIVER
      CARQDBF := "MONITOR.DBF"
      MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)



      Estru := { {"Usuario", "C", 15,0 },;
                 {"Data"   , "D",  8,0 },;
                 {"Entrada", "C",  8,0 },;
                 {"Saida"  , "C",  8,0 },;
                 {"Ip"      ,"C", 14,0 },;
                 {"Exec"    ,"C", 11,0 },;
                 {"Maquina" ,"C", 15,0 } }

      AADD(LISTADBF,{CARQCDX,CARQDBF})

      Ver_Dbf('MONITOR.DBF',ESTRU)

      If ! File("Monitor.dbf")
           MSG("AGUARDE.... CRIANDO "+CARQDBF)

           Dbcreate("Monitor.dbf",Estru)
           Use Monitor
           Index on Ip Tag Monitor To monitor
        ElseIf ! File("Monitor"+TipoDriver)
           MSG("AGUARDE.... CRIANDO "+CARQCDX)
           Use Monitor
           Index on Ip Tag Monitor To monitor
       Endif

//--- CADASTRO DE LOJAS E FILIAIS
      CARQCDX := "CADLOJAS"+TIPODRIVER
      CARQDBF := "CADLOJAS.DBF"
      MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)


      Estru := { { "CodLoja"   ,"C" , 03,0 },;
                 { "NomLoja"   ,"C" , 20,0 },;
                 { "Integrada" ,"C" , 01,0 } }
              AADD(LISTADBF,{CARQCDX,CARQDBF})

              Ver_Dbf('CADLOJAS.DBF',ESTRU)

        If ! File("CadLojas.dbf")
              MSG("AGUARDE.... CRIANDO "+CARQDBF)
              Dbcreate("CadLojas.dbf",Estru)
              Use CadLojas
              APPEND BLANK
              REPLA CODLOJA   WITH "001"
              REPLA NOMLOJA   WITH "MATRIZ"
              REPLA INTEGRADA WITH "S"
              Index on CodLoja Tag CadLojas to CadLojas
           ElseIf ! File("CadLojas"+TipoDriver)
              MSG("AGUARDE.... CRIANDO "+CARQCDX)
              Use CadLojas
              Index on CodLoja Tag CadLojas to CadLojas
        Endif

//--- CADASTRO DE LOJAS E FILIAIS

      CARQCDX := "SYSJAF"+TIPODRIVER
      CARQDBF := "SYSJAF.DIC"
      MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)


      Estru := { {"Nom_Arq" , "C" ,15,0 },;
                 {"Campo"   , "C" ,15,0 },;
                 {"Tipo"    , "C" , 1,0 },;
                 {"Tamanho" , "N" , 3,0 },;
                 {"Decimal" , "N" , 3,0 },;
                 {"Ocorren" , "C" ,20,0 } }
                 AADD(LISTADBF,{CARQCDX,CARQDBF})
                Ver_Dbf('SYSJAF.DIC',ESTRU)


            If ! File("SysJaf.Dic")
                 MSG("AGUARDE.... CRIANDO "+CARQCDX)
                 Dbcreate("SysJaf.Dic",Estru)

                 Use SysJaf.Dic
                 Index on Nom_Arq + Campo TAG SYSJAF to SysJaf
            ElseIf ! File("SysJaf"+TIPODRIVER)
                 MSG("AGUARDE.... CRIANDO "+CARQCDX)
                 Use SysJaf.Dic
                 Index on Nom_Arq + Campo TAG SYSJAF to SysJaf
            Endif

//--- CONTROLE DE NUMERO DE HD ACESSANDO O SISTEMA

      CARQCDX := "CtrlHd01"+TIPODRIVER
      CARQDBF := "CtrlHd01.jaf"
      MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)


      Estru := { { "HD", "C" , 20,0 },;
                 { "PC", "C" , 20,0 } }
          AADD(LISTADBF,{CARQCDX,CARQDBF})
          Ver_Dbf('CtrlHd01.jaf',ESTRU)


      If ! File("CtrlHd01.jaf")
          Dbcreate("CtrlHd01.jaf",Estru)

          MSG("AGUARDE.... CRIANDO "+CARQDBF)
          Use CtrlHd01.jaf
          Index on HD tag HD_001 to CtrlHd01
       ElseIf ! File("CtrlHd01"+TipoDriver)
          MSG("AGUARDE.... CRIANDO "+CARQCDX)
          Use CtrlHd01.jaf
          Index on HD tag HD_001 to CtrlHd01

      Endif



//--- CONTROLE DE ACESSO PERFIL DE USUARIO

      CARQCDX := "CADACESS"+TIPODRIVER
      CARQDBF := "CADACESS.DBF"
      MSG("AGUARDE.... VERIFICANDO ARQUIVOS DO SISTEMA "+CARQDBF)



       Estru := { {"CodAcess","C",03,0},;
                  {"DesAcess","C",40,0},;
                  {"ModAcess","C",15,0},;
                  {"Menu"    ,"C",01,0},;
                  {"Liberado","C",01,0} }
                 AADD(LISTADBF,{CARQCDX,CARQDBF})
                 Ver_Dbf('CadAcess.dbf',ESTRU)

        If ! File("CadAcess.dbf")
             MSG("AGUARDE.... CRIANDO "+CARQDBF)

             Dbcreate("CadAcess.dbf",estru)

             use CadAcess
             Index on CodAcess Tag Acess_01 To CadAcess
             Index on DesAcess Tag Acess_02 To CadAcess
             Index on ModAcess Tag Acess_03 To CadAcess

        ElseIf ! File("CadAcess"+TIPODRIVER)
             MSG("AGUARDE.... CRIANDO "+CARQCDX)

             use CadAcess
             Index on CodAcess Tag Acess_01 To CadAcess
             Index on DesAcess Tag Acess_02 To CadAcess
             Index on ModAcess Tag Acess_03 To CadAcess
        Endif


RETURN NIL

/------------------------------------------------------
Static Function Ver_Dbf(cDbf,cMatriz)
Local cArquivo    := cDbf
Local nTotCompos  := 0
Local DadoCampo   := {}
Local cCampos     := {}
Local cPesq
Local b
If XJAF_ARRUMAR==.F.
   Return .t.
ENDIF


If ! File(cArquivo)
    *Alerta("Arquivo nao localizado "+cArquivo)
     Return nil
Endif

//--- Carregando Estrutura do Dbf
      *Alerta("Arquivo :"+cArquivo)

       Close All
       Close All
       Sele 1
            Use (cArquivo) Alias _Arq

       Sele _Arq
      *Dbedit(00,00,24,79)

       nTotCompos := FCount()
       DadoCampo  := DbStruct()
       cCampos    := {}
       Close all
      *Clear Memory

       For B:=1 to nTotCompos
           *Aadd(cCampos,{Alltrim(Upper(DadoCampo[b,1])),DadoCampo[b,2],DadoCampo[b,3],DadoCampo[b,4]} )

            cFields := ALLTRIM(Upper(DadoCampo[b,1]))+;
                       Upper(DadoCampo[b,2])+;
                       Str(DadoCampo[b,3],7)+;
                       Str(DadoCampo[b,4],7)

            *Aadd(cCampos,ALLTRIM(Upper(DadoCampo[b,1])) ) // ,DadoCampo[b,2],DadoCampo[b,3],DadoCampo[b,4]} )
             Aadd(cCampos,cFields ) // ,DadoCampo[b,2],DadoCampo[b,3],DadoCampo[b,4]} )
       Next
       cErros := {}
       For x:= 1 to Len(cMatriz)
          *cPesq  := ALLTRIM(Upper(cMatriz[x,1]))

           cPesq   := ALLTRIM(Upper(cMatriz[x,1]))+;
                       upper(cMatriz[x,2])+;
                       Str(cMatriz[x,3],7)+;
                       Str(cMatriz[x,4],7)
          *nPos   := Ascan(cCampos,{|x|x[1]==cPesq})
           nPos   := Ascan(cCampos,cPesq)
           If nPos == 0
              *Alerta(cPesq+'-'+cCampos[x])
              cMsg := "Falta Campo :"+cPesq
              aadd(cErros,cMsg)
           Endif
       Next
      *Alerta("oi")
       If Len(cErros) > 0
          Cri_Dbf_Estru(cArquivo,cMatriz)
       Endif

Return nil
//--------------------------------------
Static Function Cri_Dbf_Estru(cDbf,cEstru)
Local nSize     := Len(cDbf)
Local cNomeFile := Substr(cDbf,1,nSize-4)
Local cNomeCdx  := Substr(cDbf,1,nSize-4)
Local cLocal    := Iif(Lerparam("DIRETORIODBA")=='','',Lerparam("DIRETORIODBA")+"\")
cNomeFile := 'converte.dbf'
//If File(cLocal+cNomeFile+'.Tmp')
//   Delete File (cLocal+cNomeFile+'.Tmp')
//Endif

If File(cLocal+cNomeFile)
   Delete File (cLocal+cNomeFile)
Endif

//Dbcreate(cNomeFile+'.Tmp',cEstru)
Dbcreate(cNomeFile,cEstru)

CLOSE ALL
CLOSE ALL
SET DELETED OFF
MSG("AGUARDE.... Arrumando Arquivo "+cDbf)
SELE 1
   //USE (cNomeFile+'.Tmp')
     USE (cNomeFile)
     Set index to 
     Append from (cDbf)

SET DELETED ON
CLOSE ALL
CLOSE ALL
CLOSE ALL
Delete File (cLocal+cDbf)
//Rename (cLocal+cNomeFile+'.Tmp') to (cLocal+cDbf )
Rename (cLocal+cNomeFile) to (cLocal+cDbf )
Close all
If File(cLocal+cNomeCdx+'.cdx')
   Delete File (cLocal+cNomeCdx +'.cdx')
Endif
CLOSE ALL
CLOSE ALL
Return nil
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
Eu uso uma aqui.
Basicamente, ela abre o DBF, antigo e compara a estrutura com o novo e importa.

Código: Selecionar todos

Function ChecaEstrutura(cDbf,aStruAtual,cDirSub)
LOCAL lRddLeto := .F., nTotRec, aStruAnt, lMudou:=.F.
LOCAL cDirDados := "\lugar_dos_dbfs\", cServidor := "\local_do_servidor_LetoDbf\"
hb_default(@cDirSub,"")

// Abrir o DBF VELHO
DbUseArea(.T.,iif(lRddLeto,"LETO","DBFCDX"), cDirSub + cDbf,cAlias,.T.,.F.,'PTISO')
nTotRec  := dbchk->(LastRec())  
aStruAnt := dbchk->(dbStruct()) //Pegar a estrutura do DBF velho.
(cDbf)->(DbCloseArea())    //fechar o DBF antigo.

if Len(aStruAnt) != Len(aStruAtual)
    lMudou := .t. //já viu que mudou a quantidade de campos, não precisa comparar mais nada, vai logo importar.
else
    for nCont := 1 to Len(aStruAtual) // Compara cada campo
        for nCont2 := 1 to 4 // Compara nome, tipo, tamanho e decimais
            if nCont2 <= 2
                aStruAtual[nCont,nCont2] := upper(aStruAtual[nCont,nCont2])
            endif
            If aStruAtual[nCont,nCont2] == aStruAnt[nCont,nCont2]
            Else
               //hwg_Msginfo('mudou: '+cDbf+" -- "+aStruAtual[nCont,nCont2]+" <> "+aStruAnt[nCont,nCont2])
               lMudou := .t.
               exit
            endif
        next
        If lMudou // Achou diferença já encerra
          exit
        EndIf
    next
endif

If lMudou   
   //Aqui os comandos para importar para o DBF com a nova estrutura.

   cCDX := substr(cDbf,1,at(".",cDbf))+'cdx'
   cFPT := substr(cDbf,1,at(".",cDbf))+'fpt'
      
   cDirDBF := cDirsUB + cDbf
   //Apagar o CDX via função do LetoDbf ou via função do Harbour.
   If lRddLeto
      If Leto_File(cServidor + cDirSub + cCDX)
        If Leto_fErase(cServidor + cDirSub + cCDX) > 0
          hwg_Msginfo('Erro ao Apagar o Arquivo: ' + cServidor + cDirSub + cCDX)
          FechaSistema()
        EndIf
      EndIf
   Else
      IF hb_vfExists(cDirDados + cDirSub + cCDX)
        if hb_vfErase(cDirDados + cDirSub + cCDX) > 0
          alert('Erro ao Apagar o Arquivo: ' + cDirDados + cDirSub + cCDX)
          FechaSistema()
        endif
      endif
   EndIF
  //Criar uma pasta para mover o DBF velho, tirei a parte do LetoDbf aqui para diminuir o código.
   If hb_DirExists(cDirDados + cDirSub + "arqvelho")
    Else
         If (MakeDir(cDirDados + cDirSub + "arqvelho")==0)
         Else
           alert('Sem Permissăo de Criar a Pasta.')
           FechaSistema() 
         Endif
      EndIf
     //Apagar o arquivo temporário se existir.
      IF hb_vfExists(cDirDados + cDirSub + "tmp_" + cDbf)
         if hb_vfErase(cDirDados + cDirSub + 'tmp_' + cDbf) > 0
            alert('Erro ao Apagar o Arquivo: ' + cDirDados + cDirSub + ', tmp_' + cDbf)
            FechaSistema()
         endif
      ENDIF
      IF hb_vfExists(cDirDados + cDirSub + "tmp_" + cFPT)
         if FErase(cDirDados + cDirSub + "tmp_" + cFPT ) > 0
            alert('Erro ao Apagar o Arquivo: ' + cDirDados + cDirSub + ', tmp_' + cFPT)
            FechaSistema()
         endif
      ENDIF

   //Criar o novo DBF com a nova estrutura
   BEGIN SEQUENCE WITH {| oErr | Break( oErr ) } 
      cTempDbf := iif(lRddLeto,cServidor,cDirDados) + cDirSub + 'tmp_' + cDbf            
      dbCreate(cTempDbf,aStruAtual, iif(lRddLeto,"LETO","DBFCDX") )
   Recover
      alert('Năo criou o arquivo: ' + cTempDbf + hb_eol() + " O sistema será encerrado.")
      FechaSistema()
   End Sequence

   //Abrir o DBF novo para importar os dados
   BEGIN SEQUENCE WITH {| oErr | Break( oErr ) } 
     DbUseArea(.t., iif(lRddLeto,"LETO","DBFCDX") , cTempDBF , "new" ,.f.,.f.,'PTISO') 
     //use (cTempDBF) new alias "dbc" exclusive via iif(lRddLeto,"LETO","DBFCDX")
   recover
      alert('Năo abriu o arquivo: '+cTempDBF+" O sistema será encerrado. Origem " + cDBF)
      FechaSistema()
   End Sequence
   //Abrir o DBF antigo para importar os dados
   BEGIN SEQUENCE WITH {| oErr | Break( oErr ) } 
     DbUseArea(.t., iif(lRddLeto,"LETO","DBFCDX") , cDBF , "old" ,.f.,.f.,'PTISO') 
   recover
      alert('Năo abriu o arquivo: '+cDBF+" O sistema será encerrado." + cDBF)
      FechaSistema()
   End Sequence
   MyAppendFrom("old","new",cTempDBF) 
   //Depois que importar, usar aqui rotinas para renomear. 
       IF hb_vfExists(cDirDados + cDirSub + 'old_' + cDBF)
          hb_vfErase(cDirDados + cDirSub + 'old_' + cDBF)
       ENDIF
       IF hb_vfRename(cDirDados + cDirSub + cDBF, cDirDados + cDirSub + 'old_' + cDBF) == -1
          alert( 'Error: '+Str(FERROR()) + hb_eol() + cDirDados + cDirSub + cDBF + ", Falha movendo para: " + cDirDados + cDirSub + 'old_' + cDBF)
          FechaSistema()
       EndIf       

       IF hb_vfExists(cDirDados + cDirSub + cFPT)       
          IF hb_vfExists(cDirDados + cDirSub + 'old_' + cFPT)
             hb_vfErase(cDirDados + cDirSub + 'old_' + cFPT)
          ENDIF       
          IF hb_vfRename(cDirDados + cDirSub + cFPT, cDirDados + cDirSub + 'old_' + cFPT) == -1
             Alert( cDirDados + cDirSub + cFPT + ": Falha movendo para: " + cDirDados + cDirSub + 'old_' + cFPT)
             FechaSistema()
          EndIf
       ENDIF 
       nErro   := FileMove(cDirDados + cDirSub + 'tmp_' + cDbf, cDirDados + cDirSub + cDbf)
       If nErro == 0
       Else
         alert("Năo moveu o arquivo, erro: "+str(nErro)+hb_eol()+"O Sistema Sera Cancelado.")
         FechaSistema()
       EndIf

      IF hb_vfExists(cDirDados + cDirSub + cFPT)
         nErro := FileMove(cDirDados + cDirSub + 'tmp_' + cFPT, cDirDados + cDirSub + cFPT)
         If nErro == 0
         Else
           alert("Năo moveu o arquivo, erro: "+str(nErro)+hb_eol()+"O Sistema Sera Cancelado.")
           FechaSistema()
         EndIf
      EndIf      

      If hb_vfRename(cDirDados + cDirSub + "tmp_" + cDbf, cDirDados + cDirSub + cDbf)>0
         hwg_Msginfo('Erro ao Renomear o Arquivo: ' + cDirDados + cDirSub + cDbf)
         FechaSistema()
      EndIf

      If hb_vfExists(cDirDados + cDirSub + "tmp_" + cFPT)
         If hb_vfRename(cDirDados + cDirSub + "tmp_" + cFPT, cDirDados + cDirSub + cFPT)>0
            hwg_Msginfo('Erro ao Renomear o Arquivo: ' + cDirDados + cDirSub + cFPT)
            FechaSistema()
         EndIf
      EndIf

endif
Return .T.

FUNCTION MyAppendFrom(cAO,cAD,cTempDBF) //cAO = Alias Origem, cAD Alias Destino
LOCAL nCount, nCampos := (cAD)->(FCount()), x:=1, nRec:=1, nTotRec := (cAO)->(LastRec())
//oBar := HProgressBar():NewBox("Importando " + cTempDBF + ", " + (cAO)->(Dbf()) + ": "+lTrim(str(1,9))+" De "+lTrim(Str(nTotRec,9))+" Registro(s)" ,,0,400,, nTotRec, nTotRec,,.f. )
DO WHILE (cAO)->(!Eof())
   (cAD)->(dbAppend())

   FOR nCount := 1 TO nCampos
      cField := (cAD)->(Field(nCount))      
      IF ( (cAO)->(fieldpos( cField )) != 0 )
         (cAD)->&cField := (cAO)->&cField
      ENDIF
   NEXT
   (cAO)->(dbSkip())
   //iif(x++==100,(nRec+=x,x:=1,ShowGrafico(oBar,nRec,nTotRec)),.t.)
EndDO

//oBar : Close()   
(cAD)->(DbCloseArea())    
(cAO)->(DbCloseArea())    

Return .T.
Função alterada, aqui para o forum.
Cortei algumas partes do LetoDbf, mas basta acrecentar "IF" se for usar LetoDbf.
A função nao apaga só renomeia os arquivos. Vai apagar se usar pela segunda vez o mesmo arquivo.

Código: Selecionar todos

ChecaEstrutura("clientes.dbf",fStruClientes(),cDirSub)

Function fStruClientes
Return    {{"idCliente"    ,"c",10,0},;
               {"cliente"       ,"c",60,0},;
               {"identidade" ,"c",15,0}}


Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Alterar campo de um DBF via sistema

Mensagem por JoséQuintas »

Há algumas limitações, e cuidados e serem tomados:

a) NÃO pode mudar o tipo de campo - caractere pra numérico e vice versa
b) Tem que lembrar o campo memo, que usa DBT ou FTP - arquivo separado

E o principal:

Teste muuuito, porque qualquer erro pode representar em perda de informações.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
a) NÃO pode mudar o tipo de campo - caractere pra numérico e vice versa
Pode, basta mexer na rotina de importação.
O "field" tem nome não é ? pois, então se field(x) == valor ..., field(y) := str(field(x)) ...
b) Tem que lembrar o campo memo, que usa DBT ou FTP - arquivo separado
Tá lá na importação isso, uso FPT, quem usa DBT(NTX) basta corrigir.
Teste muuuito, porque qualquer erro pode representar em perda de informações.
Não perde nada. O arquivo é renomeado depois de importado.


Uso isso há mais de 15 anos...

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Alterar campo de um DBF via sistema

Mensagem por JoséQuintas »

Itamar M. Lins Jr. escreveu:Não perde nada. O arquivo é renomeado depois de importado.
Uso isso há mais de 15 anos...
Ok, eu também uso há mais de 20 anos.
Mas lembro muito bem de vários problemas.
Tem até problema de numérico estourado, que interrompe tudo.
Aparece até problema de erro de disco, com letra gravada onde é número.

Uma coisa é fazer isso em ambiente controlado, outra coisa é colocar pra rodar em clientes, onde pode acontecer qualquer coisa, até usuário interromper no meio do caminho.

Em todo caso, segue o que uso no meu aplicativo, que SERVE PRA MIM, não significa que atende qualquer caso.
Convém destacar que nunca mais usei campo memo, desde quando memo causava índice corrompido no CLIPPER, nos tempos do Windows 98, por isso digo que a rotina SERVE PRA MIM, e pode não servir pra outros.

Código: Selecionar todos

/*
ZE_UPDATESTRU - Atualiza estruturas de DBF
José Quintas
*/

#include "dbstruct.ch"

FUNCTION ValidaStru( cDbfFile, mStruOk, lApagaAnterior, aDeleteList )

   LOCAL cTempFile, mSelect, nLastRec, mDbt, mDbfMemo, mMudaStru, mCdxName, nCont

   hb_Default( @lApagaAnterior, .F. )
   hb_Default( @aDeleteList, {} )

   IF Len( aDeleteList ) != 0
      FOR nCont = Len( mStruOk ) TO 1 STEP -1
         IF hb_ASCan( aDeleteList, mStruOk[ nCont, 1 ],,, .T. ) != 0
            hb_ADel( aDeleteList, nCont, .T. )
         ENDIF
      NEXT
   ENDIF
   IF ! ".DBF" $ Lower( cDbfFile ) .AND. ! ".TMP" $ Upper( cDbfFile )
      cDbfFile := cDbfFile + ".DBF"
   ENDIF
   mSelect  := Select()
   TestaNovaEstrutura( cDbfFile, @mStruOk )
   SELECT 0
   IF lApagaAnterior .OR. ! File( cDbfFile )
      dbCreate( cDbfFile, mStruOk )
      fErase( cDbfFile + ".CDX" )
      IF ! ".TMP" $ Upper( cDbfFile )
         GravaOcorrencia( ,, cDbfFile + ", Estrutura, criacao" )
      ENDIF
   ELSE
      mDbfMemo := Substr( cDbfFile, 1, Rat( ".", cDbfFile ) - 1 )
      fErase( mDbfMemo + ".DBT" ) // Apaga sempre que existir
   ENDIF
   USE ( cDbfFile ) ALIAS Validastru
   IF NetErr()
      USE
      MsgStop( cDbfFile + " não disponível, processo interrompido!" )
      SELECT ( mSelect )
      RETURN .F.
   ENDIF
   mMudaStru := ! ComparaEstrutura( cDbfFile, mStruOk )
   USE
   IF mMudaStru
      mCdxName := cDbfFile
      IF "." $ mCdxName
         mCdxName := Substr( mCdxName, 1, At( ".", mCdxName ) - 1 ) + ".CDX"
      ENDIF
      fErase( mCdxName )
      USE ( cDbfFile ) ALIAS ValidaStru EXCLUSIVE
      IF NetErr()
         USE
         MsgStop( "(" + cDbfFile + ") em uso, não pode ser atualizado!" )
         SELECT ( mSelect )
         RETURN .F.
      ENDIF
      ChecaAguarde( .T., "Atualização em andamento de " + cDbfFile )
      TestaCamposNumericos( cDbfFile, mStruOk )
      nLastRec := LastRec()
      USE
      Mensagem()
      SayScroll( cDbfFile + ", atualizando" )
      cTempFile := MyTempFile( "DBF", ".\" )
      dbCreate( cTempFile, mStruOk )
      USE ( cTempFile ) ALIAS ValidaStru EXCLUSIVE
      GrafTempo()
      APPEND FROM ( cDbfFile ) FOR GrafTempo( RecNo(), nLastRec + 1 )
      USE
      Mensagem()
      fErase( cDbfFile )
      fRename( cTempFile, cDbfFile )
      mDbt := Left( cDbfFile, Len( cDbfFile ) - 3 ) + "FPT"
      IF File( mDbt )
         fErase( mDbt )
      ENDIF
      IF File( Left( cTempFile, Len( cTempFile ) - 3 ) + "FPT" )
         fRename( Left( cTempFile, Len( cTempFile ) - 3 ) + "FPT", mDbt )
      ENDIF
      fErase( cDbfFile + ".CDX" )
      IF ! ".TMP" $ Upper( cDbfFile )
         GravaOcorrencia( ,, cDbfFile + ", Estrutura, Criado e/ou atualizado, Ok" )
      ENDIF
      fErase( "aguarde.txt" )
   ENDIF
   SELECT ( mSelect )

   RETURN .T.

STATIC FUNCTION TestaNovaEstrutura( cDbfFile, aStructure )

   LOCAL oElement, oElement2

   FOR EACH oElement IN aStructure
      oElement[ DBS_NAME ] := Upper( oElement[ DBS_NAME ] )
      IF Len( oElement[ DBS_NAME ] ) > 10
         MsgExclamation( "ValidaStru: Nome inválido " + cDbfFile + ", campo " + oElement[ DBS_NAME ] )
      ENDIF
      FOR EACH oElement2 IN aStructure
         IF oElement[ DBS_NAME ] == oElement2[ DBS_NAME ] .AND. oElement:__EnumIndex != oElement2:__EnumIndex
            MsgExclamation( "ValidaStru: Nome repetido " + cDbfFile + ", campo " + oElement[ DBS_NAME ] )
         ENDIF
      NEXT
      IF Len( oElement ) == 3 // Decimais zero quando nao definir
         AAdd( oElement, 0 )
      ENDIF
   NEXT

   RETURN NIL

STATIC FUNCTION ComparaEstrutura( cDbfFile, aNova )

   LOCAL oElement, oElement2, nNumCampo, lOk := .T., aArquivo, nCont

   aArquivo := dbStruct()
   FOR EACH oElement IN aNova
      nNumCampo := 0
      FOR EACH oElement2 IN aArquivo
         IF Pad( oElement[ DBS_NAME ], 10 ) == Pad( oElement2[ DBS_NAME ], 10 )
            FOR nCont = 2 TO 4
               IF oElement[ nCont ] != oElement2[ nCont ]
                  SayScroll( cDbfFile + " (*) " + oElement[ DBS_NAME ] )
                  lOk := .F.
               ENDIF
            NEXT
            nNumCampo := oElement2:__EnumIndex
         ENDIF
      NEXT
      IF nNumCampo == 0
         SayScroll( cDbfFile + " (+) " + oElement[ DBS_NAME ] )
         GravaOcorrencia( ,, cDbfFile+" (+) " + oElement[ DBS_NAME ] )
         lOk := .F.
      ENDIF
   NEXT
   FOR EACH oElement IN aArquivo
      nNumCampo := 0
      FOR EACH oElement2 IN aNova
         IF Pad( oElement[ DBS_NAME ], 10 ) == Pad( oElement2[ DBS_NAME ], 10 )
            nNumCampo := oElement2:__EnumIndex
            EXIT
         ENDIF
      NEXT
      IF nNumCampo == 0
         SayScroll( cDbfFile + " (-) " + oElement[ DBS_NAME ] )
         GravaOcorrencia( ,, cDbfFile  + " (-) " + oElement[ DBS_NAME ] )
         lOk := .F.
      ENDIF
   NEXT

   RETURN lOk

STATIC FUNCTION TestaCamposNumericos( cDbfFile, mStruOk )

   LOCAL mStruFile, aNumericos := {}, oElement, oElement2, cPicture, nValue

   SayScroll( cDbfFile + ", verificando antes de atualizar estrutura" )
   mStruFile := dbStruct()
   GOTO TOP
   FOR EACH oElement IN mStruFile
      GrafProc()
      IF oElement[ DBS_TYPE ] == "N"
         //Verifica se campo permanece, senao despreza checagem
         FOR EACH oElement2 IN mStruOk
            IF Pad( oElement[ DBS_NAME ], 10 ) == Pad( oElement2[ DBS_NAME ], 10 )
               IF oElement2[ DBS_DEC ] == 0
                  cPicture := Replicate( "9", oElement2[ DBS_LEN ] )
               ELSE
                  cPicture := Replicate( "9", oElement2[ DBS_LEN ] - oElement2[ DBS_DEC ] - 1 ) + "." + ;
                     Replicate( "9", oElement2[ DBS_DEC ] )
               ENDIF
               AAdd( aNumericos, { oElement:__EnumIndex, Val( cPicture ) } )
               EXIT
            ENDIF
         NEXT
      ENDIF
   NEXT
   IF Len( aNumericos ) > 0
      GrafTempo()
      DO WHILE ! Eof()
         GrafTempo( RecNo(), LastRec() + 1 ) // GrafProc()
         FOR EACH oElement IN aNumericos
            GrafProc()
            nValue := FieldGet( oElement[ 1 ] )
            IF nValue > oElement[ 2 ] .OR. nValue < -Int( oElement[ 2 ] / 10 )
               SayScroll( cDbfFile + ", inválido, " + FieldName( oElement[ 1 ] ) + ", reg." + LTrim( Str( Recno() ) ) + ", campo zerado" )
               GravaOcorrencia( ,, cDbfFile+", inválido, " + FieldName( oElement[ 1 ] ) + ", reg." + LTrim( Str( Recno() ) ) + ", campo zerado" )
               RecLock()
               FieldPut( oElement[ 1 ], 0 )
            ENDIF
         NEXT
         SKIP
      ENDDO
   ENDIF

   RETURN NIL
Acho que já comentei por aqui:
Em todos esses anos, UMA ÚNICA VEZ, a máquina carregava uma estrutura diferente a cada vez que o EXE era carregado.
A CPU estava com mau contato, e alterava as estruturas que faziam parte do EXE, causando atualização nos DBFs toda vez.
A imagem do monitor ficava piscando, por isso dava a impressão de que o problema era no monitor, mas na prática era a CPU com problema.
Foi uma única vez em 20 anos, mas aconteceu.

Talvez mais interessante primeiro garantir uma rotina de backup, antes de atualizar as estruturas, para o caso de algum imprevisto.

E sempre tem a opção de fazer fonte personalizado para determinado DBF, alterando tipos de campos, e qualquer coisa que queira.
Quanto mais personalizado, mais obrigatório que funcione direito, porque pode ficar sem segunda chance.
Por isso, garantir o backup pode ser a primeira coisa a ser feita, antes de qualquer mudança.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Alterar campo de um DBF via sistema

Mensagem por JoséQuintas »

Apenas exemplo, de um recente:

Código: Selecionar todos

   IF nVersaoDBF < 20200707.2
      JPBANCARIOCreateDbf( nVersaoDBF )
      JPBAAUTOCreateDbf( nVersaoDBF )
      JPBACCUSTOCreateDbf( nVersaoDBF )
   ENDIF
...
STATIC FUNCTION JPBACCUSTOCreateDbf( nVersaoDBF )

   LOCAL aStruList := { ;
      { "IDBACCUSTO", "C", 6 }, ;
      { "CUCCUSTO",   "C", 10 }, ;
      { "CUGRUPO",    "C", 10 }, ;
      { "CUMOSTRA",   "C", 1 }, ;
      { "CUINFINC",   "C", 80 }, ;
      { "CUINFALT",   "C", 80 } }

   IF nVersaoDBF < 20200707.2
      AAdd( aStruList, { "BGGRUPO",    "C", 10 } )
      AAdd( aStruList, { "BGRESUMO",   "C", 10 } )
      AAdd( aStruList, { "BGINFINC",   "C", 80 } )
      AAdd( aStruList, { "BGINFALT",   "C", 80 } )
   ENDIF

   SayScroll( "JPBACCUSTO.DBF, verificando atualizações" )
   IF ! ValidaStru( "jpbaccusto", aStruList )
      MsgStop( "jpbaccusto não disponível!" )
      QUIT
   ENDIF
   IF nVersaoDBF >= 20200707.2
      RETURN NIL
   ENDIF
   IF ! UseSoDbf( "jpbaccusto", .T. )
      QUIT
   ENDIF
   IF File( "jpbagrup.dbf" )
      IF ! ValidaStru( "jpbagrup", aStruList )
         QUIT
      ENDIF
      IF ! UseSoDbf( "jpbagrup", .T. )
         QUIT
      ENDIF
      GOTO TOP
      DO WHILE ! Eof()
         SELECT jpbaccusto
         RecAppend()
         REPLACE ;
            jpbaccusto->cuCCusto WITH jpbagrup->bgResumo, ;
            jpbaccusto->cuGrupo  WITH jpbagrup->bgGrupo, ;
            jpbaccusto->cuInfInc WITH jpbagrup->bgInfInc, ;
            jpbaccusto->cuInfAlt WITH jpbagrup->bgInfAlt
         SELECT jpbagrup
         RecDelete()
         SKIP
      ENDDO
      SELECT jpbagrup
      USE
      SELECT jpbaccusto
   ENDIF
   GOTO TOP
   DO WHILE ! Eof()
      RecLock()
      REPLACE jpbaccusto->idbaCCusto WITH StrZero( RecNo(), 6 )
      SKIP
   ENDDO
   CLOSE DATABASES

   RETURN JPBACCUSTOCreateDbf( 20200707.2 )
...
STATIC FUNCTION Update0707()

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   SayScroll( "2020-07-06" )
   SayScroll( "Salvando SQL.JPBANCARIO" )
   VerificaNumeracao( "JPBANCARIO", "IDBANCARIO" )
   CopyDbfToSQL( "JPBANCARIO", .T., .F., .T. )
   SayScroll( "Salvando SQL.JPBACCUSTO" )
   VerificaNumeracao( "JPBACCUSTO", "IDBACCUSTO" )
   CopyDBFToSQL( "JPBACCUSTO", .T., .F., .T. )
   SayScroll( "Salvando SQL.JPBAAUTO" )
   VerificaNumeracao( "JPBAAUTO", "IDBAAUTO" )
   CopyDBFToSQL( "JPBAAUTO", .T., .F., .T. )

   RETURN NIL
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Alterar campo de um DBF via sistema

Mensagem por gilbertosilverio »

Ola,

Obrigado a todos pelas dicas...
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
Uma coisa é fazer isso em ambiente controlado, outra coisa é colocar pra rodar em clientes, onde pode acontecer qualquer coisa, até usuário interromper no meio do caminho.
No meu sistema, só eu faço isso. Usuário comum não faz.
Para acontecer a atualização das estruturas, eu passo um parâmetro no arranque do sistema (linha de comando).
O sistema no modo normal, só abre em modo compartilhado, sem a possibilidade de atualização das estruturas.
Se o DBF está com campos detonados, nem vai fazer a IMPORTAÇÃO, portanto nem vai renomear, que dirá apagar.
Campos detonados já é outro problema, por conta de outros fatores, está no arquivo de origem, neste caso e detectar os registros e isolar.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
Gilberto,
aadd(a1, {'BASEST', 'N', 25, 9})
Pergunta, é assim mesmo um campo numérico ?
Nove(9) decimais ? Funciona ?

Eu uso no máximo 16 com 4 decimais.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
gilbertosilverio
Usuário Nível 3
Usuário Nível 3
Mensagens: 339
Registrado em: 18 Jan 2009 10:39
Localização: Ribeirao Pires - SP

Alterar campo de um DBF via sistema

Mensagem por gilbertosilverio »

Itamar,

Realmente, achei interessante, como nunca passou de milhão, sempre funcionou, mais se passar ai ele arredonda as decimais...

Uso assim a pedido de um contador "chato" que me questionava sempre as diferença dos calculo por arredondamento.

Nunca tinha percebido isso.
Anexos
t1.png
GilbertoSilverio
gilbertosilverio@gmail.com
gilbertosilverio2003@yahoo.com.br
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Alterar campo de um DBF via sistema

Mensagem por alxsts »

Boa tarde.

Tem que lembrar o seguinte: o tamanho máximo de uma coluna do tipo numérico em uma tabela DBF é 20 bytes, sendo que um byte é reservado para o sinal. Isto vem desde os tempos do dBase. Sendo assim, N, 25, 9 não vai funcionar...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Alterar campo de um DBF via sistema

Mensagem por JoséQuintas »

gilbertosilverio escreveu: Uso assim a pedido de um contador "chato" que me questionava sempre as diferença dos calculo por arredondamento.
Convém lembrar também que a precisão numérica é de 16 dígitos.

A diferença por arredondamento... se existe uma regra oficial, e usar a regra oficial, não há do que reclamar.
O valor unitário do produto pode ter várias decimais, se não me engano até 6 decimais, mas o valor total do produto obrigatoriamente deve ter 2 dígitos.
O cálculo de impostos da nota é por produto, se a soma da nota der diferença de imposto... não há o que fazer, está conforme a lei.

E tem aquela velha diferença de ponto flutuante que pode causar diferença em cálculos, até mesmo em uma simples soma.

Verifique exatamente qual é o problema, e use uma solução adequada.
Por exemplo: pegue uma nota aonde ele diz que tem diferença, e veja qual a fórmula que ele considera correta para cálculo.
Feito isso, ele não tem mais o que reclamar.

Voltando à diferença de ponto flutuante.....
Se somar a contabilidade, débitos e créditos, que deveria estar batido, nem sempre vai bater, dependendo se faz a comparação diretamente como valor, ou considerando a variação de ponto flutuante.
Pode mostrar na tela exatamente os mesmos valores e o aplicativo dizer que está diferente.
E não adianta aumentar casas decimais...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
O valor unitário do produto pode ter várias decimais, se não me engano até 6 decimais,
Também acredito que é 6 decimais o limite das linguagens, no calculo com ponto flutuante.
Mas estive procurando e tem o CURRENCY que é dinheiro, e o VARIANTE que é tipo variado igual aos SGBD da vida.(FoxPro)
Não sei como está isso no Harbour.
Achei...

Código: Selecionar todos

Harbour extended Field Types 

 Type Short
 Code Name Width (Bytes) Description
 ---- ------- ----------------- -------------------------------------------------------------------
 D Date 3, 4 or 8 Date
 M Memo 4 or 8 Memo
 + AutoInc 4 Auto increment
 = ModTime 8 Last modified date & time of this record
 ^ RowVers 8 Row version number; modification count of this record
 @ DayTime 8 Date & Time
 I Integer 1, 2, 3, 4 or 8 Signed Integer ( Width : )" },;
 T Time 4 or 8 Only time (if width is 4 ) or Date & Time (if width is 8 ) (?)
 V Variant 3, 4, 6 or more Variable type Field
 Y Currency 8 64 bit integer with implied 4 decimal
 B Double 8 Floating point / 64 bit binary
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

Código: Selecionar todos

PROCEDURE SG_Double() // Set / Get test for DOUBLE ( BINARY ) fields
LOCAL nRecno := 0

 LOCAL aStru11 := { { "Double", "B", 8, 4 } ,;
 { "NUM2D", "N", 21, 2 } ,;
 { "NUM4D", "N", 21, 4 } ,;
 { "NUM6D", "N", 23, 6 } ,;
 { "NUM8D", "N", 25, 8 } }
DBCREATE( "SG_Double", aStru11 )

 USE SG_Double

 FOR nRecno := 1 TO 100
 DBAPPEND()
 REPLACE Double WITH HB_RANDOM( -2^53, 2^53 ) / 10000 ,; 
 NUM2D WITH Double ,;
 NUM4D WITH Double ,;
 NUM6D WITH Double ,;
 NUM8D WITH Double 

 NEXT nRecno

 DBGOTOP() 
 BROWSE() 
 USE
RETURN // SG_Double()
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Alterar campo de um DBF via sistema

Mensagem por Itamar M. Lins Jr. »

Ola!
Eu nem sabia que era assim o VARIANTE. O campo aceita tudo, qualquer coisa: DATE/LOGICAL/NUMERIC/CHAR

Código: Selecionar todos

PROCEDURE SG_NoType() // Testing NoType ( Variant ) field type
LOCAL aStru5 := { { "Initial", "C", 19, 0 },;
 { "Internal", "V", 19, 0 },; 
 { "ReadBack", "C", 19, 0 },;
 { "ReadBackTp", "C", 1, 0 } }

 DBCREATE( "SG_NoType", aStru5 )

 USE SG_NoType

 DBAPPEND()
 REPLACE Initial WITH "String", Internal WITH "String"
 DBAPPEND()
 REPLACE Initial WITH "12345", Internal WITH 12345
 DBAPPEND()
 REPLACE Initial WITH DTOC( DATE() ), Internal WITH DATE()
 DBAPPEND()
 REPLACE Initial WITH ".T.", Internal WITH .T.

 REPLACE ALL ReadBack WITH HB_ValToStr( Internal ), ReadBackTp WITH VALTYPE( Internal )

 DBGOTOP()

 BROWSE()
 USE

RETURN // SG_NoType()
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Responder