Page 1 of 1

Leer Excel XLSX grande a un array o DBF

PostPosted: Fri Feb 04, 2022 11:18 pm
by Enrrique Vertiz
Buenas tardes

Tengo FWH 20.04 y necesito leer un excel de 1,000,000 de lineas y casi 30 columnas que manda un cliente y solo lo puede/quiere mandar en Excel, uso la TExcel y claro funciona, pero demora casi 15 horas, algo mas rapido para poder leer registro x registro y guardarlo despues como datos, levantarlo en un array o en un DBF, alguien algun ejemplo funcional, GRACIAS

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 10:47 am
by leandro
Enrique buenos días

Pues desde nuestra experiencia un millón de registros, le cuesta mucho tiempo de proceso, a cualquier procesador (valga la redundancia), hasta un CORE I7, es mucha información, no se si sea bueno que la separes en varios archivos antes de validarla, como experiencia nosotros importamos desde excel un archivo de 10.000 registros, pero no tardo tanto tiempo, aproximadamente seis minutos.

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 3:39 pm
by Enrrique Vertiz
Gracias Leandro

Lo que pasa es que el cliente lo recibe asi de otro sistema y no quiere meter mano, quiere que se importe "tal cual" ...
Una idea es grabarlo como CSV y de ahi hacerle un APPEND FROM, por el volumen puede que tome varios minutos, por eso me gustaria ponerle un "progress bar", alguien tendra un ejemplo deAPPEND FROM con PROGRESS BAR, vi uno aqui en el foro pero no logro hacerlo funcionar :


MsgRun("Espere importando", "Importacion de Movimientos desde un archivo Excel CSV", { || muestraprogreso(nPercent1,oMtr1) })

FUNCTION muestraprogreso(nPercent1, oMtr1)
APPEND FROM &cFile WHILE (nPercent1++, oMtr1:Set(nPercent1), IIF( (nPercent1/1000 - int(nPercent1/1000)) = 0 , SysRefresh(), ), TRUE ) DELIMITED WITH ({,";"})
RETURN (.T.)

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 4:31 pm
by George
Podrias probar pasando primero el archivo CSV a un array ya que esto lo hace bien rapido.

#include "FIVEWIN.CH"

FUNCTION Main()
LOCAL cMsgRun := "Procedure in execution; please Wait...", cMsgArrayData := "Creating CSV array data; please wait..."
LOCAL nStart := Seconds(), nEnd, aData := {}, cText := "", cMsgMemo := "Reading CSV data source; please wait..."


//===================================================================================================================
// STEP ONE: Read CSV File
//===================================================================================================================
cFileCSV = "your_file.csv"
MsgRun(cMsgMemo, "Main", { | | cText := fCSVMemo(cFileCSV) })
Sysrefresh()

//===================================================================================================================
// STEP TWO: Read each line and save the result in array aData
//===================================================================================================================
MsgRun(cMsgArrayData, "Main", { | | aData := HB_ATokens( cText, Chr(1), .t., .t. ) })
syswait(.05)
Sysrefresh()

? "Total rows: ", len(aData), " ", "Delay (secs): ", (Seconds() - nStart)

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 4:33 pm
by George
Faltó es pequeña función

FUNCTION fCSVMemo(cFileCSV)
cText := StrTran( MemoRead( cFileCSV ), CRLF, Chr(1) )
RETURN (cText)

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 6:01 pm
by leandro
Amigo puedes hacerlo directamente desde Excel, esta función convierte el Excel a un array de tipo hash

Code: Select all  Expand view


Function recupera(cRtaXls)
Local hLinea := {=>}
Local aDatos := {}
Local oExcel,oBook,oHoja
Local nTotRowCount := 0
Local nTotColCount := 0
Local nContador := 1

oExcel:= TOleAuto():New("Excel.Application")
oBook := oExcel:Workbooks:Open(cRtaXls)
oHoja := oExcel:Get( "ActiveSheet" )

nTotRowCount:= oHoja:UsedRange:Rows:Count()
nTotColCount:= oHoja:UsedRange:Columns:Count()

//oMeter:nTotal = nTotRowCount
//oMeter:Set( 0 )

FOR Q=1 TO nTotRowCount

    FOR b:=1 TO nTotColCount
        cNmcol := "COL"+cvaltochar(b)  
        hLinea[cNmcol] := oHoja:Cells( Q, b ):Value
    NEXT   
    AADD(aDatos,hLinea)
    hLinea := {=>}

    nContador++ 
    //oMeter:Set( nContador )   

NEXT
oExcel:WorkBooks:Close()
oExcel:Application:Quit()
oExcel:Quit()
oExcel := NIL

xbrowse(aDatos)

Return nil
 

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Sat Feb 05, 2022 6:11 pm
by Enrrique Vertiz
George, Leandro

Muchas gracias por sus respuestas, probare cada caso a ver cual mejor me resulta, GRACIAS !!!

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Thu Aug 10, 2023 3:35 am
by nageswaragunupudi
leandro wrote:Amigo puedes hacerlo directamente desde Excel, esta función convierte el Excel a un array de tipo hash

Code: Select all  Expand view


Function recupera(cRtaXls)
Local hLinea := {=>}
Local aDatos := {}
Local oExcel,oBook,oHoja
Local nTotRowCount := 0
Local nTotColCount := 0
Local nContador := 1

oExcel:= TOleAuto():New("Excel.Application")
oBook := oExcel:Workbooks:Open(cRtaXls)
oHoja := oExcel:Get( "ActiveSheet" )

nTotRowCount:= oHoja:UsedRange:Rows:Count()
nTotColCount:= oHoja:UsedRange:Columns:Count()

//oMeter:nTotal = nTotRowCount
//oMeter:Set( 0 )

FOR Q=1 TO nTotRowCount

    FOR b:=1 TO nTotColCount
        cNmcol := "COL"+cvaltochar(b)  
        hLinea[cNmcol] := oHoja:Cells( Q, b ):Value
    NEXT   
    AADD(aDatos,hLinea)
    hLinea := {=>}

    nContador++ 
    //oMeter:Set( nContador )   

NEXT
oExcel:WorkBooks:Close()
oExcel:Application:Quit()
oExcel:Quit()
oExcel := NIL

xbrowse(aDatos)

Return nil
 


This can also be written as:
Code: Select all  Expand view
oRange := GetExcelRange( cExelFileWithFullPath )
aData := xlRangeValue( oRange )
XBROWSER aData

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Thu Aug 10, 2023 6:17 am
by Jimmy
hi,

if you use FWH 64 Bit it is no Problem to use 1.000.000 Row of Excel Sheet with ADO without Array

Code: Select all  Expand view
FUNCTION ADOsheet( cPathcFile )
LOCAL objRS, oBrw
LOCAL cSheet, cRange, lHeaders := .T.

   objRS := FW_OpenADOExcelSheet( cPathcFile, cSheet, cRange, lHeaders )
 
   @ nBhight,  2 XBROWSE oBrw SIZE nWidth - 20, nHeight - 90 PIXEL OF oWnd ;
              RECORDSET objRS FASTEDIT ;
              AUTOCOLS ;
              CELL LINES NOBORDER UPDATE ;
              FONT oFontDefault COLOR BFcolor, BGcolor

this CODE work also under 32 Bit but over 500.000 Row it might crash when MEMORY is low of 32 Bit App

---

instead of XBROWSE you can use Record-Set to create a DBF or SQL-Table

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Thu Aug 10, 2023 5:44 pm
by Enrrique Vertiz
Hi Mr. Rao

Unresolved external _HB_FUN_FW_GetExcelRange
Unresolved external _HB_FUN_xlValue

I use FWH 23.07, Thanks

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Thu Aug 10, 2023 6:01 pm
by karinha

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Thu Aug 10, 2023 8:27 pm
by nageswaragunupudi
Enrrique Vertiz wrote:Hi Mr. Rao

Unresolved external _HB_FUN_FW_GetExcelRange
Unresolved external _HB_FUN_xlValue

I use FWH 23.07, Thanks

Very sorry, I corrected the mistakes.
Please see my edited posting again.
the functions are:
GetExcelRange .. not FW_GetExcelRange
and
xlRangeValue ... not xlValue

Code: Select all  Expand view
oRange := GetExcelRange( cExelFileWithFullPath )
aData := xlRangeValue( oRange )
XBROWSER aData

Re: Leer Excel XLSX grande a un array o DBF

PostPosted: Fri Aug 11, 2023 5:24 pm
by Enrrique Vertiz
GRACIAS Karinha, Rao !!!