Page 1 of 2

Modificar estructura de una DBF

Posted: Fri Feb 19, 2021 8:21 pm
by arroya2
Hola a todos.

Necesito modificar varias DBF con datos que tienen la misma estructura. Puedo hacerlo una a una con ourXdbu manualmente, pero me va a tomar mucho tiempo.
¿Hay alguna forma de hacerlo mediante un programa hecho con HMG con el que pueda modificar el nombre de algunos campos e insertar otros nuevos en una posición determinada, sin perder ningún dato?
Muchas gracias

Un saludo
Rafael Pérez

Re: Modificar estructura de una DBF

Posted: Fri Feb 19, 2021 8:30 pm
by jparada
Hola Rafael,
No he probado estos códigos, valida si te pueden ayudar, obvio con respaldos y dbf de pruebas primero

https://www.tek-tips.com/viewthread.cfm?qid=1356199
http://www.kresin.ru/en/prcother.html

Saludos,
Javier

Re: Modificar estructura de una DBF

Posted: Fri Feb 19, 2021 8:35 pm
by arroya2
Gracias Javier
Mañana lo miraré y si soy capaz de usarlo te contaré.

Un saludo
Rafael Pérez

Re: Modificar estructura de una DBF

Posted: Sat Feb 20, 2021 1:11 pm
by AUGE_OHR
hi,

when change Name of Field you have to use FIELDGET() / FIELDPUT()

Structure of DBF can be shown by DBSTRUCT().
let say you want to Change FIELD "AAA" to "BBB" so you have to ASCAN() Result of DBSTRUCT() for Position of "AAA"

dummy code

Code: Select all

   SELECT 1
   USE XYZ
   aStruc := DBSTRUCT()
   nLen :? LEN(aStruc)
   nPosi := ASCAN(aStruct,{ |e| e[1] = "AAA" } )
   sStruct[nPosi][1) := "BBB"

   SELECT 2
   DbCreate( "NEWDBF", aStruct, "DBFNTX" )
   USE "NEWDBF"
   SELECT 1  
   DO WHILE !EOF
      NEWDBF->( DbAppend() )
      i := 1
      FOR i := 1 TO nLen
         xValue := XYZ->( FieldGet( i )		
         NEWDBF->(FieldPut(i),xValue) 
      NEXT
      SELECT 1
      SKIP
   ENDDO
   CLOSE ALL
   
   FERASE("XYZ.DBF")
   RENAME "NEWDBF.DBF" TO "XYZ.DBF"
   
   

Re: Modificar estructura de una DBF

Posted: Sun Feb 21, 2021 4:44 pm
by arroya2
Hola Jimmy
Muchas gracias por la respuesta.
La solución que me has aportado, me resulta más sencilla y directa que la que me propuso el amigo Javier, al menos con los conocimientos que poseo.
Gracias de nuevo.

Saludos
Rafael Pérez

Re: Modificar estructura de una DBF

Posted: Tue Feb 23, 2021 11:41 am
by mol
I'm still using DBU for manual changing of dbf files.
Sources are available in harbour contrib. You can compile it

Re: Modificar estructura de una DBF

Posted: Tue Feb 23, 2021 12:01 pm
by AUGE_OHR
hi,
mol wrote: Tue Feb 23, 2021 11:41 am I'm still using DBU for manual changing of dbf files.
but it will not work correct if you change FIELD Name.

Re: Modificar estructura de una DBF

Posted: Tue Feb 23, 2021 6:29 pm
by mol
It works OK when you change field name.
But, when you want do more changes, it's necessary to do it step by step saving structure everytime.

Re: Modificar estructura de una DBF

Posted: Tue Feb 23, 2021 9:43 pm
by movilceles
Hola Rafael,

Esta es una funcion mu simple que hice para modificar tablas dbf de forma automatica o manual.

Se le pasan dos parametros, el nombre del dbf y la matriz con la estructura deseada.

Si estas en red y detecta que la dbf esta en uso retorna y no es actualizada, en caso contrario continua
efectua una copia de seguridad y modifica la estructura.

Puedes añadir o modificar campos, no debes de modificar el tipo de datos o nombres de campos que
contengan registros ya que perderias la informacion.

Espero te sirva, es una funcion sencilla y muy util.

Code: Select all

/************************************************************************************************/
FUNCTION CG_MODIFICA_DBF(cNDBF,aStruc)   //FUNCION PARA MODIFICAR TAMAÑO CAMPOS O AÑADIR CAMPOS
/************************************************************************************************/

         // --------------------------------------------------------------------------
         //                   !!! ATENCION !!! - LIMITACIONES !!
         // --------------------------------------------------------------------------
         // - SOLO SE PUEDE:
         //   Añadir nuevos campos, (se pueden añadir en el orden que se quiera).
         //   Modificar el tamaño de los campos.
         //   Se pueden reordenar los campos.
         //
         // - EN CAMPOS QUE CONTENGAN REGISTROS NO SE PUEDE:
         //   Modificar el tipo de datos.
         //   Modificar nombre de los campos ya existentes.
         // --------------------------------------------------------------------------
         //          !! SI NO SE CUMPLEN ESTAS NORMAS SE PERDERAN DATOS !!
         // --------------------------------------------------------------------------

         //Creo temporal
         cCopiSegu:="Segu_" + cNDBF + "_F" + StrTran(DToC(Date()),"/") + "_H" + StrTran(TIME(),":")
         cBdTemp  :="TEMP" + AllTrim(Str(RANDOM()))
         DBCreate( (cBdTemp) , aStruc )
         USE (cBdTemp) EXCLUSIVE NEW
         StruNueva:=DBSTRUCT()
         CLOSE (cBdTemp)

         //En red si algun usuario esta usando la base de datos se sale ya
         //que si comparamos una bd miestras esta siendo usada siempre daria
         //valores diferentes y provocaria una falsa actualizacion
         USE (cNDBF) EXCLUSIVE NEW
         IF NETERR()
            CLOSE (cNDBF)
            ERASE ( (cBdTemp) + ".DBF" )
            ERASE ( (cBdTemp) + ".DBT")
            RETURN Nil
         ENDIF
         
         StruVieja:=DBSTRUCT()

         cCOM1:=HB_ValToExp(StruVieja) //Convierte a cadena
         cCOM2:=HB_ValToExp(StruNueva)

         //SI SE A MODIFICADO O AÑADIDO ALGUN CAMPO PROCEDE
         IF cCOM1<>cCOM2
            IF !MsgYesNo("SE A DETECTADO ACTUALIZACION DE LA BASE DE DATOS: " + AllTrim(cNDBF) +".DBF" + CHR(13) + CHR(10) + ;
                CHR(13) + CHR(10) + "EN EL DIRECTORIO: " + GETCURRENTFOLDER() + CHR(13) + CHR(10) + ;
                + CHR(13) + CHR(10) + "DESEA ACTUALIZAR AHORA ?","AVISO - ACTUALIZACION DETECTADA")
            ELSE
               COPY TO (cCopiSegu) //& Crea precopia de seguridad
               Inkey(1)
               USE (cBdTemp)
               APPEND FROM (cNDBF)          //& Importa registros del dbf viejo
               COPY TO (cNDBF)              //& Aplica los cambios en el dbf
               Inkey(1)
               CLOSE (cBdTemp)
               MsgInfo("ESTRUCTURA BASE DATOS: -> " + cNDBF + ".DBF -> HA SIDO MODIFICADA","AVISO")
            ENDIF
         ENDIF

         CLOSE (cNDBF)

         //Observacion: Erase solo funciona en el directorio actual del dos
         ERASE ( (cBdTemp) + ".DBF" ) //Borra tmp DBF
         ERASE ( (cBdTemp) + ".DBT" ) //Borra tmp DBT, si los hubiera

RETURN Nil

Re: Modificar estructura de una DBF

Posted: Tue Feb 23, 2021 10:45 pm
by AUGE_OHR
hi Mol,
mol wrote: Tue Feb 23, 2021 6:29 pm It works OK when you change field name.
i was sure that it will fail when change FIELD Name ...
now i have test it with DBU and it work :o

so you are right