Page 1 of 1

array to Excel

Posted: Tue Jun 16, 2026 3:55 pm
by ralph

Necesito pasar un array 2D a Excel.
Al ejecutar este test, no se copia nada en el excel.

Code: Select all | Expand

PROCEDURE TestMatriz()
   LOCAL oExcel, oWorkbook, oSheet
   LOCAL aDatos := {}

   oExcel := CreateObject( "Excel.Application" )
   oExcel:Visible := .T.
   oWorkbook := oExcel:Workbooks:Add()
   oSheet    := oExcel:ActiveSheet

   aDatos := { ;
      { "Producto A", 120.50, 10 }, ;
      { "Producto B",  85.00, 22 }, ;
      { "Producto C",  45.15, 15 }  ;
      }

   oRange := oSheet:Range( "A1:C3" )
   oRange:Value := aDatos
   
RETURN

Si funciona esto:

Code: Select all | Expand

oRange:Value := aDatos[1]

Pero ejecutarlo en un loop no es eficiente para arrays grandes, como es mi caso.

Consultando con la IA me responde:

En las versiones recientes de FiveWin para Harbour (no xHarbour), Antonio Linares añadió soporte para escribir arrays completos mediante SAFEARRAY COM. Sin embargo, en xHarbour 123_10120 ese soporte suele ser limitado o inexistente.

Por eso, aunque encuentres ejemplos en Internet como:

oRange:Value := aMatrix

muchos funcionan en Harbour puro y no necesariamente en xHarbour.
...
...
El problema es que ni xHarbour ni FiveWin exponen públicamente una función tipo ArrayToVariant() para matrices 2D, pero sí puedes construir el SAFEARRAY mediante:

SafeArrayCreate()
SafeArrayPutElement()
VariantInit()

y luego pasarlo como VARIANT al objeto COM.

Antonio, me das alguna pista sobre los SAFEARRAY ?


Re: array to Excel

Posted: Tue Jun 16, 2026 5:32 pm
by Antonio Linares

Estimado Ralph,

Hazlo asi:

Code: Select all | Expand

PROCEDURE TestMatriz()  
LOCAL oExcel, oWorkbook, oSheet, oRange
LOCAL aDatos := { ;
{ "Producto A", 120.50, 10 }, ;
{ "Producto B", 85.00, 22 }, ;
{ "Producto C", 45.15, 15 } ;
}
LOCAL n
oExcel := CreateObject( "Excel.Application" )
oExcel:Visible := .T.
oWorkbook := oExcel:Workbooks:Add()
oSheet := oExcel:ActiveSheet
oExcel:ScreenUpdating := .F.
oRange := oSheet:Range( oSheet:Columns( 1 ), oSheet:Columns( Len( aDatos[1] ) ) )
for n := 1 to Len( aDatos )
oRange:Rows( n ):Value := aDatos[ n ]
next
oExcel:ScreenUpdating := .T.
RETURN

Re: array to Excel

Posted: Tue Jun 16, 2026 6:44 pm
by karinha

Maestro, esto es justo lo que necesitaba. Muchas gracias por el modelo.Y puede mejorar aún más.

Code: Select all | Expand

// C:\FWH2603\SAMPLES\RALPH1.PRG

#include "FiveWin.ch"

PROCEDURE TestMatriz()
  
LOCAL oExcel, oWorkbook, oSheet, oRange, oBook LOCAL aDatos := { ;
{ "Producto A" , 120.50, 10 }, ; { "Producto B", 85.00, 22 }, ; { "Producto C", 45.15, 15 } ; }
LOCAL n
oExcel := CreateObject( "Excel.Application" ) oExcel:Visible := .T. oWorkbook := oExcel:Workbooks:Add() oSheet := oExcel:ActiveSheet oExcel:ScreenUpdating := .F. oRange := oSheet:Range( oSheet:Columns( 1 ), oSheet:Columns( Len( aDatos[1] ) ) ) for n := 1 to Len( aDatos ) oRange:Rows( n ):Value := aDatos[ n ] next oSheet:Columns( "A" ):ColumnWidth := 12 // / Alinhamento Horizontal (1: Esquerda, 2: Centro, 3: Direita) oSheet:Cells( 1, 1 ):HorizontalAlignment := 1 // Border oSheet:Cells( 1, 1 ):Borders(1):LineStyle := 1 // Contorno oSheet:Cells( 1, 1 ):Borders(1):Weight := 2 // Espessura // Estilo da Fonte oSheet:Cells( 1, 1 ):Font:Name := "Arial" oSheet:Cells( 1, 1 ):Font:Size := 10 oSheet:Cells( 1, 1 ):Font:Bold := .T. oSheet:Cells( 1, 1 ):Font:ColorIndex := 3 oSheet:Columns( "B" ):ColumnWidth := 12 oSheet:Cells( 1, 2 ):NumberFormat := "$ #.##0,00" oSheet:Cells( 1, 2 ):Font:ColorIndex := 3 oSheet:Cells( 1, 2 ):Font:Name := "Arial" oSheet:Cells( 1, 2 ):Font:Size := 10 oSheet:Cells( 1, 2 ):Font:Bold := .T. oSheet:Cells( 2, 2 ):NumberFormat := "$ #.##0,00" oSheet:Cells( 2, 2 ):Font:ColorIndex := 4 oSheet:Cells( 2, 2 ):Font:Name := "Arial" oSheet:Cells( 2, 2 ):Font:Size := 10 oSheet:Cells( 2, 2 ):Font:Bold := .T. oSheet:Columns( "C" ):ColumnWidth := 12 oSheet:Cells( 3, 2 ):NumberFormat := "$ #.##0,00" oSheet:Cells( 3, 2 ):Font:ColorIndex := 5 oSheet:Cells( 3, 2 ):Font:Name := "Arial" oSheet:Cells( 3, 2 ):Font:Size := 10 oSheet:Cells( 3, 2 ):Font:Bold := .T. oExcel:ScreenUpdating := .T.
RETURN NIL // FIN / END

Regards, saludos.