![]() |
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:confused: |
|
Gracias, ensayare a ver como me va...
|
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:
o intentar capturar alguna ejecución de Excel que ya esté activa en el PC con esto otro:
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.
|
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í:
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. |
:D Muchas gracias FLECHA, esta ayuda me responde las dudas que me surgieron.
|
Una cosita más
:D
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.
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. :cool: |
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
|
No sabes como utilizarlo??
|
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 |
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.
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 No lo he provado, pero quizá esto equivalga al código en VB Excel. Si con ésto saltara una excepction, quizá habría que cambiarlo por esto otro: 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 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... Que equivale en VB de Excel a poner ésto... Código:
Cells(2,1).Interior.ColorIndex = $00000003 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" 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. |
Cita:
|
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 //---------- |
Gracias por esa explicación y tu aporte tan grade, tengo una inquietud Flecha, cuando tengo instalado office 2007 funciona el mismo codigo???
|
Buen aporte que me había pasado desapercibido. ^\||/:)
|
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. El mensaje dice: "No se puede asignar la propiedad ColumnWidth de la clase Range". ¿Me pueden ayudar con esto? Gracias de nuevo. |
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.
Fíjate que concuerda bastante con el mensaje de error que obtienes. Saludos... |
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 vi que sí funcionaba. Entonces supuse que el problema si era el tipo de dato. Al final convertí la función en procedimiento mejor.
En la implementación, solo tengo que indicar cuál es la columna y qué tan ancho la necesito, por ejemplo 10,71.
Mil gracias.!:D |
La franja horaria es GMT +2. Ahora son las 00:05:52. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi