USO DE LIBRERÍA OLE2 PARA GENERAR ARCHIVOS EXCEL EN FORMS 6I OLE.- Object Linking and Embedding (OLE). Esta librería nos permite interactuar con aplicaciones como Office, por medio de Visual Basic. Para poder utilizarla, la librería debe estar incluida en los paquetes de desarrollo del Forms.
Los objetos se definen mediante OLE2.OBJ_TYPE. Se deben definir los siguientes: app OLE2.OBJ_TYPE; wbs OLE2.OBJ_TYPE; wb OLE2.OBJ_TYPE; wss OLE2.OBJ_TYPE; ws OLE2.OBJ_TYPE; args OLE2.LIST_TYPE; cell OLE2.OBJ_TYPE;
---> APLICACIÓN EXCEL ---> LIBRO DE TRABAJO ---> HOJA DE TRABAJO ---> LISTADO DE ARGUMENTOS ---> CELDA
Primero se debe abrir Excel y adicionar un libro de trabajo. app := OLE2.CREATE_OBJ('Excel.Application'); wbs := OLE2.GET_OBJ_PROPERTY(app,'Workboo OLE2.GET_OBJ_PROPERTY(app,'Workbooks'); ks'); wb := OLE2.INVOKE_OBJ(wbs,'Add');
Luego se debe crear una Hoja de Trabajo sobre la cual vamos a escribir nuestro reporte. wss := OLE2.GET_OBJ_PROPERTY(app,'Worksheets'); ws := OLE2.INVOKE_OBJ(wss,'Add'); Le damos un nombre a la Hoja de Trabajo OLE2.SET_PROPERTY (ws, 'Name', 'Consumo de Tintas'); Para adicionar valor a una celda se debe pasar por parámetros el número de fila y columna (en este mismo orden), y luego setear la propiedad de valor. ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(ARGS, row_num); OLE2.ADD_ARG(args, Col_num);
----> Se crea la lista de argumentos ----> Se agrega al listado el numero de fila ----> Se agrega al listado el numero de columna
Se obtiene la celda en la fila y columna indicado CELL := OLE2.GET_OBJ_PROPERTY(WORKSHEET,'Cells', ARGS); Se elimina la lista de parámetros OLE2.DESTROY_ARGLIST(ARGS); Se setea la propiedad de valor de la celda. OLE2.SET_PROPERTY(CELL, 'Value',5); Para guardar el archivo se debe pasar como parámetro el nombre del archivo con la ruta completa. ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG( ARGS, 'C:\COMPARATIVO_CONSUMO.XLS'); OLE2.INVOKE(ws, 'SaveAs', ARGS); OLE2.DESTROY_ARGLIST(ARGS) ; Si el archivo ya existe, preguntará si se desea sobrescribir.
Si se desea mostrar el archivo en pantalla, se debe setear la siguiente propiedad. OLE2.SET_PROPERTY(app, 'Visible','True'); Para salir de Excel y cerrar el programa se debe invocar el comando Quit de la aplicación. OLE2.INVOKE(app,'Quit'); Siempre es importante liberar de memoria los recursos utilizados (OLE2.OBJ_TYPE). OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(ws); OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(wb); OLE2.RELEASE_OBJ(app); OLE2.RELEASE_OBJ(CELL);
Dando formato a un archivo de excel Se puede dar formato a una celda como a varias celdas a la vez (rango). Modificar la fuente Para modificar la fuente se debe primero obtener la propiedad Font de la celda y luego modificar sus propiedades. Se declara el objeto que contendrá la propiedad Font. font OLE2.OBJ_TYPE; Se obtiene propiedad Font de la celda. font := ole2.get_obj_property (CELL, 'Font'); Colocar la celda en negrita OLE2.SET_PROPERTY (font, 'Bold', TRUE); Colocar la celda en Cursiva OLE2.SET_PROPERTY (font, 'Italic', TRUE); Subrayar la celda OLE2.SET_PROPERTY (font, 'Underline', TRUE);
Para cambiar el color de fuente, se debe indicar el índice de la paleta de colores. Para ver cuál es el valor se puede acceder a la siguiente página http://www.mvps.org/dmcritchie/excel/colors.htm
OLE2.SET_PROPERTY(font, 'ColorIndex', INDEX_COLOR); No olvidarse de liberar el objeto de memoria OLE2.RELEASE_OBJ(font); Para cambiar el color de fondo, se debe obtener de la celda la propiedad Interior. Se declara el objeto que contendrá la propiedad Interior. v_interior OLE2.OBJ_TYPE; Se obtiene la propiedad Interior de la celda. v_interior := ole2.get_obj_property(CELL,'Interior'); Para cambiar el color de fondo, se debe indicar el índice de la paleta de colores. Para ver cuál es el valor se puede acceder a la siguiente página http://www.mvps.org/dmcritchie/excel/colors.htm ole2.set_property(v_interior,'ColorIndex',BOLOR); No olvidarse de liberar el objeto de memoria OLE2.RELEASE_OBJ(v_interior);
Alinear una celda Para alinear una celda se debe modificar las propiedades HorizontalAlignment, para la alineación Horizontal, VerticalAlignment, para modificar la alineación vertical. OLE2.SET_PROPERTY(CELL, 'HorizontalAlignment', ALIGN); OLE2.SET_PROPERTY(CELL, 'VerticalAlignment', ALIGN); Estas propiedades reciben valores binary_integer. Se pueden declarar constantes con los tipos de alineación. SUBTYPE xlHAlign IS binary_integer; CENTER CONSTANT xlHAlign := - 4108; CENTERACROSSSELECTION CONSTANT xlHAlign := 7; DISTRIBUTED CONSTANT xlHAlign := - 4117; FILL CONSTANT xlHAlign := 5; GENERAL CONSTANT xlHAlign := 1; JUSTIFY CONSTANT xlHAlign := - 4130; LEFT CONSTANT xlHAlign := - 4131; RIGHT CONSTANT xlHAlign := - 4152; Modificando la alineación de la celda. OLE2.SET_PROPERTY(CELL, 'HorizontalAlignment', CENTER); OLE2.SET_PROPERTY(CELL, 'VerticalAlignment', CENTER);
Agregar Bordes a una celda Para agregar un borde a una celda o rango de celdas, se debe obtener la propiedad Borders de la celda. Declarando el objeto que contendrá la propiedad Borders. borders OLE2.OBJ_TYPE; Obteniendo la propiedad Borders de la celda. borders := ole2.get_obj_property (CELL, 'Borders'); Modificando el estilo de línea de la celda (1=Contínuo). OLE2.SET_PROPERTY(borders, 'LineStyle', 1); Modificando el ancho de la línea del borde. Esta propieda recibe un valor binary_integer, los cuales se pueden declarar como constantes y pasarlos a la función. SUBTYPE XlBorderWeight IS binary_integer; xlHairline CONSTANT xlHAlign := 1; xlMedium CONSTANT xlHAlign := -4138; xlThick CONSTANT xlHAlign := 4; xlThin CONSTANT xlHAlign := 2; Modificando el grueso de la línea. OLE2.SET_PROPERTY(borders, 'Weight', xlThin); Modificando el Color de la línea del borde. Se debe indicar el índice de la paleta de colores (1 = negro). OLE2.SET_PROPERTY(borders, 'ColorIndex', 1); No olvidarse de liberar el objeto de memoria OLE2.RELEASE_OBJ(borders);
Seleccionando un rango de celdas Para seleccionar un rango de celdas se debe crear una lista de argumentos con el valor del rango de celdas, y luego pasarlo como parámetro para obtener la propiedad Range de la hoja de trabajo. Declarando el objeto que contendrá la propiedad Range RANGO OLE2.OBJ_TYPE; Creando la lista de argumentos y oteniendo la propiedad Range ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(ARGS, A1:C1); ---> De la Celda A1 a la celda B1 RANGO := OLE2.GET_OBJ_PROPERTY(WORKSHEET,'Range', args); OLE2.DESTROY_ARGLIST(ARGS); A la propiedad Range se la puede tratar como una celda y modificar sus propiedades de valor, fuente, color, alineación, bordes, etc. También se pueden combinar las celdas del rango mediante modificando a TRUE la propiedad MergeCells. OLE2.SET_PROPERTY(RANGO, 'MergeCells',true);
Ejemplo completo para generar un archivo Excel Función para modificar una celda PROCEDURE PU_P_CELL_OLE2 (WORKSHEET IN OUT OLE2.OBJ_TYPE, CELL IN OUT OLE2.OBJ_TYPE, ARGS IN OUT OLE2.LIST_TYPE, Row_num number, Col_num number, VALOR VARCHAR2, BOLD BOOLEAN, ITALIC BOOLEAN, UNDERLINE BOOLEAN, ALIGN binary_integer, BORDER BOOLEAN, BORDER_WEIGHT binary_integer DEFAULT NULL, FCOLOR number default null, BCOLOR number default null) IS font OLE2.OBJ_TYPE; v_interior OLE2.OBJ_TYPE; borders OLE2.OBJ_TYPE; /* PARÁMETROS RECIBIDOS WORKSHEET CELL ARGS Row_num Col_num VALOR BOLD ITALIC UNDERLINE ALIGN BORDER BORDER_WEIGHT FCOLOR BOLOR */
--- FUENTE --- INTERIOR DE LA CELDA --- BORDES
---> HOJA DE TRABAJO ---> CELDA ---> LISTADO DE ARGUMENTOS ---> NÚMERO DE FILA ---> NÚMERO DE COLUMNA ---> VALOR DE LA CELDA ---> SI LLEVA NEGRITA ---> SI LLEVA CURSIVA ---> SI LLEVA SUBRAYADO ---> ALINEACIÓN ---> SI LLEVA BORDES ---> GROSOR DEL BORDE ---> COLOR DE FUENTE ---> COLOR DE FONDO
BEGIN ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(ARGS, row_num); --- FILA OLE2.ADD_ARG(args, Col_num); --- COLUMNA CELL := OLE2.GET_OBJ_PROPERTY(WORKSHEET,'Cells', ARGS); OLE2.DESTROY_ARGLIST(ARGS); OLE2.SET_PROPERTY(CELL, 'Value',VALOR); -- ALINEACIÓN OLE2.SET_PROPERTY(CELL, 'HorizontalAlignment', ALIGN); OLE2.SET_PROPERTY(CELL, 'VerticalAlignment', ALIGN); -- FUENTE font := ole2.get_obj_property (CELL, 'Font'); OLE2.SET_PROPERTY (font, 'Bold', BOLD); OLE2.SET_PROPERTY (font, 'Italic', ITALIC); OLE2.SET_PROPERTY (font, 'Underline', UNDERLINE); -- COLOCAR BORDE IF BORDER=TRUE THEN borders := ole2.get_obj_property (CELL, 'Borders'); OLE2.SET_PROPERTY(borders, 'LineStyle', 1); OLE2.SET_PROPERTY(borders, 'Weight', BORDER_WEIGHT); OLE2.SET_PROPERTY(borders, 'ColorIndex', 1); OLE2.RELEASE_OBJ(borders); END IF; -- colocar color IF FCOLOR IS NOT NULL THEN OLE2.SET_PROPERTY(font, 'ColorIndex', FCOLOR); END IF; IF BOLOR IS NOT NULL THEN v_interior := ole2.get_obj_property(CELL,'Interior'); ole2.set_property(v_interior,'ColorIndex',BOLOR); OLE2.RELEASE_OBJ(v_interior); END IF; OLE2.RELEASE_OBJ(font); END;
Función que combina un rango de celdas PROCEDURE PU_F_RANGO_OLE2(WORKSHEET IN OUT OLE2.OBJ_TYPE, VALOR VARCHAR2, ARGS IN OUT OLE2.LIST_TYPE, BOLD BOOLEAN, ITALIC BOOLEAN, UNDERLINE BOOLEAN, ALIGN binary_integer, BORDER BOOLEAN, BORDER_WEIGHT binary_integer DEFAULT NULL, FCOLOR number default null, BCOLOR number default null) IS RANGO OLE2.OBJ_TYPE; FONT OLE2.OBJ_TYPE; borders OLE2.OBJ_TYPE; v_interior OLE2.OBJ_TYPE;
--- RANGO --- FUENTE --- BORDES --- INTERIOR DE LA CELDA
/* PARÁMETROS RECIBIDOS WORKSHEET ---> HOJA DE TRABAJO VALOR ---> RANGO DE CELDAS (X EJ: A1:C3) ARGS ---> LISTADO DE ARGUMENTOS BOLD ---> SI LLEVA NEGRITA ITALIC ---> SI LLEVA CURSIVA UNDERLINE ---> SI LLEVA SUBRAYADO ALIGN ---> ALINEACIÓN BORDER ---> SI LLEVA BORDES BORDER_WEIGHT ---> GROSOR DEL BORDE FCOLOR ---> COLOR DE FUENTE BOLOR ---> COLOR DE FONDO */ BEGIN ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(ARGS, valor); RANGO := OLE2.GET_OBJ_PROPERTY(WORKSHEET,'Range', args); OLE2.DESTROY_ARGLIST(ARGS); -- COMBINAR RANGO DE CELDAS OLE2.SET_PROPERTY(RANGO, 'MergeCells',true); -- ALINEACIÓN OLE2.SET_PROPERTY(RANGO, 'HorizontalAlignment', ALIGN); OLE2.SET_PROPERTY(RANGO, 'VerticalAlignment', ALIGN);
-- MODIFICAR FUENTE font := ole2.get_obj_property (RANGO, 'Font'); OLE2.SET_PROPERTY (font, 'Bold', BOLD); OLE2.SET_PROPERTY (font, 'Italic', ITALIC); OLE2.SET_PROPERTY (font, 'Underline', UNDERLINE); -- COLOCAR BORDE IF BORDER=TRUE THEN borders := ole2.get_obj_property (RANGO, 'Borders'); OLE2.SET_PROPERTY(borders, 'LineStyle', 1); OLE2.SET_PROPERTY(borders, 'Weight', BORDER_WEIGHT); OLE2.SET_PROPERTY(borders, 'ColorIndex', 1); OLE2.RELEASE_OBJ(borders); END IF; -- colocar color IF FCOLOR IS NOT NULL THEN OLE2.SET_PROPERTY(font, 'ColorIndex', FCOLOR); END IF; IF BOLOR IS NOT NULL THEN v_interior := ole2.get_obj_property(RANGO,'Interior'); ole2.set_property(v_interior,'ColorIndex',BOLOR); OLE2.RELEASE_OBJ(v_interior); END IF; OLE2.RELEASE_OBJ(font); OLE2.RELEASE_OBJ(RANGO); END;
Función genera archivo PROCEDURE PU_P_EXCEL_OLE2 IS CURSOR C_DATOS IS SELECT NOMBRE, VALOR FROM TABLA; REGISTRO C_DATOS%ROWTYPE; RES NUMBER; row_num number; col_num number; cell_val number; app OLE2.OBJ_TYPE; wbs OLE2.OBJ_TYPE; wb OLE2.OBJ_TYPE; wss OLE2.OBJ_TYPE; ws OLE2.OBJ_TYPE; args OLE2.LIST_TYPE; cell OLE2.OBJ_TYPE;
---> APLICACIÓN EXCEL ---> LIBRO DE TRABAJO ---> HOJA DE TRABAJO
---> CELDA
-- ALINEACIÓN DE CELDAS SUBTYPE xlHAlign IS binary_integer; CENTER CONSTANT xlHAlign := - 4108; CENTERACROSSSELECTION CONSTANT xlHAlign := 7; DISTRIBUTED CONSTANT xlHAlign := - 4117; FILL CONSTANT xlHAlign := 5; GENERAL CONSTANT xlHAlign := 1; JUSTIFY CONSTANT xlHAlign := - 4130; LEFT CONSTANT xlHAlign := - 4131; RIGHT CONSTANT xlHAlign := - 4152; -- TIPO BORDES DE CELDAS SUBTYPE XlBorderWeight IS binary_integer; xlHairline CONSTANT xlHAlign := 1; xlMedium CONSTANT xlHAlign := -4138; xlThick CONSTANT xlHAlign := 4; xlThin CONSTANT xlHAlign := 2;
BEGIN -- ABRE EXCEL app := OLE2.CREATE_OBJ('Excel.Application'); -- ABRE UN NUEVO LIBRO DE TRABAJO Y LO ADICIONA wbs := OLE2.GET_OBJ_PROPERTY(app,'Workbooks'); wb := OLE2.INVOKE_OBJ(wbs,'Add'); -- ABRE UNA NUEVA HOJA DE TRABAJO Y LO ADICIONA wss := OLE2.GET_OBJ_PROPERTY(app,'Worksheets'); ws := OLE2.INVOKE_OBJ(wss,'Add'); OLE2.SET_PROPERTY (ws, 'Name', 'Consumo de Tintas'); row_num:=1; PU_P_CELL_OLE2(ws, cell, args, row_num, 1, 'Análisis de Consumo', false, false, false, CENTER, FALSE); -- Unifica celdas del título y lo alínea a la izquierda PU_F_RANGO_OLE2(ws, 'A'||row_num||':C'||row_num, ARGS, true, true, true, LEFT, FALSE); row_num:=row_num+2; -- Escribe el valor de la celda, alinea al centro y le coloca un borde simple. PU_P_CELL_OLE2(ws, cell, args, row_num, 13, 'Nombre', true, false, false, CENTER, TRUE, xlThin); PU_P_CELL_OLE2(ws, cell, args, row_num, 14, 'Valor', true, false, false, CENTER, TRUE, xlThin); row_num:=row_num+1;
-- LLENA EL ARCHIVO IF C_DATOS%ISOPEN THEN CLOSE C_ DATOS; END IF; OPEN C_ DATOS FETCH C_ DATOS INTO REGISTRO; WHILE C_ DATOS %FOUND LOOP PU_P_CELL_OLE2(ws, cell, args, row_num, 1, REGISTRO.NOMBRE, false, false, false, CENTER, TRUE, xlThin); PU_P_CELL_OLE2(ws, cell, args, row_num, 2, REGISTRO.VALOR, false, false, false, CENTER, TRUE, xlThin); row_num:=row_num+1; FETCH C_ DATOS INTO REGISTRO; END LOOP; CLOSE C_ DATOS; -- guardar documento ARGS := OLE2.CREATE_ARGLIST; OLE2.ADD_ARG( ARGS, 'C:\ANALISIS_CONSUMO.XLS'); OLE2.INVOKE(ws, 'SaveAs', ARGS); OLE2.DESTROY_ARGLIST(ARGS) ; RES:=PU_F_ENVIA_ALERTA('Archivo creado exitosamente en C:\COMPARATIVO_CONSUMO.XLS','Información','Aceptar',NULL,NULL,3); -- SETEA PARA QUE SE MUESTRE EN PANTALLA -- OLE2.SET_PROPERTY(app, 'Visible','True'); -- CIERRA EXCEL OLE2.INVOKE(app,'Quit');
-- liberar recursos OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(ws); OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(wb); OLE2.RELEASE_OBJ(app); OLE2.RELEASE_OBJ(CELL); EXCEPTION WHEN OTHERS THEN OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(ws); OLE2.RELEASE_OBJ(wbs); OLE2.RELEASE_OBJ(wb); OLE2.RELEASE_OBJ(app); OLE2.RELEASE_OBJ(CELL); OLE2.INVOKE(app,'Quit'); END; Al presionar el botón de generar Excel. -- Verificar si el computador soporta OLE2 IF OLE2.ISSUPPORTED=TRUE THEN PU_P_EXCEL_OLE2; ELSE Null; END IF;