Foros del Web » Programando para Internet » PHP »

Aporte: Tablas como las de Excel

Estas en el tema de Aporte: Tablas como las de Excel en el foro de PHP en Foros del Web. 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, ...
  #1 (permalink)  
Antiguo 24/02/2009, 22:02
 
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
  #2 (permalink)  
Antiguo 24/02/2009, 22:50
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Aporte: Tablas como las de Excel

un tip:

si el SQL siempre debe terminar con GROUP BY puedes omitir el segundo argumento, y hacerlo automatico....

Código PHP:
// obtenemos las columnas despues de GROUP BY (a,b,c,d,...)
preg_match('/GROUP\s+BY\s+(.*)$/i'$CadSQL$test);

// separamos por comas, y contamos los trozos...
$Columnas_Principales sizeof(explode(','$test[1])); 
tal ves.. es solo una idea, suerte!


__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 25/02/2009, 07:12
 
Fecha de Ingreso: diciembre-2007
Mensajes: 50
Antigüedad: 16 años, 4 meses
Puntos: 1
Respuesta: Aporte: Tablas como las de Excel

Doc, voy a probarlo y te comento... aunque el SQL podria tener un HAVING despues de la sentencia GROUP BY

Cita:
Iniciado por pateketrueke Ver Mensaje
un tip:

si el SQL siempre debe terminar con GROUP BY puedes omitir el segundo argumento, y hacerlo automatico....

Código PHP:
// obtenemos las columnas despues de GROUP BY (a,b,c,d,...)
preg_match('/GROUP\s+BY\s+(.*)$/i'$CadSQL$test);

// separamos por comas, y contamos los trozos...
$Columnas_Principales sizeof(explode(','$test[1])); 
tal ves.. es solo una idea, suerte!


Un saludo
K-Suma
  #4 (permalink)  
Antiguo 25/02/2009, 20:19
 
Fecha de Ingreso: diciembre-2007
Mensajes: 50
Antigüedad: 16 años, 4 meses
Puntos: 1
Respuesta: Aporte: Tablas como las de Excel

pateketrueke, he probado como me dijiste y sale error... aver si me das una mano.

Salu2,
K-SuMa
  #5 (permalink)  
Antiguo 26/02/2009, 02:15
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Aporte: Tablas como las de Excel

¿que error??

recuerda, mas ayuda el que informa... que el que tan solo pregunta!
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:28.