Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 15-02-2007
Jose Roman Jose Roman is offline
Miembro
 
Registrado: jul 2006
Ubicación: Colombia
Posts: 361
Poder: 18
Jose Roman Va por buen camino
Unhappy Como utilizar TExcelApplication

Hola a todos.

Mi pregunta es la siguiente, tengo delphi 7 y me gustaria saber como utilizar el componente TExcelApplication de la paleta Servers, mas exactamente deseo trabajar con excel a traves de un programa realizado en Delphi:
- Crear un archivo de excel
- Insertar datos en celdas
- Borrar Hojas o celdas
- Editar celdas

Clara que si hay alguna manera mas facil de trabajar por favor expliquenme, he tratado con ADO pero no deja borrar celdas
Responder Con Cita
  #2  
Antiguo 15-02-2007
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.272
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Busca información sobre Automatización en Excel; Hay mucha información; Aquí en los foros y fuera de ellos.
Empieza por este y este.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 15-02-2007
Jose Roman Jose Roman is offline
Miembro
 
Registrado: jul 2006
Ubicación: Colombia
Posts: 361
Poder: 18
Jose Roman Va por buen camino
Talking

Gracias, ensayare a ver como me va...
Responder Con Cita
  #4  
Antiguo 16-02-2007
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Hola.

Por si acaso no encontraras lo que buscas, aquí te dejo el código fuente de una clase que me curré en su día para implementarla en Delphi 3 (aún no existía la paleta Servers ni nada de su contenido).

Básicamente consiste en crearte un objeto OLE por medio de esta línea de código:

Código Delphi [-]
Obj_Excel := CreateOleObject('Excel.Application');


o intentar capturar alguna ejecución de Excel que ya esté activa en el PC con esto otro:

Código Delphi [-]
 

Obj_Excel := GetActiveOleObject('Excel.Application');

Después, todo el trabajo es idéntico a crearte macros en Visual Basic de Excel.

Resulta luego curioso ver dentro del código Delphi líneas de código que son en realidad macros de VB.



A continuación el código. Lo preparé para mi apaño personal, y con las cositas justas que fui necesitando. Así que tiene muchas carencias, pero espero que te valga.

Código Delphi [-]
 

unit uExportExcel;

interface

const

  //============================================================
  //              Constantes creadas por mí
  //============================================================

  //--------- Colores en Fondo de Celdas -------------------------------------
  xl_CL_AmarLight = $00000024; // (36) Amarillo Claro
  xl_CL_AzulCielo = $00000021; // (33) Azul Cielo
  xl_CL_Turq      = $00000008; // ( 8) Truquesa
  xl_CL_TurqLight = $00000022; // (34) Turquesa Claro
  xl_CL_Rojo      = $00000003; // ( 3) Rojo
  //--------- Formatos de Impresión para Cabecera y Pie de página ------------
//  xl_FI_Fich = '&F'; // Nombre del Archivo Excel
  xl_FI_Fich = '&N'; // Nombre del Archivo Excel
  xl_FI_Hoja = '&A'; // Nombre de la Hoja Excel
  xl_FI_Pag  = '&P'; // Nº de la Hoja impresa
  xl_FI_TPag = ''; // Nº Total de Hojas impresas
  xl_FI_RC   = #10 ; // Salto de línea

  //============================================================
  //              Constantes de Excel
  //============================================================

  //--------- Constantes reutiliables en varios conceptos --------------------
  //--------- (ver su uso dentro de cada sección) ----------------------------
  xlAutomatic     = $FFFFEFF7; // (-4105)
  //--------- Para crear "objetos" nuevos dentro de una aplicación Excel -----
  xlWBATWorksheet = $FFFFEFB9; // (-4167) Documento Excel
  //--------- Para el cálculo de fórmulas ------------------------------------
  (* xlAutomatic -> Cálculo Automático *)
  xlManual        = $FFFFEFD9; // (-4135) Cálculo Manual
  //--------- Bordes de las Celdas -------------------------------------------
  xlEdgeLeft         = $00000007; // ( 7) Izquierdo
  xlEdgeTop          = $00000008; // ( 8) Superior
  xlEdgeBottom       = $00000009; // ( 9) Inferior
  xlEdgeRight        = $0000000A; // (10) Derecho
  xlInsideVertical   = $0000000B; // (11) Vertical Interior
  xlInsideHorizontal = $0000000C; // (12) Horizontal Interior
  //--------- Tipo de línea en bordes de Celdas ------------------------------
  xlContinuous = $00000001; // ( 1) Continua
  xlNone       = $FFFFEFD2; // (-4142) Ningúna línea
  //--------- Grosores en bordes de Celdas -----------------------------------
  xlThin   = $00000002; // ( 2) Fino
  xlMedium = $00000003; // ( 3) Medio
  //--------- Colores en bordes de Celdas ------------------------------------
  (* xlAutomatic -> Color por Defecto (negro) *)
  //--------- Selección de Celdas --------------------------------------------
  xlLastCell = $0000000B; // (11) Como si en Excel se pulsa [Ctrl]+[Shift] y [Cursor]
  //--------- Alineación de texto en las celdas ------------------------------
  xlCenter = $FFFFEFF4; // (-4108) Centrado
  //--------- Tipos de Condiciones para Formato Condicional
  xlCellValue  = $00000001; // ( 1) Basado en el valor de la celda
  xlExpression = $00000002; // ( 2) Basado en el resultado de una fórmula
  //--------- Operadores para Condiciones de Formato Condicional
  xlBetween      = $00000001; // ( 1)    Entre dos valores
  xlNotBetween   = $00000002; // ( 2) No Entre dos valores
  xlEqual        = $00000003; // ( 3)    Igual a...
  xlNotEqual     = $00000004; // ( 4) No Igual a...
  xlGreater      = $00000005; // ( 5) Mayor que...
  xlLess         = $00000006; // ( 6) Menor que...
  xlGreaterEqual = $00000007; // ( 7) Mayor o igual a...
  xlLessEqual    = $00000008; // ( 8) Menor o igual a...
  //--------- Para el tamaño de la pantalla de Excel -------------------------
  xlNormal    = $FFFFEFD1; // (-4143) Pantalla Tamaño Normal
  xlMaximized = $FFFFEFD7; // (-4137) Maximizar Pantalla
  xlMinimized = $FFFFEFD4; // (-4140) Minimizar Pantalla
  //--------- Para seleccionar celdas ----------------------------------------
  xlToLeft  = $FFFFEFC1; // (-4159) [Ctrl]+[Shift] + [flecha izquierda]
  xlToRight = $FFFFEFBF; // (-4161) [Ctrl]+[Shift] + [flecha derecha]
  xlUp      = $FFFFEFBE; // (-4162) [Ctrl]+[Shift] + [flecha arriba]
  xlDown    = $FFFFEFE7; // (-4121) [Ctrl]+[Shift] + [flecha abajo]


type
  TAplExcel = class
  private
  protected
    Obj_Excel : Variant;
    Obj_WBook : Variant;
    Reutilizado : boolean;
    Back_Calculation : integer;

    function Get_Obj_Excel : variant;
    function Get_Obj_WBook : variant;
    procedure Set_Obj_WBook (objeto : variant);

    procedure CrearAplicacionExcel (Reutilizar:boolean);
    procedure DocumentoTerminado(WorkBook:variant);
    procedure InitVarExcel;
    procedure LiberarMemoria (QuitarTodos:boolean);
  public
    constructor Create; virtual;    // Crea una Aplicación Excel
    procedure Destroy; virtual;     // Borro el objeto

    property Excel:Variant read Get_Obj_Excel;
    property WBook:Variant read Get_Obj_WBook;

    function CrearNuevoWBook : variant;
    procedure QuitarWBook(WorkBook:variant);
    procedure QuitarWSheet (WorkSheet:variant);
    procedure GuardarDocumento(WorkBook:variant; PathAndName:string; MostrarAlertas:boolean);
    procedure CargarDocumento(PathAndName:string);
    procedure NoGuardarDocumento(WorkBook:variant);
    procedure MostrarAplExcel;
    procedure OcultarAplExcel;

    procedure ControlErrorExcel;

    procedure ColorFondo (Selection:Variant; Color:integer);
    procedure PonerGrid  (Selection:Variant; GrosorMarco, GrosorVerti, GrosorHoriz:integer);
    procedure PonerMarco (Selection:Variant; Grosor:integer);

    function LetraColumna (x:integer):string;
    procedure SetPrintArea (Hoja : variant; x1,y1, x2,y2 : integer);
    procedure SetSaltoPagVert (Hoja : variant; NumSalto, Columna : integer);
  end;

implementation

uses ComObj, SysUtils;

procedure TAplExcel.LiberarMemoria (QuitarTodos:boolean);
var x:integer;
begin
  if VarIsNull(Obj_Excel) Then Exit;
  try
    for x:=Obj_Excel.Workbooks.Count downto 1 do Begin
      if QuitarTodos or Obj_Excel.Workbooks[x].Saved
      Then Begin
        QuitarWBook(Obj_Excel.Workbooks[x]);
      End;
    End;
  Except
  End;
end;

function TAplExcel.CrearNuevoWBook : variant;
begin
  //--------------------------------------------------
  // Me creo el documento Excel de la siguiente manera
  // para que sólo contenga una única hoja.
  //--------------------------------------------------
  try
    Result := Obj_Excel.Workbooks.Add(xlWBATWorksheet);
  except
    Result := null;
    raise;
  end;

  //--------------------------------------------------------
  // Pongo cálculo manual para agilizar el proceso
  // IMPORTANTE: siempre después de crear el documento Excel
  //--------------------------------------------------------
  if Obj_Excel.Workbooks.Count = 1
  Then Back_Calculation  := Obj_Excel.Calculation;
  If Obj_Excel.Calculation <> xlManual
  Then Obj_Excel.Calculation := xlManual;
end;

procedure TAplExcel.QuitarWBook(WorkBook:variant);
begin
  {$B-}
  if  (not VarIsNull(Obj_WBook))
  and (Obj_WBook.FullName = WorkBook.FullName)
  Then Obj_WBook := Null;
  NoGuardarDocumento(WorkBook);
  WorkBook.Close;
end;

procedure TAplExcel.QuitarWSheet (WorkSheet:variant);
var Alertas:boolean;
begin
  alertas := WorkSheet.Application.DisplayAlerts;
  WorkSheet.Application.DisplayAlerts := False;
  WorkSheet.Delete;
  WorkSheet.Application.DisplayAlerts := Alertas;
end;

procedure TAplExcel.DocumentoTerminado(WorkBook:variant);
begin
  WorkBook.Worksheets[1].Select;
  WorkBook.Worksheets[1].Activate;
  WorkBook.Worksheets[1].Cells[1,1].Select;
end;

procedure TAplExcel.GuardarDocumento(WorkBook:variant; PathAndName:string; MostrarAlertas:boolean);
var Alertas:boolean;
begin
  DocumentoTerminado(WorkBook);
  WorkBook.Application.Calculation  := Back_Calculation;
  alertas := WorkBook.Application.DisplayAlerts;
  WorkBook.Application.DisplayAlerts := MostrarAlertas;
  WorkBook.SaveAs ( PathAndName );
  WorkBook.Application.DisplayAlerts := alertas;
//  WorkBook.Application.Calculation := xlManual;
end;

procedure TAplExcel.CargarDocumento(PathAndName:string);
begin
  Obj_Excel.Workbooks.Open(PathAndName);
  if VarIsNull(Obj_WBook) Then Obj_WBook := Obj_Excel.Workbooks[Obj_Excel.Workbooks.Count];
end;

procedure TAplExcel.NoGuardarDocumento(WorkBook:variant);
begin
  WorkBook.Saved := True;
end;

procedure TAplExcel.MostrarAplExcel;
var x:integer;
Begin
  for x:=1 to Obj_Excel.Workbooks.Count do DocumentoTerminado(Obj_Excel.Workbooks[x]);
  Obj_Excel.Calculation  := Back_Calculation;
  Obj_Excel.WindowState :=  xlMaximized;
  Obj_Excel.Visible := True;
End;

procedure TAplExcel.OcultarAplExcel;
begin
  Obj_Excel.Visible := False;
end;

procedure TAplExcel.CrearAplicacionExcel (Reutilizar:boolean);
var v_Excel : variant;
begin
  //---------------------------------------------
  // Inicializo variables con valores por defecto
  //---------------------------------------------
  InitVarExcel;

  try
    //-------------------------------------
    // Creo o Recupero una Aplicación Excel
    //-------------------------------------
    try
      if Reutilizar Then try
        Obj_Excel := GetActiveOleObject('Excel.Application'); // La intento recuperar
        Reutilizado := True;
      except
        Obj_Excel := null;
      End;
      if VarIsNull(Obj_Excel) Then Begin
        Obj_Excel := CreateOleObject('Excel.Application'); // La creo
        Reutilizado := False;
      End;
    except
      Obj_Excel := null;
      raise;
    end;

    //---------------------------------------------------------------
    //  La hago invisible al usuario para que:
    //      - al evitar refrescos de pantalla, la velocidad sea mayor
    //      - el usuario no podrá "hurgar" y estorbar en el proceso
    //---------------------------------------------------------------
    OcultarAplExcel;
//Obj_Excel.Visible := True;

    //---------------------------
    // Creo nuevo documento Excel
    //---------------------------
    Obj_WBook := CrearNuevoWBook;

  except
    //------------------------------
    // Algo ha fallado en el proceso
    //------------------------------
    ControlErrorExcel;
  end;
end;

constructor TAplExcel.Create;
begin
  //-------------------------------------------------------
  // Me creo primero la Aplicación Excel para asegurarme de
  // que se crea junto al objeto
  //-------------------------------------------------------
  CrearAplicacionExcel (False);

  //-----------------------------
  // Por último me creo el objeto
  //-----------------------------
  inherited Create;
end;

//constructor TAplExcel.CreateOrRetrieve;
//begin
//  //-------------------------------------------------------
//  // Me creo primero la Aplicación Excel para asegurarme de
//  // que se crea junto al objeto
//  //-------------------------------------------------------
//  CrearAplicacionExcel (True);
//
//  //-----------------------------
//  // Por último me creo el objeto
//  //-----------------------------
//  inherited Create;
//end;

procedure TAplExcel.Destroy;
begin
  if not Obj_Excel.Visible Then Begin
    if not Reutilizado          Then LiberarMemoria(False);
    if not VarIsNull(Obj_Excel) Then Begin
      if Obj_Excel.Workbooks.Count > 0 Then Begin
        MostrarAplExcel;
      End
      Else Begin
        Obj_Excel.Quit;
        Obj_Excel := null;
      End;
    End;
  End;

  InitVarExcel;
  inherited Free;
end;

//procedure TAplExcel.DestroyToRetrieve;
//begin
//  Reutilizado := True;
//  Self.Destroy;
//end;

procedure TAplExcel.InitVarExcel;
begin
  //---------------------------------------------------------
  // Las inicializo en orden de menor a mayor entorno por si
  // acaso se produjera error inicializando de mayor a menor.
  //---------------------------------------------------------
  Back_Calculation := xlAutomatic;
  Reutilizado      := False;
  Obj_WBook := Null;
  Obj_Excel := Null;
end;

function TAplExcel.Get_Obj_Excel : variant;
begin
  Result := Obj_Excel;
end;

function TAplExcel.Get_Obj_WBook : variant;
begin
  Result := Obj_WBook;
end;

procedure TAplExcel.Set_Obj_WBook (objeto : variant);
begin
  Obj_WBook := objeto;
end;

procedure TAplExcel.ControlErrorExcel;
begin
  LiberarMemoria(True);
//  if Borrar And VarIsNull(Obj_Excel) and (Not Reutilizado)
//  then Self.Destroy;
  raise Exception.Create('No ha podido generarse el documento Excel.'#13#13+
                         'Cierre la aplicación, e inténtelo de nuevo.'#13+
                         'Si el problema persiste, reinicie el equipo.');
end;

procedure TAplExcel.ColorFondo (Selection:Variant; Color:integer);
begin
  Selection.Interior.ColorIndex := Color;
end;

procedure TAplExcel.PonerGrid  (Selection:Variant;
                                GrosorMarco, GrosorVerti, GrosorHoriz:integer);
begin
  PonerMarco (Selection, GrosorMarco);
  if Selection.Columns.Count > 1 Then Begin
    if GrosorVerti = xlNone Then
      Selection.Borders[xlInsideVertical  ].LineStyle := xlNone
    Else Begin
      Selection.Borders[xlInsideVertical  ].LineStyle := xlContinuous;
      Selection.Borders[xlInsideVertical  ].Weight    := GrosorVerti;
    End;
  End;
  if Selection.Rows.Count > 1 Then Begin
    if GrosorHoriz = xlNone Then
      Selection.Borders[xlInsideHorizontal].LineStyle := xlNone
    Else Begin
      Selection.Borders[xlInsideHorizontal].LineStyle := xlContinuous;
      Selection.Borders[xlInsideHorizontal].Weight    := GrosorHoriz;
    End;
  End;
end;

procedure TAplExcel.PonerMarco (Selection:Variant; Grosor:integer);
begin
  Selection.Borders[xlEdgeLeft  ].LineStyle := xlContinuous;
  Selection.Borders[xlEdgeLeft  ].Weight    := Grosor;
  Selection.Borders[xlEdgeTop   ].LineStyle := xlContinuous;
  Selection.Borders[xlEdgeTop   ].Weight    := Grosor;
  Selection.Borders[xlEdgeBottom].LineStyle := xlContinuous;
  Selection.Borders[xlEdgeBottom].Weight    := Grosor;
  Selection.Borders[xlEdgeRight ].LineStyle := xlContinuous;
  Selection.Borders[xlEdgeRight ].Weight    := Grosor;
end;

function TAplExcel.LetraColumna (x:integer):string;
const letras = 'ABCDEFGHIJKLMNOPKRSTUVWXYZ';
begin
  Result := '';
  While x > 0 do begin
    Result := letras[1 + ((x - 1) Mod length(letras))] + Result;
    x := (x - 1) div length(letras);
  End;
end;

procedure TAplExcel.SetPrintArea (Hoja : variant; x1,y1, x2,y2 : integer);
begin
  if (x1 <= 0) or (x2 <= 0)
  Then raise Exception.Create('');
  Hoja.PageSetup.PrintArea := '$' + LetraColumna(x1) + '$' + inttostr(y1) + ':' +
                              '$' + LetraColumna(x2) + '$' + inttostr(y2);
end;

procedure TAplExcel.SetSaltoPagVert (Hoja : variant; NumSalto, Columna : integer);
var range : variant;
begin
  range := Hoja.Cells[1,Columna];
  Hoja.VPageBreaks[NumSalto].Location := Range;
end;

end.
Responder Con Cita
  #5  
Antiguo 16-02-2007
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Se me olvidaba un consejo.

Para mayor agilidad a la hora de rellenar el contenido de las celdas del documento Excel te aconsejo que utilices un TMemo (aunque sea de forma temporal (en ejecución te lo creas y luego lo destruyes) y no sea visible en pantalla).
En el TMemo vas metiendo el contenido de todas las celdas (o de una buena cantidad de ellas, si lo vas haciendo por bloques). Luego ejecutas el procedimiento CopyToClipboard del TMemo. Por último sólo te queda ejecutar el procedimiento Paste que pertenece al WorkSheet del documento Excel.
Por ejemplo así:

Código Delphi [-]
 
procedure TMiForm.PegarDatos;
var x:integer;
begin
      Memo.SelectAll;
      Memo.CopyToClipboard;
      x:=0;
      repeat
        try
          MiExcel.ActiveSheet.Paste( MiExcel.ActiveSheet.Cells[ FilasFijas+Cont-(NumGrColum*FilasTope)-FilasDatos+1,
                                                              NumGrColum*AnchoGrColumnas+1 ],
                                   False);
          break;
        except
          inc(x);
          if x=20 Then raise;
        end;
      until false;
      Memo.Lines.Clear;
end;

En ese ejemplo el objeto MiExcel es del tipo TAplExcel que me creé.
Sólo hay una pequeña pega. Y es que en ocasiones este truco es tan rápido que intenta hacer el Paste casi antes de haber terminado de ponerse en orden el Clipboard y entonces salta un mensaje de error. Por eso lo tengo encerrado en un bucle. Si no consigue hacer el Paste a la primera, lo normal es que siempre lo consiga a la segunda, pues ya ha pasado algo más de tiempo.

Dentro del TMemo, lo que le vayas metiendo ahí, para separarlo por filas te valen los saltos de página, y para separarlo por columnas insertale caracteres de tabulación (#9).

Un saludo.
Responder Con Cita
  #6  
Antiguo 16-02-2007
Jose Roman Jose Roman is offline
Miembro
 
Registrado: jul 2006
Ubicación: Colombia
Posts: 361
Poder: 18
Jose Roman Va por buen camino
Muchas gracias FLECHA, esta ayuda me responde las dudas que me surgieron.
Responder Con Cita
  #7  
Antiguo 20-02-2007
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Exclamation Una cosita más


De nada, hombre. Para eso estamos.

Por cierto acabo de acordarme de que no es necesario recurrir al TMemo para utilizar el Clipboard.

Existe una unidad llamada ClipBrd que implementa el uso de objetos TClipboard, los cuales permiten trabajar con el ClipBoard de Windows.

A continuación el mismo truco que antes, pero con el uso de la unidad ClipBrd.

Código Delphi [-]
procedure TMiForm.PegarDatos;
var x:integer;
begin
      x:=0;
      Clipboard.Clear;                     // Borrar el contenido del ClipBoard
      Clipboard.SetTextBuf(Datos.GetText); // Copiar texto en el ClipBoard
      try
        repeat
          try
            MiExcel.ActiveSheet.Paste( MiExcel.ActiveSheet.Cells[ 1,1 ], False);
            break;
          except
            inc(x);
            if x>=20 Then raise;
          end;
        until false;
      finally
        Clipboard.Clear; // Borrar el contenido del ClipBoard
      end;
      FilasDatos := 0;
      Datos.Clear;
end;

En este ejemplo Datos es del tipo TStringList. ClipBoard no es un objeto, sino una función perteneciente a la unidad ClipBrd que retorna un objeto TClipBoard. El método SetTextBuf es el que copia texto en el ClipBoard de Windows. Este método recibe un PChar, por eso le paso el GetText del TStringList en vez del Text.
En este ejemplo, además, el ClipBoard de Windows queda vacío después de cada copia.

Como dije antes, el lado bueno de este truco es la velocidad de copiado sobre el documento Excel. Pero olvidé decir que hay que tener cuidado con los posibles copy-paste que el usuario esté haciendo por otro lado mientras este proceso se está ejecutando. Si el documento Excel que estás construyendo es tan sumamente grande que aunque utilices este truco, tarda mucho tiempo en terminarse de construir, el usuario podría aprovechar su tiempo abriendo otra aplicación distinta (por ejemplo un documento Word) para trabajar con ello mientras tu proceso termina. Los copy-paste que el usuario haga en esa otra aplicación podrían interferir perjudicialmente en la creación de tu documento Excel. Podrían copiarse en tu Excel los copy que el usuario hace en su Word, o copiarse sobre el Word del usuario lo que estas intentando exportar a tu documento Excel.

No todo podían ser buenas noticias.
Responder Con Cita
  #8  
Antiguo 11-01-2011
Avatar de Wbarrantes
Wbarrantes Wbarrantes is offline
Miembro
 
Registrado: ago 2010
Posts: 119
Poder: 14
Wbarrantes Va por buen camino
buenas

se que ha pasdo algun tiempo de este hilo, pero me interesa saber si alguien tiene un ejemploun poco mas concreto de como usar este unit... se ve interesante
Responder Con Cita
  #9  
Antiguo 12-01-2011
Jose Roman Jose Roman is offline
Miembro
 
Registrado: jul 2006
Ubicación: Colombia
Posts: 361
Poder: 18
Jose Roman Va por buen camino
No sabes como utilizarlo??
Responder Con Cita
  #10  
Antiguo 12-01-2011
Avatar de Wbarrantes
Wbarrantes Wbarrantes is offline
Miembro
 
Registrado: ago 2010
Posts: 119
Poder: 14
Wbarrantes Va por buen camino
pos no

pues no por eso pregunto... tendria que instalarlo como un pakage? o importarlo en cada aplicacion como un unit? lo debo incluir el codigo dentro de la unit que este usando? como ejecuto algo desde mi aplicacion?


Aclaro, estoy hablando del codigo chorreado que puso Flecha... por que gracias a Dios ya encontre bastante informacion sobre el uso del TExcelApplication... pero igual me gustaria si tienes informacion sobre este ultimo, aprender mas sobre algunas otras funciones como el merge de celdas por ejemplo
Responder Con Cita
  #11  
Antiguo 12-01-2011
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Hola Wbarrantes.

Hace mucho de ésto, y... es cierto..., quizá debí acompañarlo de un pequeño manual de usuario, jejejejeje...
Intentaré ayudarte. A ver qué recuerdo...

La unit que me creé no es para cogerla y hacer copy-paste dentro de otro código. Es una unit totalmente independiente. Basicamente lo que contiene es una clase que me creé (la llamé TAplExcel), y varias constantes que también me creé.

Así que para utilizarlo lo que tienes que hacer es añadir la unit a tu proyecto (el archivo .PAS que te crees con mi unit llamala uExportExcel, que es como yo la llamé; o si le das otro nombre no olvides cambiarlo también en la cabecera del unit). Luego, desde tu programa, te creas una instancia a TAplExcel.

Código Delphi [-]
...
var MyAplExcel : TAplExcel;
begin
...
MyExcel : TAplExcel.Create;
try
... // utilización de la clase
 finally
 MyExcel.Destroy;
 end;
...
end;


Por lo demás decirte que la clase me la creé 100% basada en la utilización de macros de VisualBasic de Excel. Si echas un vistazo al código fuente, encontrarás que practicamente utilizo funciones y procedimientos que no existen en Delphi y que sólo pertenecen a VB Excel.

¿Cómo consigo utilizar VB Excel entremezclado con código Delphi? Es gracias a que me creo un objeto OLE del tipo "Excel.Application". Esto lo explico al principio de mi chorro-mensaje.

Un truco que utilicé. Yo no domino VB de Excel. Lo que yo hacía mientras diseñaba mi clase fue grabar una macro de Excel con las operaciones que yo quería recrear en mi clase. Luego hacía copy-paste sobre mi unidad, y poco más. Por desgracia hay algunas cosas que no se pueden adaptar.

Preguntas sobre cómo hacer un "merge" de celdas con la clase que me creé. Esto no lo implementé. No recuerdo si es que no lo intenté o si es que no pude.

El "merge" se aplica a un rango de celdas, y dicho rango ha de ser acotado entre 2 referencias a celda (cada una representando una esquina opuesta).
En VB de Excel, para hacer un "merge" acotado pora las celdas E1 y G5, sería éste código:
Código:
Range(Cells(1, "E"), Cells(5, "G")).Merge
Para hacer lo mismo desde Delphi tocaría cambiar varias cosas. Para empezar no se puede hacer uso de letras para indicar columnas. Hay que utilizar el valór numérico (5 para "E", y 7 para "G"). Y en vez de paréntesis (), muchas veces hay que sustituirlo por corchetes [].
No lo he provado, pero quizá esto equivalga al código en VB Excel.
Código Delphi [-]
MyExcel.Excel.Range[ MyExcel.Excel.Cells[1, 5], MyExcel.Excel.Cells[5, 7] ].Merge;
Si con ésto saltara una excepction, quizá habría que cambiarlo por esto otro:
Código Delphi [-]
var esquina1, esquina2, rango:variant;
begin
...
  esquina1 := MyExcel.Excel.Cells[1, 5];
  esquina2 := MyExcel.Excel.Cells[5, 7];
  rango := MyExcel.Excel.Range[ esquina1, esquina2 ];
  rango.Merge;
...
end;
Y si aún así sigue sin funcionar..., pues no se me ocurro ahora nada. Quizá es que no se pueda hacer.





Aprovecho y añado una breve desccripción de las propiedades, funciones y procedimientos públicos de la clase TAplExcel.


property Excel:Variant read Get_Obj_Excel;

Esta propiedad es la más importante.
Te da acceso al objeto OLE que es creado internamente dentro de la clase, y por medio del cual, a su vez, se accede a Excel. Por tanto, te da acceso al uso de código de VisualBasic de Excel.
Por ejemplo. Lo que en VB de Excel se escribe así:
Código:
vble = Cells(25, 3).Text
Utilizando la clase que me creé, sería así:
Código Delphi [-]
vble := MyExcel.Excel.Cells[25, 3].Text;
Esa línea de código lo que hace es tomar el valor que haya en la fila 25, columna 3 (letra "C"), del documento Excel.
Observa que lo que en VB va encerrado entre paréntesis (), en Delphi va entre corchetes [].


property WBook:Variant read Get_Obj_WBook;

El uso de esta propiedad equivale a lo que en VB de Excel sería utilizar el ActiveWorkBook, o lo que es lo mismo, el documento Excel activo.
Por tanto..., MyExcel.Excel.ActiveWorkBook equivaldría a MyExcel.WBook.


function CrearNuevoWBook : variant;

Esto equivale a lo que dentro de Excel sería "File" -> "New..." -> "Blank workbook". O sea, crear un nuevo documento Excel.
Esta función además retorna un objeto que da acceso directo a dicho nuevo documento. En cierto sentido equivaldría al WBook de antes.


procedure QuitarWBook(WorkBook:variant);

Como sabes, dentro de Excel puedes tener varios documentos abiertos. Con esta función, le pasas un documento y lo cierra. Es como en Excel ir a "File" -> "Close".


procedure QuitarWSheet (WorkSheet:variant);

Es como QuitarWBook, pero en vez de quitar un documento, quita una de las hojas del documento. Funciona igual. Hay que pasarle como parámetro algo que apunte a dicha hoja.


procedure GuardarDocumento(WorkBook:variant; PathAndName:string; MostrarAlertas:boolean);

Con ésto guardas el documento abierto en Excel. Hay que pasarle el objeto que contiene el documento, un nombre con la ruta para el archivo a crear, y decirle TRUE o FALSE dependiendo de si quieres que muestre o no posibles mensajes de alerta.


procedure CargarDocumento(PathAndName:string);

Para abrir con Excel un documento que tengas guardado. A dicho documento puedes acceder luego por medio de la propiedad WBook.


procedure NoGuardarDocumento(WorkBook:variant);

Simplemente se le quita al documento Excel la marca de "pendiente de grabar", pero el documento permanece abierto.
La consecuencia es que al querer cerrar el documento, éste consta como ya grabado, aunque sea mentira.


procedure MostrarAplExcel;

Con la clase que me creé, se puede trabajar con Excel sin que Excel sea visible por el usuario (ni siquiera aparece el botón abajo como si estubiera minimizado).
Al ejecutar este procedimiento, la aplicación Excel aparece en pantalla, y el usuario puede ver el documento que tengas abierto.


procedure OcultarAplExcel;

Lo mismo que MostrarAplExcel, pero para ocultar la aplicación Excel.
Es muy aconsejable mantener Excel oculto mientras trabajas con el documento. Así se evitan refrescos de pantalla, que es algo que resta mucha CPU, y consigues más velocidad. Aparte de que así también evitas que el usuario esté viendo "las tripas" del curro que estás haciendo.


procedure ControlErrorExcel;

Esto lo que hace es liberar la memoria (se borra de memoria el documento Excel), y lanzar una Exception.
Me lo creé para mi apaño personal, para tener un texto común como mensaje cuando detectase una situación que me impidiera crear el documento Excel que estaba intentando crear.


procedure ColorFondo (Selection:Variant; Color:integer);

Esto cambia el color de fondo de las celdas del documento. Dichas celdas deben ir indicadas en el parámetro Selection.
Por ejemplo, para poner de color rojo el fondo de la celda B1...
Código Delphi [-]
  MyExcel.ColorFondo ( MyExcel.Excel.Cells[2,1] , xl_CL_Rojo );
Que equivale en VB de Excel a poner ésto...
Código:
Cells(2,1).Interior.ColorIndex = $00000003
Hay varias constantes declaradas en la unit para trabajar con colores.


procedure PonerGrid (Selection:Variant; GrosorMarco, GrosorVerti, GrosorHoriz:integer);

Esto es para resaltar los bordes de las celdas contenidas dentro de un rango de celdas.
Se ha de indicar dicho rango de celdas (Selecction), y el grosor que se quiere para
- borde exterior (el marco)
- líneas interiores verticales
- líneas interiores horizontales
Para los tipos de grosores hay constantes declaradas en la unit.


procedure PonerMarco (Selection:Variant; Grosor:integer);

Lo mismo que PonerGrid, pero sólo para el borde exterior.


function LetraColumna (x:integer):string;

A esta función le pasas un número, y te devuelve la letra de columna correspondiente.


procedure SetPrintArea (Hoja : variant; x1,y1, x2,y2 : integer);

Esto es para definier el área de impresión de una hoja de un documento Excel. Hay que pasarle como parámetro la hoja en cuestión, y también el área (como coordenadas x-y, de las esquinas superior izquierda, e inferior derecha).

procedure SetSaltoPagVert (Hoja : variant; NumSalto, Columna : integer);

Al igual que SetPrintArea, este procedimiento es para preparar el documento Excel para su salida por impreosra. Como sabrás, Excel pagina automáticamente dependiendo de cuántas columnas hayas ocupado en la hoja Excel. Es posible que la paginación automática establezca cortes en lugares que no te resulten apropiados. Con SetSaltoPagVert puedes establecer "puntos de corte" que Excel deberá respetar a la hora de imprimir la hoja.
Debes pasarle la hoja en cuestión, un identificador para el punto de corte (se pueden poner varios), y la columna donde lo situas.






Para entender mejor el funcionamiento, te aconsejo que profundices en la utilización de VB de Excel, porque como habrás podido comprobar, la clase que me creé hace un continuo uso de dicho VB de Excel, permitiendo utilizar códigos fuente de VB (macros) intercalados dentro del código fuente de Delphi.
Sólo así podrás sacarle el máximo rendimiento a la clase que me creé.
Lo mejor es creárte macros en VB de Excel que hagan exactamente lo que tu quieres que luego se haga en Delphi. Luego coges esas macros, y haces copy-paste sobre tu código Delphi. Luego, cada vez que en dichas macros se haga uso de objetos propios de VB de Excel, dentro de Delphi lo traduces anteponiendo la propiedad TAplExcel.Excel a dicho objeto.
Por ejemplo..., para en VB Excel poner el valor "Hola mundo" dentro de la celda C5, se escribiría esto:
Código:
Cells(5, "C").Text = "Hola mundo"
En Delphi sería así:
Código Delphi [-]
MyExcel.Excel.Cells[5, 3].Text := 'Hola mundo';
Observa que se cambian también paréntesis () por corchetes [], y dobles comillas (") por simples ('), aparte de referenciar columnas con un número en vez de por su letra.




No puedo evitar escribir ladrillos. Cualquier explicación me parece poca para dejarlo suficientemente claro.
Lo siento.
Espero haber sido de ayuda.

Un saludo.
Responder Con Cita
  #12  
Antiguo 12-01-2011
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.272
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Thumbs up

Cita:
Empezado por Flecha Ver Mensaje
No puedo evitar escribir ladrillos. Cualquier explicación me parece poca para dejarlo suficientemente claro.
Bueno, a mi más que un ladrillo, me parece una fantástica y detallada explicación.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #13  
Antiguo 01-07-2014
Avatar de StartKill
StartKill StartKill is offline
Miembro
 
Registrado: ene 2004
Posts: 299
Poder: 21
StartKill Va por buen camino
Thumbs up

Realmente muy buen aporte.

Debo suponer que Flecha ah mejorado su clase..

A ver si te animas a subir novedades de tu clase (que ocioso que soy...)


Ss.

Your friend

Startkill
//----------
Responder Con Cita
  #14  
Antiguo 01-07-2014
Jose Roman Jose Roman is offline
Miembro
 
Registrado: jul 2006
Ubicación: Colombia
Posts: 361
Poder: 18
Jose Roman Va por buen camino
Question

Gracias por esa explicación y tu aporte tan grade, tengo una inquietud Flecha, cuando tengo instalado office 2007 funciona el mismo codigo???
Responder Con Cita
  #15  
Antiguo 02-07-2014
Avatar de pacopenin
pacopenin pacopenin is offline
Miembro
 
Registrado: sep 2010
Ubicación: Asturias
Posts: 382
Poder: 14
pacopenin Va por buen camino
Buen aporte que me había pasado desapercibido.
__________________
http://www.gestionportable.com
Responder Con Cita
  #16  
Antiguo 18-07-2021
Avatar de PabloTech
PabloTech PabloTech is offline
Miembro
 
Registrado: ene 2007
Ubicación: Tucumán, Argentina
Posts: 82
Poder: 18
PabloTech Va por buen camino
Thumbs up Poner ancho de columna...

Hola amgios. Muy muchas gracias @Flecha por la clase, funciona de maravilla.

Yo ahora quisera saber cómo ponerle un ancho particular a una columna. Ya busqué y probé varias cosas pero siempre da error. Les muestro lo que me parece más acertado.
Código Delphi [-]
// En la clase tendría la función para cambiar el ancho de la columna... 
procedure TAplExcel.PonerAnchoColumna (Selection: Variant; Column: Variant; Width: Real);
begin
  Selection.Columns[Column].ColumnWidth := width;
end;
// Y en la implementación, debo especificar la columna y el ancho que deseo.
    Esquina1 := MyExcel.Excel.Cells[1, 1];
    Esquina2 := MyExcel.Excel.Cells[10, 18];
    Rango := MyExcel.Excel.Range[ esquina1, esquina2 ];
    MyExcel.PonerAnchoColumna (Rango, 3, 300 );
El mensaje dice: "No se puede asignar la propiedad ColumnWidth de la clase Range".


¿Me pueden ayudar con esto? Gracias de nuevo.
__________________
Cita:
Cuando respetes al ilustrado y al ignorante, al rico y al pobre, al bello y al feo, estarás muy cerca de la sabiduría, que trasciende lo aparente.

E. Rharo
Responder Con Cita
  #17  
Antiguo 19-07-2021
manelb manelb is offline
Miembro
 
Registrado: mar 2017
Posts: 280
Poder: 8
manelb Va por buen camino
Saludos a todos ….

Pues he mirado como lo hago yo, y lo hago igual que tú, pero actuando únicamente sobre una celda, y no sobre un rango.

Código Delphi [-]

var
  .....
  celda: OleVariant;
  ..... 
begin
      ......
      CELDA:= HOJA.Cells.Item[FFILA,COLUMNA+1];
      celda.Font.Bold:=true;
      celda.Font.Size:=9;
      celda.Font.Underline:=true;
      celda.ColumnWidth:= ValorDeseado;
      ........

end;

Fíjate que concuerda bastante con el mensaje de error que obtienes.

Saludos...
Responder Con Cita
  #18  
Antiguo 19-07-2021
Avatar de PabloTech
PabloTech PabloTech is offline
Miembro
 
Registrado: ene 2007
Ubicación: Tucumán, Argentina
Posts: 82
Poder: 18
PabloTech Va por buen camino
Poner ancho de columna...

Hola amigos y gracias manelb.
Ya lo descubrí y les comento cómo lo resolví. El problema en la función era el tipo de dato del argumento Width, yo había puesto Real pero debe ser Variant. Lo descubrí hacendo debuging y asignándole a

Código Delphi [-]
ColumnWidth := ColumnWidth * 2;
vi que sí funcionaba. Entonces supuse que el problema si era el tipo de dato.

Al final convertí la función en procedimiento mejor.



Código Delphi [-]
procedure TAplExcel.PonerAnchoColumna (Column: Variant; Width: Variant);
var Obj_Col: Variant;
begin
  Obj_Col := Obj_Excel.Columns[Column];
  Obj_Col.ColumnWidth := width;
end;


En la implementación, solo tengo que indicar cuál es la columna y qué tan ancho la necesito, por ejemplo 10,71.
Código Delphi [-]
    // Pone el ancho de la columnas.
    MyExcel.PonerAnchoColumna(1, 8.00);
    MyExcel.PonerAnchoColumna(2, 10.71);
    MyExcel.PonerAnchoColumna(3, 45.14);


Mil gracias.!
__________________
Cita:
Cuando respetes al ilustrado y al ignorante, al rico y al pobre, al bello y al feo, estarás muy cerca de la sabiduría, que trasciende lo aparente.

E. Rharo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como utilizar Apis? JoeyJordison Varios 5 12-01-2007 21:48:52
como Utilizar una DLL de VB KaTo Varios 0 30-05-2004 19:01:30
como utilizar el UpdateSQL Irina SQL 10 17-03-2004 15:35:39
Como utilizar un DCR y PAS andrestsas Varios 1 26-10-2003 19:31:58
como utilizar sql plus fcran Oracle 2 10-09-2003 02:44:01


La franja horaria es GMT +2. Ahora son las 05:38:40.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi