Tutorials

Rapporten met subtotalen

Het maken van rapporten is niet mijn favoriete klusje. Maar helaas moet ik het veel doen en ben altijd op zoek naar manieren om het makkelijker te maken. De grote uitdaging is dan altijd om de programmatuur leesbaar en onderhoudbaar te houden.

Pagina 1

Inleiding

Bij het maken van rapporten met een of meerdere categorieƫn en subtotalen is het probleem altijd dat je bij het na de laatste rij de while loop uitgaat en dus geen subtotaal meer kan maken.
Je kunt dan achter de while loop natuurlijk de subtotaal code nog een keer herhalen, maar dat is lelijk programmeren en niet goed voor het onderhouden.

Als je dit probleem op internet zoekt, komt je niet veel goede oplossingen tegen. Eigenlijk vreemd voor iets dat veel voor lijkt te komen.
Ik heb uiteindelijk gekozen voor de methode om de gegevens eerst in een array te zetten en daarna pas te printen.

Er zijn vele manieren om dit op te lossen en ik moedig jullie graag aan om andere en/of betere oplossingen te posten.
Pagina 2

Gegevens

Ik hou van eenvoudige voorbeelden, dus neem ik de vertrouwde tabel met auto's.


CREATE TABLE `test` (
	`test_id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`test_merk` VARCHAR( 20 ) NOT NULL ,
	`test_type` VARCHAR( 20 ) NOT NULL ,
	`test_aantal` INT( 5 ) NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `test` (`test_id`, `test_merk`, `test_type`, `test_aantal`) 
	VALUES (NULL, 'Audi', 'A4', '3'), 
		(NULL, 'Audi', 'A6', '6'), 
		(NULL, 'Audi', 'A8', '1'), 
		(NULL, 'VW', 'Golf', '4'), 
		(NULL, 'VW', 'Polo', '3');

Pagina 3

Het rapport afdrukken

En dan nu de PHP code. Ik hoop dat de commentaren duidelijk genoeg zijn.


<?
// Ik heb een class util waar alle database acties afgehandeld worden.
// De naamgeving spreekt verder voor zich. 
$result = $util->query("SELECT * FROM test ORDER BY test_merk, test_type");
// Definiƫren van de gegevens array. 
$data = array();
// Bij het vullen de array wordt al rekening gehouden met de structuur van het rapport.
// In dit geval is er maar een subtotaal, maar als je nog een onderverdeling hebt, dan voeg je er een laag aan toe.
// Dus bijvoorbeeld:  $data[$rij["test_merk"]][$rij["test_type"]][$rij["test_id"]] = $rij;
while ($rij = $result->fetch_assoc()) {
	$data[$rij["test_merk"]][$rij["test_id"]] = $rij;
}

// Reset het totaal en druk de kop af.
$totaal = 0;
echo "<table border=\"1\">";
echo "<tr><th>Merk/Type</th><th>Aantal</th></tr>";
// Begin met de merken. In $val staat dus nu dit gedeelte: [$rij["test_id"]] = $rij;  
foreach ($data as $merk => $val) {
	// Het subtotaal moet bij elk merk worden gereset.
	$subtotaal = 0;
	// Hoewel het merk in dit geval in $merk staat, zul je in de praktijk vaak de 
	// gegevens uit de rij willen halen.
	// Je weet de index van $val niet, dus met current() haal je de eerste rij op uit val. 
	$rij = current($val);
	// Druk de kop met het merk af. 
	echo "<tr><th colspan=\"2\">{$rij["test_merk"]}</th></tr>";
	// Nu worden de details doorgelopen.
	foreach ($val as $test_id => $rij) {
		// Druk de detail regel af en tel het aantal bij het subtotaal.
		echo "<tr><td>{$rij["test_type"]}</td><td>{$rij["test_aantal"]}</td></tr>";
		$subtotaal += $rij["test_aantal"];
	}
	// Werk het totaal bij en druk het subtotaal af.
	$totaal += $subtotaal;
	echo "<tr><th>Subtotaal</th><th>$subtotaal</th></tr>";
}
// Tot slot wordt het totaal afgedrukt en de table afgesloten.
echo "<tr><th>Totaal</th><th>$totaal</th></tr>";
echo "</table>";

?>


Resultaat:

Reacties

0
Nog geen reacties.