Xml, Html y vb
[Informes con datos guardados en xml, y mostrados en html]

Fecha: 13/03/2003
Autor: Jos� F. Romaniello


Introducci�n

Muchas veces cuando comenzamos a desarrollar una aplicaci�n somos concientes de su simplicidad, pero aparece siempre la duda de los benditos "informes". Crystal reports, Datareport y algunos otros dise�adores de informes que cuestan cierto dinerillo.

A veces es inentendible como para generar informes tan simple recurrimos a herramientas pagas como "Crystal Report". 

En colaboraci�n con un compa�ero que he conocido en un curso de programaci�n en tres capas, nos hemos embarcado en la tarea de crear alg�n m�todo para desarrollar informes simples, con controles gratuitos, y finalmente hemos dado con resultados muy positivos.

Para continuar leyendo este articulo ser�a importante tener una noci�n m�nima de Xml.

Mezclando y mezclando desarrolle por as� decirlo "un modelo" de informes, donde los datos son transportados de una tabla o consulta a un documento XML, y el formato (colores, tipos de letras, etc.) almacenados en un documento Html. Se crea una parte en la aplicaci�n que permite "editar" simplificadamente el contenido del html, sin modificar el origen de datos.

 

Informe Simple

Los controles y clases que he creado no tienen tanta importancia como la forma en que esto se realiza, as� que debido a su complejidad, decid� crear una versi�n m�s entendible y funcional.

La forma en que se guardan los datos en el Xml es mediante open, write y close del tratamiento de archivos comunes que se realiza con vb.

La estructura del xml es del tipo

<NombreInforme>

    <NombreElemento>

        <Campo1>Contenido</Campo1>

        <Campo2>Contenido</Campo2>

    </NombreElemento>

    <NombreElemento>

        <Campo1>Contenido</Campo1>

        <Campo2>Contenido</Campo2>

    </NombreElemento>

</NombreInforme>

Bien, ahora teniendo los datos en el xml, procedo a contarles acerca de la importaci�n del Xml en un Html. Por ahora lo que he encontrado es bastante "pobre", por que solo funciona para "Ms Internet Explorer", y a veces hace renegar un poco.... Sobre todo por que no existe informaci�n acerca de esta funcionalidad del html en ning�n editor de html, ni si quiera en el propio "Front Page", que me sorprendi� bastante que no tuviera.

Lo que hago es despu�s del tag <body> insertar un tag que abre de alguna manera un origen de datos:

<xml id="Od" src="informe.xml"></xml>

El Id es un identificador que nada tiene que ver con el contenido del documento Xml, y src esta por dem�s decir que es el nombre y ubicaci�n del fichero Xml.

A continuaci�n colocaremos una tabla de 2 filas y N columnas, donde N es igual a la cantidad de campos que tenga la tabla. Dicha tabla deber� contener una propiedad en el tag <table> que es el "datasrc", este tiene que ser equivalente al nombre del identificador del Xml... es decir:

<table datasrc="#Od" width="100%">

A continuaci�n sigue un tag que le da la caracter�stica a la fila 1 de ser cabecera de tabla <thead>, luego va el  <tr> y luego los <th>. Despu�s se cierran en el orden inverso.  Entre <th> y </th> ir�a el t�tulo del campo.

Luego de cerrar thead va el tag <tbody> , <tr> y finalmente <td>. Entre <td> y </td> debe ir :

<span datafld="NombreCampo"></span>

en vez de nombre campo tiene que ir el nombre del campo que aparece en el xml. Y luego se van cerrando los otros dos tags.

De esta manera funciona perfectamente, solo para Internet Explorer.

 

Informes Anidados

Algo muy com�n son los informes anidados es decir un informe que a su vez tiene subinformes. Tal es el caso de las Cuentas Corrientes o Facturas, donde un Item perteneciente al informe principal esta vinculado con un varios Items de un subinforme (Nro de Movimiento o Nro de factura).

Por ejemplo:

    Nro    Cliente    Fecha    Forma

        Producto    Cantidad    PrecioUnitario

 

A continuaci�n describir� como deben exponerse los datos en cada fichero (Xml, y html), para dotar de esta funcionalidad a nuestros informes.

El Xml debe tener la siguiente estructura:

<NombreInforme>

    <NombreElemento>

        <Campo1>Contenido</Campo1>

        <Campo2>Contenido</Campo2>

        <SubElemento>

            <SubCampo1>Contenido</SubCampo1>

            <SubCampo1>Contenido</SubCampo1>

        </SubElemento>

        <SubElemento>

            <SubCampo1>Contenido</SubCampo1>

            <SubCampo1>Contenido</SubCampo1>

        </SubElemento>

    </NombreElemento>

    <NombreElemento>

        <Campo1>Contenido</Campo1>

        <Campo2>Contenido</Campo2>

    </NombreElemento>

        <SubElemento>

            <SubCampo1></SubCampo1>

            <SubCampo1></SubCampo1>

        </SubElemento>

</NombreInforme>

Cada elemento puede tener N subelementos, donde N puede valer 0 en dicho caso debe escribirse como si fuera un solo subelemento sin ning�n contenido. 

A esta altura del art�culo cabe destacar que los elementos por mas que est�n contenidos dentro de otro elemento, deben siempre tener el mismo nombre, mientras que los campos finales, que poseen "el contenido" deben tener nombres diferentes en un mismo elemento, para que el Xml este "bien formado".

Con respecto al documento html debe ser igual al ejemplo sin anidar, solo que en vez de ser de 2 filas y N columnas, debe tener 3 filas. 

La tercera fila solo tendr� una columna y debe contener otra tabla mas en su interior, y en el tag <table> adem�s de la propiedad datasrc apuntando al identificador del xml, la propiedad datafld con el nombre del subelemento. 

Para el ejemplo de xml anterior:

<table datasrc="#Od" datafld="SubElemento" width="100%">

Y nuevamente se repite todo lo explicado para la primera tabla.

 

Salto de p�gina

Puede ser necesario algunas veces crear un salto de p�gina cada N registros. El salto de p�gina en html puede ser provocado mediante la siguiente etiqueta: 

<div style="page-break-before:always"></div>

Solo para Internet Explorer.

Podemos agregarle un campo a los elementos del Xml y al html (pero invisible), que sea nulo y en el registro que queremos provocar el salto el c�digo antes mencionado.

 

Quitar encabezado y pie de p�ginas autom�ticos del Iexplorer

Al momento de imprimir puede dotar de "calidad" a nuestros informes que no salgan los encabezados y pie de p�gina que el IExplorer tiene por defecto. 

Ya sea haciendo que no se imprima nada o que se imprima algo personalizado.

Para no hacer demasiado extenso el art�culo solo dir� que dichas caracter�sticas se encuentran en el registro de Windows en: 

"Software\Microsoft\Internet Explorer\PageSetup"

(si alguien necesita las funciones explicitas para modificar el registro en estas direcciones mandarme un mail)

Primero deben guardarse en algunas variables el contenido de estas, luego modificarlo, luego la impresi�n, y cuando regresa al proyecto, restaurar el valor anterior.

 

Algo de Vb

A continuaci�n sigue c�digo en Visual Basic:

Private Function GuardarDInf(strInforme As String, rsRecordset As ADODB.Recordset)
    'se recibe el nombre del informe en singular, (no plural)
    'por ejemplo; strinforme = "cliente",
    'y un recordset ya abierto de la tabla clientes.
    Dim i As Integer
    
    Open strInforme & ".xml" For Output As fXml
    'se abre el archivo xml en cuesti�n, para el ejemplo "cliente.xml"
        
        Escribir "<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?> "
        'se escribe el tag de descripci�n del xml
        
        Escribir Eq1(strInforme & "s")
        'se escribe el elemento 'madre' del xml
        'para el ejemplo "<clientes>"
        'cabe destacar que todos los demas elementos pertenecen
        'a <clientes>
        
        With rsRecordset
            Do While Not .EOF
            'recorremos la tabla
            
                Escribir Eq1(strInforme)
                'abrimos un elemento
                '<cliente>
                
                For i = 0 To .Fields.Count - 1
                'recorremos todos los campos de dicho registro
                
                    Escribir Eq1(.Fields(i).Name) & .Fields(i).Value & Eq2(.Fields(i).Name)
                    'abrimos el nombre del campo, escribimos el contenido
                    ', y cerramos el nombre del campo
                    '<Id>124</Id>
                    
                Next i
                
                Escribir Eq2(strInforme)
                'cerramos el elemento
                '</cliente>
            Loop
        End With
        
        Escribir Eq2(strInforme & "s")
        'cerramos el elemento madre
        
    Close fXml
    'cerramos el xml
    
    Ejecutar strInforme & ".html"
    'finalmente, o lo mostramos en algun objeto webbrowser de nuestra app.
    
End Function

Public Function Eq1(ByVal strCadena As String) As String
Eq1 = "<" & Trim(strCadena) & ">"
End Function

Public Function Eq2(ByVal strCadena As String) As String
Eq2 = "</" & Trim(strCadena) & ">"
End Function

Public Function Escribir(ByVal strCadena As String)
Print #fXml, strCadena
End Function

Nota: el c�digo expuesto anteriormente no debe ser copiado y pegado "intacto", puede contener incoherencias, solo lo expongo como ejemplo de lo sencillo que puede ser la creaci�n del Xml.

Espero que les haya sido interesante el art�culo y ojala me manden sugerencias y comentarios a mi mail. 

El archivo zip que adjunto debe ser descomprimido todo en la misma carpeta.

El contendi de dicho archivo es el siguiente:

Clientes.html Ejemplo de informe simple.
Clientes.xml Origen de datos del ejemplo de informe simple.
ClientesA.html Ejemplo de informe anidado.
ClientesA.xml Origen de datos del ejemplo de informe anidado.
Module1.bas M�dulo para cambiar el encabezado y pie de p�gina.

xmlhtmlvb.zip


ir al índice