BlogoDev

Técnicas

Crystal Reports con DataSet’s en ASP.Net

by P-los on Jan.20, 2010, under Técnicas, Web

Esta ocasión me topé con la necesidad de mostrar un reporte de Crystal Reports en un formulario .aspx de .NET tomando como origen de datos un DataSet. Tras un buen rato de probar con diferentes métodos que me encontré en Google y varios foros que no lograron resolver mis dudas, he aqui una forma sencilla para lograr este cometido.

Lo primero que hay que hacer es crear el DataSet (archivo .xsd). No mostraré aqui como crearlo pues ya hay muchos sitios con esa información, así que supondremos que ya lo tenemos creado.

Ahora crearemos nuestro reporte. Agregamos un nuevo elemento a nuestro proyecto de tipo “Crystal Reports” y en el “Field Explorer” en el nodo “Database Fields” seleccionamos “Database Expert” en el menú contextual:

DatabaseExpert

Dentro del arbol en el cuadro izquierdo se mostrarán los DataSets que tenemos en nuestra solución. Agregamos el (los) DataSet o Tabla que requerimos y aceptamos. Una vez hecho esto, en el “Field Explorer” se mostrarán las tablas y campos que hayamos seleccionado. Arrastramos estos campos a nuestro reporte para diseñarlo segun nuestras necesidades.

Ahora en nuestro archivo .aspx agregamos un CrystalReportViewer para mostrar nuestro reporte.

En la parte de código, la parte medular es la siguiente:

Visual Basic:

' Llenar DataSet ya sea desde una base de datos, un web service, o datos ingresados por el usuario
Dim dsDatos as dsClientes() = ObtenerDatos()
' Creamos el objeto
Dim rpt As New CrystalDecisions.CrystalReports.Engine.ReportDocument()
' Indicamos la ruta del archivo del reporte que requerimos. En este caso suponemos que está en la raiz de nuestro proyecto
rpt.FileName = Server.MapPath("~\rptListadoClientes.rpt")
' Establecemos nuestro DataSet como origen de datos de nuestro reporte
rpt.SetDataSource(dsDatos)
' Indicamos al Report Viewer cual es el reporte que queremos mostrar
CrystalReportViewer1.ReportSource = rpt

C#

// Llenar DataSet ya sea desde una base de datos, un web service, o datos ingresados por el usuario
dsClientes dsDatos = ObtenerDatos();
//Creamos el objeto
CrystalDecisions.CrystalReports.Engine.ReportDocument rpt = New CrystalDecisions.CrystalReports.Engine.ReportDocument();
// Indicamos la ruta del archivo del reporte que requerimos. En este caso suponemos que está en la raiz de nuestro proyecto
rpt.FileName = Server.MapPath("~\rptListadoClientes.rpt");
// Establecemos nuestro DataSet como origen de datos de nuestro reporte
rpt.SetDataSource(dsDatos);
//Indicamos al Report Viewer cual es el reporte que queremos mostrar
CrystalReportViewer1.ReportSource = rpt;

Con esto nuestro reporte se mostrará en la ventana del navegador de internet de nuestro usuario sin la necesidad de que tenga que descargar un archivo PDF o DOC.

1 Comment :, more...

Consumir WebServices JSon desde PHP

by P-los on Nov.14, 2009, under Funciones, Técnicas, Web

Hoy gracias a que estuve apoyando a un proyecto de unos amigos, les traigo un simple ejemplo de como consumir WebServices hechos con JSon desde PHP.

Para este ejemplo utilizaremos una búsqueda en Twitter, ya que cumple con estas características.

Primero tenemos que formar una dirección URL con la ubicación de nuestro WebService, que para nuestro caso sería:
$URL="http://search.twitter.com/search.json?q=" . $Busqueda;
donde $Busqueda es el término que vamos a buscar.

Primero vamos a abrir esta dirección como un archivo cualquiera y guardamos su contenido en una variable:
$archivo = fopen ($URL, "r");
$texto = fgets($archivo);

Ahora, aprovechamos una función de PHP 5.2.0 o superior, llamada json_decode() que nos regresa un objeto con el contenido del JSon, cuyas propiedades son los valores entregados por el WebService, y podremos mostrar su contenido:

$json = json_decode($texto);
echo "max_id=".$json->max_id;
echo "next_page=".$json->next_page;

Para este caso particular, Twitter nos entrega un arreglo con los resultados, que facilmente podemos meter en un foreach:

foreach($json->results as $valor)
{
echo "<img src='".$valor->profile_image_url."' style='width:60px;height:60px;' /><br />";
echo "<h1>".$valor->from_user."</h1><br />";
echo $valor->text."<br />";
}

y así de facil tenemos un cliente que muestra los resultados de busqueda en twitter desde PHP.

2 Comments :, , more...

Widgets con PHP

by P-los on Sep.01, 2009, under Funciones, Técnicas

En este post voy a exponer un método para crear widgets. Como mencionaba al principio de este blog, parte de mi objetivo al escribir aqui es obtener retroalimentación de su parte con tal de que todos mejoremos en los desarrollos que hacemos.

Lo que estoy haciendo con esto utiliza una base de datos para gestionar que widgets estan disponibles, que paneles tenemos disponibles para mostrarlos y los parámetros que se utilizarán para cada instancia de los widgets. Las tablas tienen la siguiente estructura:

Widgets: Aqui se almacenan los widgets que tenemos disponibles

  • IdWidget – Int – PK – Identificador del widget
  • Nombre – varchar(30) – Nombre del Widget
  • Archivo – varchar(30) – Nombre del archivo que contiene el widget. Incluir la extensión del archivo
  • Clase – varchar(30) – Nombre de la clase que representará el widget. Se separa del nombre del archivo para el caso de que haya 2 o más widgets dentro de un mismo archivo de PHP

Paneles: Representa cada una de las zonas capaz de mostrar los widgets, por ejemplo, las columnas derecha e izquierda, un bloque al pie de la página, etc.

  • IdPanel – Int – PK – Identificador del panel
  • Nombre – varchar(30) – Nombre que tiene el panel

PanelWidget: Indica que widgets se muestran en cada panel

  • IdPanelWidget – Int – PK – Identifica a cada uno de los widgets que se mostrarán
  • IdPanel – Int – Id del panel al que se hace referencia
  • IdWidget – Int – Id del tipo de widget que se utilizará
  • Orden – Int – Indica el orden en que se mostrarán los widgets

ParametrosWidget: En caso de que los widgets que tengamos requieran algún tipo de parámetro, aqui es donde se almacenarán

  • IdParametro – Int – PK – Identificador del parámetro
  • IdPanelWidget – Int – Identifica la instancia del widget para el que se aplicará este parámetro
  • NombreParametro – varchar(30) – El nombre del parámetro
  • Valor – varchar(100) – El valor del parámetro

En todas estas tablas es posible agregar campos según sean requeridos para nuestra aplicación.

Ya estando en nuestra aplicación de PHP, crearemos una clase abstracta que nos servirá de molde para crear nuestros widgets que estará en un archivo llamado “absWidget.php”:

<?php
abstract class absWidget {
    public $params;
    public $idPanelWidget = 0;
    function ObtenerParametros(){
        global $mySql;
        $this->params = new ArrayObject();
        if($this->idPanelWidget!=0)
        {
            $res=$mySql->consulta("select NombreParametro, Valor from ParametrosWidget where IdPanelWidget= ".$this->idPanelWidget);
            while($arr=$mySql->fetch_assoc($res)){
                $this->params[$arr['NombreParametro']]=$arr['Valor'];
            }
        }
    }
    abstract function MostrarWidget();
}
?>

En esta clase se está utilizando una variable global llamada $mySql, esta es la clase para conextarse a MySql que expuse tiempo atras, y se crea desde antes, ya sea en el index, o donde se instancía el framework que estemos utilizando / creando).

A continuación sigue la creación del widget propiamente dicho. Como podran imaginarse, ésta hereda de la clase abstracta absWidget. He aquí un ejemplo sencillo:


<?php
require_once ('Framework/modulos/absModulos.php');
class modBuscar extends absModulos {
    function MostrarModulo() {
        ?>
        <h1>Buscar</h1>
        <form id="modBusqueda" method="get" action="index.php" >
            Buscar:<br />
            <input type="text" name="busqueda" /><br />
            <input type="submit" value="Buscar" />
        </form>
        <?php
    }
}
?>

Este ejemplo lo que hace es solicitar una búsqueda. Ya depende de cada aplicación que se esté haciendo si se utiliza el método POST o el método GET para procesar la llamada al servidor, así como el nombre de las variables. Estos temas no son materia del presente post, así que no los tocaré por el momento.

Lo único que hacemos es crear una función que implemente a MostrarWidget() y lo que hace es, como su nombre lo indica, mostrar el widget que se está creando. Si recuerdan, cada ocasión que se muestra un widget puede tener diferentes parámetros. Para obtener estos parámetros de la base de datos, hay que hacer una llamada a $this->ObtenerParametros(). Una vez hecho esto, los parámetros los tendremos en el array asociativo $this->params[] y podremos utilizarlo a nuestro gusto.

Por último, nos queda llamar desde nuestra plantilla cada uno de los páneles que queremos. Para esto, he aquí una funcion (mal hecho, pero yo la tengo como una función global o estatica) para buscar en la base de datos cuales son los widgets que se mostraran en un panel y mostrarlos:

function MostrarPanel($nombrePanel)
{
    global $mySql;
    //Obtener los modulos correspondientes a este panel
    $res=$mySql->consulta("SELECT idPanelWidget, archivo, clase
FROM paneles
INNER JOIN panelWidget ON paneles.idpanel = panelWidget.idpanel
inner join Widgets on panelWidget.idWidget = Widgets.idWidget
where descripcion = '$nombrePanel'
order by orden");
    while($arr=$mySql->fetch_assoc($res))
    {
        //Instanciar las clases adecuadas
        require_once("Framework/Widgets/".$arr['archivo']);
        $widget = new $arr['clase']();
        $widget->idPanelWidget = $arr['idPanelWidget'];
        //Mostrar el contenido del módulo
        $modulo->MostrarWidget();
    }
}

Una vez teniendo esta, ya podemos llamarla mandandole como parámetro el nombre del panel que vamos a mostrar, por ejemplo:
MostrarPanel('IZQUIERDO');
Esto ya pudiera ser dentro de nuestra plantilla.

Lo único que quedaría pendiente, y lo dejo para cada quien, es un pequeño panel de control para administrar que widgets mostrar en cada panel, en que orden mostrarlos, y que parametros utilizará cada uno de ellos.

2 Comments :, , more...

Objetos dinámicos con PHP

by P-los on Jul.08, 2009, under Funciones, Técnicas

Con php utilizando OOP, existe una forma sencilla para utilizar la herencia y polimorfismo. La idea es instanciar un objeto teniendo el nombre de la clase en un string, ya sea constante o una variable. La forma típica de hacer esto (o al menos la unica que yo conocía) era la siguiente:

$objeto = new clase();

Si lo que queríamos es instanciar diferentes clases heredadas de una misma, o que implementen una interfase, lo que hacía era un switch para definir cual utilizar:

switch(condicion){
case 1: $objeto = new clase1(); break;
case 2: $objeto = new clase2(); break;
}

Sin embargo, despues de buscar mucho por internet, me encontré con que es posible instanciar un objeto en base a un string, esto es:

$objeto = new "clase1"();

Una vez que comprobé esto, probé con éxito el utilizar una variable para el mismo fin:

$objeto = new $nombreClase();

¿Para que puede servir esto? Estoy trabajando en un sistema para mostrar widgets, los cuales se cargan en base a la información guardada en una base de datos, con la intensión de facilitar la inclusión y administración de los mismos. El cómo lo pondré más adelante en un nuevo post, pero basicamente es lo siguiente:

<?php
function Mostrar($nombre){
require_once($nombre.".php");
$objeto=new $nombre();
$objeto->MostrarWidget();
}
?>

De esta manera, la función recibe el nombre de la clase que se desea mostrar, incluye el archivo correspondiente (suponiendo que la clase está en un archivo con el mismo nombre) y llama a una función específica.

2 Comments :, , more...

Técnicas – TSQL 2

by P-los on Apr.23, 2009, under Bases de Datos, Técnicas

Previamente les mostraba la forma de simplificar las sentencias SQL cuando deseamos filtrar en base al tipo “Todas” o “Solo Activas”. ¿Que pasa si deseamos dar más opciones? Pongo el siguiente ejemplo para especificar la situación:

Un pedido puede tener uno de los siguientes estados: Recibido, En proceso, Procesado, Enviado, Cancelado.

La forma erronea que me he encontrado implementada en algunos sistemas es la siguiente:
if (@todos = 1)
begin

select campo1, campo2 from pedidos
end
else
begin

select campo1, campo2 from pedidos where estado = @estado
end

Utilizando esta forma, en la interface de usuario es necesario mostrar por ejemplo, un checkbox para mostrar todos, y en caso de que esté desmarcado, habilitar un combo con las opciones de los diferentes estados posibles. Como podrán ver, esto requiere que se tenga un poco de trabajo de más al tener que programar las funciones del checkbox.

Solución:

Vamos a utilizar solamente combo para mostrar las opciones. A este combo hay que añadir la opción “Todos”, dandole un valor diferente al que tengan las demas opciones. Para este ejemplo vamos suponer que los valores de los diferentes estados son numeros enteros, del 1 en adelante, así que a la opción “Todos” le asignaremos el valor “-1″

Al momento de crear nuestra sentencia SQL quedaría de la siguiente manera:

select campo1, campo2 from pedidos where (estado = @estado or @estado = -1)

Así, cuando la variable @estado es -1, sin importar el valor que tenga el campo estado en la tabla, el registro se va a mostrar, y cuando la variable @estado tiene un valor diferente, se mostrarán únicamente los registros donde el valor del campo y el valor del parámetro sean iguales.

De esta manera, en primera instancia reducimos la cantidad de parámetros (antes: @todos y @estado, ahora: @estado) y al momento de hacer alguna modificación en los campos a mostrar, se hará el cambio solo en 1 sentencia, simplificando así la labor de mantenimiento.

2 Comments :, , more...

Técnicas – TSQL 1

by P-los on Apr.20, 2009, under Bases de Datos, Técnicas

Ultimamente me ha tocado hacer revisiones de mantenimiento a un sistema, y me he encontrado en los procedimientos almacenados con algo como lo siguiente:

if (@Todos = 1)
begin

select campo1, campo2 from tabla
end
else
begin

select campo1, campo2 from tabla where activo = 1
end

El principal problema con esta forma, es que al momento de cambiar los campos que se requieren mostrar, es necesario modificar las 2 sentencias para no provocar errores.

Para el presente ejemplo, estaremos asumiendo que:

  1. activo es el campo de la tabla en base al que se filtrará la información
  2. @Todos es el parámetro del procedimiento almacenado que indica de que manera filtrar la información

La forma de corregir esto, haciendo más sencillo el código, es modificar la clausula where de la siguiente manera:

select campo1, campo2 from tabla where (activo = 1 or @Todos = 1)

De esta manera, se obtienen los resultados en base a la siguiente tabla:

activo @Todos Resultado
0 0 No se muestra
0 1 Si se muestra
1 0 Si se muestra
1 1 Si se muestra

Esta tabla es por cada registro de nuestra tabla.

Esta forma de simplificar la estructura de nuestros procedimientos almacenados (o métodos equivalentes) aplica unicamente cuando el campo en base al que se filtra es de tipo binario (o booleano). En un post posterior estaré mostrando la forma que utilizo para simplificar las sentencias cuando el campo mencionado puede tener uno de muchos valores diferentes.

1 Comment :, , more...

Paginas

 

July 2010
M T W T F S S
« Jun    
 1234
567891011
12131415161718
19202122232425
262728293031