miércoles, 17 de septiembre de 2008

Macros Excel en LN4

(Sacado del CSS de Meta4 y ampliado)

El número de métodos del objeto Excel es muy limitado, por lo que en ocasiones, se puede requerir la utilización de nuevos métodos de EXCEL accesibles vía OLE, a través de la OLEEXEC.DLL.

El Meta4Object Excel instancia un objecto aplicación en el nodo raíz y una colección Workbooks en el nodo hijo. En esa colección no se soportan más que unos pocos métodos (Add, close ...), dado que los métodos de operaciones con hojas de cálculo, no están implementados a nivel de colección, sino a nivel de instancia, la cual sin embargo no está accesible.

Así pues lo primero, tras una llamada de la colección a "Add", que es cuando se crea la nueva hoja de cálculo, es cuando se puede obtener el handle de objeto Workbook instanciado dentro de la colección Workbooks. Como no se tiene referencia directa, se puede obtener, por ejemplo, utilizando la jerarquía de clases de Excel, utilizando la propiedad "ActiveWorkbook" de la clase "Application", para obtener el Handle de la hoja de cálculo. Si hacemos llamadas en el nodo raíz, nos devolvería el Handle en la misma propiedad que donde se ha almacenado el handle propio de la clase aplicación, y se perdería. 

  • Créate un Meta4Object nuevo, CSL_EXCEL que herede del Meta4Object EXCEL estándar. (Podrías tocar el propio Meta4Object EXCEL estándar pero mejor hacerlo así)
  • Mapealo y colocalo en el arbol de ejecución, para que las llamadas a EXCEL se hagan siempre contra tu Meta4Object.
  • Crea un nuevo nodo nodo y su estructura de nodo, que se debe crear a la misma altura que EXCEL_WORKBOOKS, por ejemplo ACTIVE_WORKBOOK. Se añaden las propiedades ERRORS, InterfacePointer y ParentInterfacePointer como en el nodo EXCEL_WORKBOOKS. En la tercera, se almacena el puntero del nodo padre a través del conector, conectando con la propiedad InterfacePointer del nodo raíz para leer el handle de la clase Application (nodo EXCEL).


  • Para implantar la llamada a la propiedad "ActiveWorkbook", debe llamarse a la función GetObjectFromProperty. Para ello, se crea un método (por ejemplo GET) de tipo DLL que referencie el recurso "OleExec.dll", método "GetObjectFromProperty", con un parámetro.
  • Para realizar la llamada, crea un método  (por ejemplo INICIALIZAR) de tipo ln4 en el mismo nodo, realizar el siguiente código; 
AddRegister()
MoveTo(Count()-1)
Get("ActiveWorkbook")
  • Sobre éste nodo, con el valor de InterfacePointer conseguido, se pueden realizar llamadas a los métodos de la clase "WorkBook", creando un método que ejecute la llamada "SaveAs". El método debe llamarse EXACTAMENTE IGUAL que la función que se quiera invocar a través de OLE. En este caso SAVEAS, con código DLL, y recurso "OleExec.dll", método "OLE_Execute" (se llama a la ejecución OLE del método cuyo nombre venga determinado por el identificador del item). Se debe indicar que tenga un parámetro que será la ruta de grabación. Posteriormente podrá ser invocado de la siguiente manera:

EXCEL!ACTIVE_WORKBOOK.INICIALIZAR()
EXCEL!ACTIVE_WORKBOOK.SAVEAS(“c:\MiArchivoExcel.xls”)

Adjunto la definición de los métodos creados:
Método GET:

Método INICIALIZAR:
Método SAVEAS:




Espero que os sirva...

7 comentarios:

MaMBrU dijo...

Hola Oscar.

Estoy necesitando alguna interacción con EXCEL que tampoco parece soportar el objeto nativo.

Sabes como controlar el formato de la celda de excel, color por ejemplo.

¿Tendira que hacer algo parecido?, tienes alguna documentación del modelo de excel, o de como hacer esto.

Muchas gracias!!!!

MaMBrU dijo...

Ya logre cambiar el color de la celda.

Cree un nuevo nodo para obtener el objeto "Interior" que es la propiedad de una celda y a este objeto le cambio la proiedad "ColorIndex"

Este artículo me sirvio de base, muy bueno.

Si alguien necesita el detalle de lo que hice me avisan.

Oscar López dijo...

MaMBru, por favor, te agradecería que me hicieras llegar cómo lo hiciste a
oscar.lopezgrandmontagne@gmail.com
y que me dieras el permiso para publicarlo.

Gracias!
Un saludo!

Anónimo dijo...

Seria muy bueno conocer como se hizo referencia a esta funcionalidad. Gracias!

Saludos,

Oscar López dijo...

Podeis encontrar más información en el siguiente post, redactado con la colaboración de Lucas Gutierrez Jaramillo de Ceiba Software House (www.ceiba.com.co)

http://m4peoplenet.blogspot.com/2008/10/colaboracin-de-lucas-gutirrez-jaramillo.html

Un saludo,
Oscar L.

Paco Vela. dijo...

Hola,

Siento revivir un post tan antiguo, pero creo es el que más se acerca a mi duda.

Vaya por delante que soy un novato (muy muy novato) con esto de Meta4, así que puede que mi duda o mis razonamientos al respecto sean pueriles.

Tengo un meta4object que realiza un informe, y utiliza el meta4object EXCEL para montarse un fichero Excel con el resultado y luego enviarlo por mail.

El problema que tengo es que algunos de los campos que se recuperan son de tipo texto, pero su contenido es numérico, y al hacer la inserción en Excel con EXCEL.EXCEL_CELLS.Value(valor), al ser el formato de celda por defecto el "General", lo convierte a número.
Esto me da problemas porque hay algunos campos como por ejemplo el ID de persona, que es un campo de texto de ancho fijo, y se rellenan con ceros a la izquierda para completar. Por ejemplo "000345". Pero al hacer la inserción se pierde el formato, y me queda como "345".

No he encontrado ningún método para cambiar el formato de la celda y decir que es un texto. ¿Existe? ¿Hay alguna forma de hacerlo?.

Si no, se me ocurren dos formas de hacerlo. Una mediante una macro, como se explica aquí, y otra creando una plantilla de Excel con todos los formatos de texto, y crear el documento con esa plantilla.

¿podéis echarme algo de luz?

Gracias y saludos,

Paco Vela.

Oscar López dijo...

Paco, lo que suelo hacer o bien generas una plantilla para contener la salida o bien a la hora de hacer el EXCEL.EXCEL_CELLS.Value(valor) añado EXCEL.EXCEL_CELLS.Value("'" + valor) [Siempre y cuando valor sea una cadena, si fuera un número, ponlo como ToString(valor).

Un saludo!
Oscar L.