Modificar estructura de una DBF

HMG en Español

Moderator: Rathinagiri

arroya2
Posts: 172
Joined: Thu Aug 06, 2009 7:16 am

Modificar estructura de una DBF

Post 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
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: Modificar estructura de una DBF

Post 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
arroya2
Posts: 172
Joined: Thu Aug 06, 2009 7:16 am

Re: Modificar estructura de una DBF

Post by arroya2 »

Gracias Javier
Mañana lo miraré y si soy capaz de usarlo te contaré.

Un saludo
Rafael Pérez
User avatar
AUGE_OHR
Posts: 2117
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: Modificar estructura de una DBF

Post 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"
   
   
have fun
Jimmy
arroya2
Posts: 172
Joined: Thu Aug 06, 2009 7:16 am

Re: Modificar estructura de una DBF

Post 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
User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Modificar estructura de una DBF

Post by mol »

I'm still using DBU for manual changing of dbf files.
Sources are available in harbour contrib. You can compile it
User avatar
AUGE_OHR
Posts: 2117
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: Modificar estructura de una DBF

Post 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.
have fun
Jimmy
User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Modificar estructura de una DBF

Post 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.
movilceles
Posts: 20
Joined: Sun Dec 04, 2016 1:43 pm
DBs Used: DBF
Location: Murcia - España

Re: Modificar estructura de una DBF

Post 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
Celes
Saludos / Regards :P - :idea: Cuanto mas simple mejor !! / The simpler the better !!
User avatar
AUGE_OHR
Posts: 2117
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: Modificar estructura de una DBF

Post 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
have fun
Jimmy
Post Reply