Ver Mensaje Individual
  #1 (permalink)  
Antiguo 24/02/2009, 22:02
K-SuMa
 
Fecha de Ingreso: diciembre-2007
Mensajes: 50
Antigüedad: 16 años, 4 meses
Puntos: 1
Aporte: Tablas como las de Excel

Espero les sea util esta funcion, lo que hace es crear una tabla HTML como esas q hacemos al crear una tabla dinamica en excel, a partir de una sentencia SQL la cual sera formateada y se calcularan los subtotales y totales de arriba a abajo... Bueno para que funciones solo hay que pasarle lo siguiente (disculpen soy algo malo explicando):



1.- Una sentencia SQL, la cual como dije antes sera formateada en la funcion, es importante que sea una consulta del tipo "group by" (nose si esta bien dicho)

$sql="select motivo, submotivo, count(if(month(`fechaaltacontacto`)=1, 1, null)) as Enero, count(if(month(`fechaaltacontacto`)=2, 1, null)) as Febrero, count(*) as `Total` from cn_contactos where year(fechaaltacontacto)=2009 group by motivo, submotivo";

esto nos daria un resultado como este

motivo-- | submotivo------ | Enero | Febrero | Total
----------------------------------------------------
Reclamos | 1era Instancia- | --124 | -----75 | --199
Reclamos | Reiteracion 1-- | ---64 | -----13 | ---77
Averias- | corte frecuente | ---21 | ------3 | ---24
Averias- | equipo malo---- | ----9 | -----11 | ---20


Es importante que nuestra sentencia este bien estructurada para que tengamos el resultado que queremos


2.- El numero de columnas principales, para el ejemplo serian 2, puesto que nuestro group by esta compuesto por 2 campos: motivo y submotivo

3.- Por ultimo la variable de conexion que estes usando. bueno no esta echo con adodb asi que no le pases una conexion de este tipo, sino la clasica "$cn=mysql_conect(....);"

He aqui el codigo:

Código PHP:
function formatea_valor($valor){
    if (
$valor>0){
        return 
$valor;
    }else{
        return 
" ";
    }
}

function 
generaTabla($cadSql$Columnas_Principales$Conexion){
    
$tabla="<table id=\"tbl\" class=\"tbl\" border=1>\r\n";
    
$tabla.="<tr>\r\n";
    
$result=mysql_query($cadSql,$Conexion);
    for (
$i=0;$i<mysql_num_fields($result);$i++){
        
$tabla.="<td class=\"td_head\">".mysql_field_name($result,$i)."</td>\r\n";
        
$nombre_fila[$i]="";
    }
    
$tabla.="</tr>\r\n";
    while (
$rs=mysql_fetch_array($result)){
        
        for (
$i=$Columnas_Principales-2;$i>-1$i--){
            if ((
$nombre_fila[$i]!=$rs[$i] && $nombre_fila[$i]!="") || ($nombre_fila[$i-1]!=$rs[$i-1] && $nombre_fila[$i-1]!="")){
                
$tabla.="<tr>\r\n";    
                for (
$j=0;$j<$i;$j++){
                    
$tabla.="<td class=\"td1\">&nbsp;</td>\r\n";
                }
                
$tabla.="<td colspan=\"".($Columnas_Principales-$i)."\" class=\"td".($Columnas_Principales-$i)."\">Total {$nombre_fila[$i]}</td>\r\n";
                for (
$j=$Columnas_Principales;$j<mysql_num_fields($result); $j++){
                    
$tabla.="<td class=\"td".($Columnas_Principales-$i)."\" align=\"center\">".formatea_valor($subtotal[$i][$j])."</td>\r\n";
                    
$subtotal[$i][$j]=0;
                }
                
$tabla.="</tr>\r\n";
            }

        }
        for (
$m=0$m<$Columnas_Principales-1$m++){
            for (
$n=$Columnas_Principales$n<mysql_num_fields($result); $n++){
                
$subtotal[$m][$n]+=$rs[$n];
                
$total[$n]+=$rs[$n];
            }
        }        
        for (
$n=$Columnas_Principales$n<mysql_num_fields($result); $n++){
            
$total[$n]+=$rs[$n];
        }
        
$tabla.="<tr>\r\n";
        for (
$a=0$a<$Columnas_Principales-1$a++){
            if (
$nombre_fila[$a]!=$rs[$a]){
                
$nombre_fila[$a]=$rs[$a];
                
$tabla.="<td class=\"td1\">{$rs[$a]}</td>\r\n";
                for (
$c=$a+1$c<$Columnas_Principales-1;$c++){
                    
$nombre_fila[$c]="";
                }
            }else{
                
$tabla.="<td class=\"td1\">&nbsp;</td>\r\n";
            } 
        } 
        
$tabla.="<td class=\"td1\">".$rs[$Columnas_Principales-1]."</td>\r\n";
        for (
$c=$Columnas_Principales;$c<mysql_num_fields($result); $c++){
            
$tabla.="<td class=\"td1\" align=\"center\">".formatea_valor($rs[$c])."</td>\r\n";
        } 
        
$tabla.="</tr>\r\n";        
    }
    for (
$i=$Columnas_Principales-2;$i>-1$i--){
        
$tabla.="<tr>\r\n";    
        for (
$j=0;$j<$i;$j++){
            
$tabla.="<td class=\"td1\">&nbsp;</td>\r\n";
        }
        
$tabla.="<td colspan=\"".($Columnas_Principales-$i)."\" class=\"td".($Columnas_Principales-$i)."\">Total {$nombre_fila[$i]}</td>\r\n";
        for (
$j=$Columnas_Principales;$j<mysql_num_fields($result); $j++){
            
$tabla.="<td class=\"td".($Columnas_Principales-$i)."\" align=\"center\">".formatea_valor($subtotal[$i][$j])."</td>\r\n";
            
$subtotal[$i][$j]=0;
        }
        
$tabla.="</tr>\r\n";
    }
    
$tabla.="<tr>\r\n";
    
$tabla.="<td colspan=\"".($Columnas_Principales)."\" class=\"td_foot\">Total General</td>\r\n";
    for (
$n=$Columnas_Principales$n<mysql_num_fields($result); $n++){
        
$tabla.="<td class=\"td_foot\" align=\"center\">".formatea_valor($total[$n])."</td>\r\n";
    }
    
$tabla.="</tr>\r\n";
    
$tabla.="</table>\r\n";
    return 
$tabla;

La llamada a la funcion se hace de la siguiente manera:
Código PHP:
$cn=mysql_connect("localhost","root","") or die (mysql_error());
mysql_select_db("tup") or die (mysql_error());

$sql="select desmotivo, dessubmotivo,
count(if(month(`fechaaltacontacto`)=1, 1, null)) as Enero,
count(if(month(`fechaaltacontacto`)=2, 1, null)) as Febrero, count(*) as `Total`
from cn_contactos where year(fechaaltacontacto)=2009
group by desmotivo, dessubmotivo"
;

echo 
generaTabla($sql,2,$cn); 
Cabe resaltar que tu sentencia SQL puede estar agrupada por n campos, solo no olvidar que esa misma cantidad es la que tienes que pasar como segundo parametro.

Sobre la estructura de la tabla, para que sea mas facil el manejo de estilos, cada etiqueta "<td>" tiene 1 clase asignada de acuerdo al nivel que se encuentren, por ejemplo, n el nivel mas bajo, tenemos a los datos de la ultima columna de nuestro group by, para el ejemplo de la imagen, los datos de la columna "desestado" tiene asignada la clase "td_1", el siguiente nivel "dessubmotivo" tiene asignada la clase "td_2", el siguiente nivel desmotivo tiene la clase "td_3", es decir se van a ir creando tantas clases como ColumnasPrincipales tenga la funcion. sobre la cabecera y el pie de tabla estos tienen asociados la clase "td_head" y "td_foot" respectivamente.



Saludos,
K-suma,
Cualquier duda que haya quedado estoy presto a despejarla

Última edición por K-SuMa; 28/02/2009 a las 10:05