importación de un excel a dbf

133 views
Skip to first unread message

Daniel Aisenberg

unread,
Dec 3, 2021, 12:27:17 PM12/3/21
to harbou...@googlegroups.com
Buenas tardes:

Implementé un procedimiento para tomar un archivo excel e importarlo a dbf.
La estrategia utilizada fue:
Abrir el excel como objeto OLE.
Exportarlo a CSV
Uso del comando Append from, para tomar el CSV

Tengo 2 preguntas:
1: si hay una manera más eficiente para hacer eso
2: tengo un problema cuando en lugar de usar Coma, usa "punto y coma" (colon) como separador. Hay manera de predeterminarlo, pero desde el código,  sin necesidad de tocar la configuración regional?

Gracias


Jose Antonio Leon Tellez

unread,
Dec 3, 2021, 9:24:24 PM12/3/21
to harbou...@googlegroups.com
Buenas noches Daniel,

Esta función convierte un archivo xls a dbf.

************************************
function xls2dbf(marchxls,aDbf)
************************************
* marchxls       archivo excel    
* aDbf           array de la estructura del DBF
LOCAL oExcel, oSheet
LOCAL nRows := 0
LOCAL nCols := 0
LOCAL cVar := ""
LOCAL n := 0
LOCAL m := 0
LOCAL cArtNr := ""
LOCAL cBuf := ""
LOCAL nSheets := 0

#ifndef __XHARBOUR__
   IF( oExcel := win_oleCreateObject( 'Excel.Application' ) ) == NIL
      MsgStop( 'Error: Excel no está disponible [' + win_oleErrorText()+ ']' )
      RETURN NIL
   ENDIF
#else
   oExcel := TOleAuto():New( 'Excel.Application' )
   IF Ole2TxtError() != 'S_OK'
      MsgStop( 'Error: Excel no está disponible.' )
      RETURN NIL
   ENDIF
#endif

DBCREATE("c:\temp\temporal",aDbf)
select h
use c:\temp\temporal exclusive

oExcel:WorkBooks:Open(marchxls)
oSheet := oExcel:ActiveSheet()
nCountCol := oSheet:UsedRange:Columns:Count()
nCountRow := oSheet:UsedRange:Rows:Count()
msginfo('Columnas:'+tran(nCountCol,'999,999')+"       Filas:"+tran(nCountRow,'999,999'))
mnummovi:=nCountRow-1

merrx:=0
for j:=1 to nCountCol
    mnomcolv=oSheet:Cells(1, j ):Value
    if type('mnomcolv')#'C'
       msginfo('Error en Nombre de columna #'+tran(j,'9999')+' no corresponde; No se leeran datos de esta columna, Tipo de dato:'+type('mnomcolv'))
       merrx++
    endif
next
if merrx=nCountCol
   mmensaje:='No se lee ningun dato, no hay columnas con nombre validos'
   MSGinfo(mmensaje)
else
***  en la Hoja de excel, la primera fila esta el nombre de la columnas, no interesa en que orden estan las columnas
*** se lee celda por celda, es lenta la lectura cuando el excel es grande
   for i:= 2 TO mnummovi+1
       append blank
       for j:=1 to nCountCol
           mnomcolv=oSheet:Cells(1, j ):Value
           if type('mnomcolv')='C'
              mnomcol=alltrim(oSheet:Cells(1, j ):Value)
              mdato=oSheet:Cells(i, j ):Value
              for k:=1 to len(aDbf)
                  if alltrim(upper(mnomcol))==alltrim(upper(aDbf[k,1]))
                     mnomcol=upper(aDbf[k,1])
                     mtipodato=upper(aDbf[k,2])
                     mlongdato=aDbf[k,3]
                     mdecidato=aDbf[k,4]
                     IF mtipodato='N'
                        mvaln=0
                        if type('mdato')='N'
                           mvaln=mdato
                        elseif type('mdato')='C'
                           mvaln=val(mdato)
                        endif
                        replace &mnomcol with mvaln
                     ENDIF
                     IF mtipodato='C'
                        mvalC=""
                        if type('mdato')='C'
                           mvalC=mdato
                        elseif type('mdato')='N'
                           mvalC=str(mdato,mlongdato,mdecidato)
                        endif
                        replace &mnomcol with alltrim(mvalC)
                     ENDIF
                     IF mtipodato='D'
                        mvalD=ctod("  /  /    ")
                        if type('mdato')='D'
                           mvalD=mdato
                        endif
                        replace &mnomcol with mvalD
                     ENDIF
                     IF mtipodato='L'
                        mvall=.f.
                        if type('mdato')='L'
                           mvalL=mdato
                        endif
                        replace &mnomcol with mvalL
                     ENDIF
                     K:=LEN(aDbf)+1
                  endif
              next
           endif
       next
   next
endif
oExcel:Visible := .T.
oSheet := NIL
oExcel := NIL
return nil


Saludos,


José Antonio León Téllez




--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/CACAt13xysynZR7Vt8Vjac%3D%2BhCSSjYZWQ3R15DHOE%2Bw_aSR-xPA%40mail.gmail.com.

Auge & Ohr

unread,
Dec 4, 2021, 4:44:22 AM12/4/21
to Harbour Users
hi,

after these lines


>   nCountCol := oSheet:UsedRange:Columns:Count()
>   nCountRow := oSheet:UsedRange:Rows:Count()

   // create empty Array with same Size
   aExcel := ARRAY(nCountRow,nCountCol)

   // convert Col to A - Z
   cEnde := ZAHL2CHR(nCountCol)

   // now "paste" all to Array
   aExcel := oSheet:range( "A1:"+cEnde+LTRIM(STR(nCountRow)) ):value
   
   // use Array to "fill" DBF
   Do_Append(aExcel)

Jimmy
Reply all
Reply to author
Forward
0 new messages