Subtotalizar filas en excel

Subtotalizar filas en excel

Postby artu01 » Thu Dec 03, 2020 4:45 am

Gente:
Necesito subtotalizar filas en excel desde fwh usando alguna de las alternativas de abajo:
1. Podrá hacerse con xbrowse?
2. Algun ejemplo con la clase texcelscript u otra clase?
3. Algun ejemplo con tablas dinámicas?
fwh 17.12, harbour 3.2.0, pelles C, bcc7, Ms-Sql
artu01
 
Posts: 400
Joined: Fri May 11, 2007 8:20 pm
Location: Lima

Re: Subtotalizar filas en excel

Postby Mike Serra » Thu Dec 03, 2020 9:19 am

Buenos días Artu01:

Ahora creo que dependiendo de la versión que tengas, hay soluciones a lo que pides. Yo hace mucho tiempo me construí una clase, que en su momento me resolvió el problema que tenía. Te paso un ejemplo de uso y la clase. He sacado el código del fuente que tenía y lo he adaptado para que puedas compilarlo (yo tengo FW1610 / BCC / Compilador correspondiente a la versión). El ejemplo es sencillo. Por cierto, la clase tiene un metodo para ocultar columnas del detalle de datos. Espero que te sirva para lo que necesitas.

Code: Select all  Expand view  RUN

#include "fivewin.ch"

#DEFINE EXCEL_FORMAT_FILE_CSV   6

function main()
   local oExcel,cNombreEmpresa:="Nombre empresa, S.C.A."
   local dDesdeFecha:=CTOD(""),dHastaFecha:=date()
   local aProductos:={;
                            {"001","Descripcion 1",14,3.99,55.86},;
                            {"002","Descripcion 2",1,2.5,2.5};
                     }
   
   oExcel:=tExcelExport():New()
   oExcel:AddTitle({cNombreEmpresa})
   oExcel:AddTitle({"Fecha:" + dtoc(date())})
   oExcel:AddBlankLine()
   oExcel:AddTitle({"Exportación de Productos a Excel:"})
   oExcel:AddTitle({"Desde Fecha:",dtoc(dDesdeFecha),"Hasta Fecha: ",dtoc(dHastaFecha)})
   oExcel:AddBlankLine()
   oExcel:AddHeadTitle({"Codigo", "Descripción","Udes.","Precio M.","Total"}) 
   oExcel:SetData(aProductos)
   //oExcel:SetHideColumns({6})
   oExcel:AddColumnsTotals({5})       //Aqui el nº de columnas que tiene que totalizar añades los totales
   oExcel:CreateFile()
return


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class tExcelExport

    data nRow               init 1
    data nColumn            init 1 
    data aTitles            init {}
    data aDatas             init {}
    data aTitles            init {}
    data aHidesColumn       init {}
    data aHeadTitles        init {}
    data aColumnTotals      init {}
    data cPosibleColumnWord INIT "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
   
    data cFileName  init ""
    data oExcel,oSheet,oBook
   
    data lScreenUpdating init .t.
   
    method New()                                                                    // Constructor de la Clase
    method CreateFile(lSave)                                                        // Metodo que construye el excel en base a todo lo especificado. Termina abriendolo y mostrando el fichero
    method SetData(aDatas)                  INLINE ::aDatas:=aDatas                 // Metodo para asignarle un array bidimensional con los datos a mostrar
    method SetHideColumns(aHidesColumn)     INLINE ::aHidesColumn:=aHidesColumn     // Metodo para asignar un array unidimensional con las columnas de los datos que no queremos mostrar
    method ReviewExcel()           
    method SetName(cFileName)               INLINE ::cFileName:=cFileName           // Establecemos un nombre al fichero de salida
    method AddTitle(aValues)                INLINE aadd(::aTitles,aValues)          // Método para añadir lineas de titulo al documento
    method AddBlankLine()                   INLINE aadd(::aTitles,{""})             // Método simple para añadir una linea en blanco (seria como un salto de línea)
    method AddHeadTitle(aHeadTitles)        INLINE ::aHeadTitles:=aHeadTitles       // Metodo para añadir un array unidimensional con los nombre de las cabeceras de los datos
    method AddColumnsTotals(aColumnTotals)  INLINE ::aColumnTotals:=aColumnTotals
    method SetViewUpdating(lView)           INLINE ::lScreenUpdating:=lView
   
end class

///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
method New() class tExcelExport
return self

method CreateFile(lSave) class tExcelExport
    local i,x,nTamTitle,nTamTitleElement,nTam,nTamData,nPos,nPosicionComienzoDetalle,nFilasImpresas:=0,cFileName
    local lActivaDobleLetraColumna:=.f.
    default lSave:=.f.
    if !::ReviewExcel()
        msgalert("Microsoft Excel NO instalado. La exportación no se va a llevar a cabo","¡Atención!")
        return
    end if
   
    ::oExcel:ScreenUpdating := ::lScreenUpdating
    ::oBook:=::oExcel:WorkBooks:Add()
    ::oSheet:=::oExcel:ActiveSheet
    nTamTitle:=len(::aTitles)
    for i = 1 to nTamTitle
        nTamTitleElement:=len(::aTitles[i])
        for x = 1 to nTamTitleElement
            ::oSheet:Cells( ::nRow, ::nColumn):Value:=::aTitles[i,x]
            ::nColumn++
        next x
        ::nColumn:=1
        ::nRow++
    next
   
    //Ahora pintamos las cabeceras de las columnas
    nTamData:=len(::aHeadTitles)
    if nTamData>0
        for i = 1 to nTamData
            nPos:=ASCAN(::aHidesColumn,i)
            if nPos = 0
                ::oSheet:Cells( ::nRow, ::nColumn):Value:=::aHeadTitles[i]
                ::nColumn++
            end if
        next i
        //Pintamos una linea de separacion entre lo ultimo impreso y el detalle a imprimir
        ::oSheet:Range( ::oSheet:Cells( ::nRow, 1 ), ::oSheet:Cells( ::nRow, nTamData-len(::aHidesColumn) ) ):Select()
        ::oExcel:Selection:Borders(9):LineStyle := 1   // xlContinuous = 1
        ::oSheet:Rows( ::nRow ):Font:Bold   := .T.
        ::nRow++
        ::nColumn:=1
    end if
   
    //Ahora el detalle
    nPosicionComienzoDetalle:=::nRow
    nTam:=len(::aDatas)
    if nTam>0
        nTamData:=len(::aDatas[1])
       
        for i = 1 to nTam
            for x = 1 to nTamData
                nPos:=ASCAN(::aHidesColumn,x)
                if nPos = 0
                    ::oSheet:Cells( ::nRow, ::nColumn):Value:=::aDatas[i,x]
                    ::nColumn++
                end if
            next x
            ::nColumn:=1
            ::nRow++
        next i
       
        ::oSheet:Range( ::oSheet:Cells( ::nRow-1, 1 ), ::oSheet:Cells( ::nRow-1, nTamData-len(::aHidesColumn) ) ):Select()
        if !lSave //Si se va a crear un fichero, no le ponemos los bordes
            ::oExcel:Selection:Borders(9):LineStyle := 1   // xlContinuous = 1
        end if
        //Vamos a no ajustar el texto en las columnas que sean caracter
        for x = 1 to nTamData
            nPos:=ASCAN(::aHidesColumn,x)
            if nPos = 0
                if valtype(::aDatas[1,x]) = "C"
                    ::oSheet:Range( ::oSheet:Cells( 1, x ), ::oSheet:Cells( ::nRow , x) ):Select()
                    ::oExcel:Selection:WrapText:=.f.
                end if
            end if
        next x
    end if
   
    //AHora vamos a añadir los totales si los hubiera
    for i = 1 to len(::aColumnTotals)
        nPos:=ASCAN(::aHidesColumn,i)
        if nPos = 0
            if !lActivaDobleLetraColumna
                ::oSheet:Cells(::nRow,::aColumnTotals[i]):Formula:="=SUMA("+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(nPosicionComienzoDetalle)) + ":"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(::nRow-1))+")" // APLICAR FORMULA A UNA CELDA
                if substr(::cPosibleColumnWord,::aColumnTotals[i],1) = "Z"
                    lActivaDobleLetraColumna:=.t.
                end if
            else
                ::oSheet:Cells(::nRow,::aColumnTotals[i]):Formula:="=SUMA(A"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(nPosicionComienzoDetalle)) + ":A"+substr(::cPosibleColumnWord,::aColumnTotals[i],1)+alltrim(str(::nRow-1))+")" // APLICAR FORMULA A UNA CELDA
            end if
        end if
    next i
    ::oSheet:Cells(1,1):Select()
    if !lSave
        ::oExcel:Visible:=.t.
    else
        if !empty(::cFileName)
            cFileName:=alltrim(::cFileName)
        else
            cFileName:=".\Excel_Export_" + dtos(date()) + strtran(time(),":","") + ".csv"
        end if
        ::oSheet:SaveAs(cFileName,EXCEL_FORMAT_FILE_CSV)
        ::oBook:Close(.t.)
        msginfo("Se ha generado el fichero " + cFileName,"Información")
    end if
   
return

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
method ReviewExcel() class tExcelExport
    TRY
        ::oExcel:= GetActiveObject( "Excel.Application" )
    CATCH
        TRY
            ::oExcel:= CreateObject( "Excel.Application" )
        CATCH
            return .f.        
        END
    END
return .t.

 


Un Saludo,
Mike Serra
 
Posts: 297
Joined: Fri Apr 14, 2006 5:52 pm
Location: Córdoba (España)

Re: Subtotalizar filas en excel

Postby cnavarro » Thu Dec 03, 2020 12:29 pm

Gracias "paisano"
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6552
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Subtotalizar filas en excel

Postby artu01 » Thu Dec 03, 2020 4:15 pm

Gracias Mike lo voy a probar y cualquier cosa te molesto
fwh 17.12, harbour 3.2.0, pelles C, bcc7, Ms-Sql
artu01
 
Posts: 400
Joined: Fri May 11, 2007 8:20 pm
Location: Lima

Re: Subtotalizar filas en excel

Postby artu01 » Thu Dec 03, 2020 6:10 pm

Mike
lo que busco es hacer lo mismo que hace la funcion subtotales() de excel, es decir poder expandir o contraer la data tipo arbol jerarquico 2 niveles


viewtopic.php?f=6&t=39665
fwh 17.12, harbour 3.2.0, pelles C, bcc7, Ms-Sql
artu01
 
Posts: 400
Joined: Fri May 11, 2007 8:20 pm
Location: Lima

Re: Subtotalizar filas en excel

Postby Mike Serra » Fri Dec 04, 2020 3:23 pm

Buenas Tardes Artu01:

Disculpa, no había entendido bien entonces. Con "macros" de Excel se puede hacer, pero desconozco si se puede ejecutar "código VBA" en Excel desde FW. Entre los master del foro pude componer la clase que te escribí antes, esperemos que haya alguien que pueda echarnos una mano.

Un SAludo,
Mike Serra
 
Posts: 297
Joined: Fri Apr 14, 2006 5:52 pm
Location: Córdoba (España)

Re: Subtotalizar filas en excel

Postby Mike Serra » Fri Dec 04, 2020 3:24 pm

cnavarro wrote:Gracias "paisano"


Buenas Tardes Cristobal, no sabia que eras "paisano"

Un Saludo,
Mike Serra
 
Posts: 297
Joined: Fri Apr 14, 2006 5:52 pm
Location: Córdoba (España)


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 99 guests