Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

PHP während einer while Schleife Zwischensumme bilden

Frage Entwicklung PHP

Mitglied: gechger

gechger (Level 1) - Jetzt verbinden

08.09.2009, aktualisiert 13:21 Uhr, 10144 Aufrufe, 13 Kommentare

Eine mysql Abfrage liefert mir verschiedene Benutzer mit verschiedenen Daten (hier explizit Zeiten). Wenn ein neuer Benutzer in der while Schleife erkannt wird, soll eine Zwischensumme seiner Zeiten ausgegeben werde. Wie stele ich das am geschicktesten an?

Hallo Forum,

eine Monatsabfrage einer Mysql Datenbank liefert mir nach Person sortiert eine Menge Daten, die ich in einer while Schleife ausgebe.

Sie sieht vereinfacht so aus:
MA1, 01.09.2009, 8 Stunden
MA1, 02.09.2009, 6,5 Stunden
MA2, 01.09.2009, 4 Stunden
MA2, 02,09,2009, 6,25 Stunden
MA3,...
MA3,...
MA4,...
MA4,...

usw.

Wenn in der while Schleife von MA1 auf MA2 gewechselt wird, sollen alle Zeiten des MA1 summiert in einer Zwischensumme ausgegeben werden. Am Ende sollen alle Zwischensummen als Gesamtssumme des ausgewählten Zeitraumes erscheinen.

Wie stelle ich das am geschicktesten an?

Vielen Dank für jede Idee
Schöne Grüße
Christof
Mitglied: Snowman25
08.09.2009 um 13:26 Uhr
wenn dir die Datenbank schon die Zeiten liefert, dann rechne doch auch mit Ihnen. Sobald du einen MA durch hast, lässt du dir nur die Stunden des MA ausgeben und rechnest die zusammen. Dabei behälst du immer das letzte Ergebnis, gibst es aus und rechnest es dann deiner Gesamtsumme zu. Die gibst du dann ganz am Ende aus. Du brauchst also 2 Schleifen.
Bitte warten ..
Mitglied: gechger
08.09.2009 um 13:57 Uhr
Hallo snowman,

mit dieser Selectabfrage

$select = "SELECT ztyp, zdat, zper, zpro, pzmember.nname, pzmember.vname from pzetool left JOIN pzmember on pzmember.rfid = pzetool.zper where (zpro = $fanr) and (zdat BETWEEN '$datumvon' AND '$datumbis') ORDER BY zper, zdat";

In dem zdat Feld bekomme ich Datum und Uhrzeit.
Durch ein Script ermittle ich eine von Zeit und eine bis Zeit, die ich gegeneiander aufrechnen kann.
Dieses wandle ich dann noch um.

01.
$zdatjahr=substr($zdatsav,0,4); 
02.
      $zdatmonat=substr($zdatsav,5,2); 
03.
      $zdattag=substr($zdatsav,8,2); 
04.
      $zdatstr="$zdattag"."."."$zdatmonat"."."."$zdatjahr"
05.
 
06.
      //Aufschlüsselung des gesamten Zeitwertes in die einzelnen Werte 
07.
      $jahrv=substr($strtimvsav,0,4); 
08.
      $monatv=substr($strtimvsav,5,2); 
09.
      $tagv=substr($strtimvsav,8,2); 
10.
      $stdv=substr($strtimvsav,11,2); 
11.
      $minv=substr($strtimvsav,14,2); 
12.
      $sekv=substr($strtimvsav,17,2); 
13.
 
14.
      $jahrb=substr($strtimbsav,0,4); 
15.
      $monatb=substr($strtimbsav,5,2); 
16.
      $tagb=substr($strtimbsav,8,2); 
17.
      $stdb=substr($strtimbsav,11,2); 
18.
      $minb=substr($strtimbsav,14,2); 
19.
      $sekb=substr($strtimbsav,17,2); 
20.
 
21.
      //Errechnung des UNIX-Timestamp Wertes 
22.
 
23.
      $zeitv=mktime($stdv,$minv,$sekv,$monatv,$tagv,$jahrv); 
24.
      $zeitb=mktime($stdb,$minb,$sekb,$monatb,$tagb,$jahrb); 
25.
      $unixzeit=$zeitb-$zeitv
26.
 
27.
      $unixzeit2=$strtimbsav-$strtimvsav
28.
 
29.
      $zeit=gmdate("H:i:s",$unixzeit);
In $zeit steht also nun die errechnete Anwesenheitszeit.

Die Select Abfrage kann mir bis zu 120 Mitarbeiter ausgeben, die alle mit Zwischensummen voneinander getrennt werden sollen.

Meine Idee geht in die Richtung:
zper=Personalnummer
zpertemp=temporäre Variable

Vor der while Schleife:
$zpertemp = "";

Durchlauf der Schleife:
01.
if ($zpertemp=0) 
02.
03.
$zpertemp=$zper;  
04.
$zeittemp=+$zeit; //Hier sollte solange der Name gleich ist, die Zeit bei jedem Durchlauf in eine temp Variable hinzugefügt werden 
05.
 
06.
07.
if ($zpertemp !=$zper
08.
$zwsumme=$zeittemp
09.
$zeittemp=0; //Wenn ein Wechsel erkannt ist, soll die aufgelaufene Summe weg geschrieben und ausgegeben werden, die temp Variable wird auf null zurückgesetzt 
10.
11.
 
Irgendwie so hatte ich das angedacht, aber geht das überhaupt?

Mit einer zweiten Schleife arbeiten scheint mir da wesentlich komplizierter zu sein.

Schöne Grüße
Christof
Bitte warten ..
Mitglied: Snowman25
08.09.2009 um 14:25 Uhr
nunja, ich dachte mir das so, dass du eine äussere schleife hast, die die MA's durchläuft und die Innere jeweils die einzelnen Einträge für den momentanen MA.
In der Inneren Schleife gibst du einfach die Einträge aus und am Ende jeder Ausgabe (bzw. innerem schleifendurchlauf) addierst du die MA Zeiten aufeinander ($zwsumme+=$zeittemp).
Sobald du einen MA durch hast, also am Fuß der äusseren Schleife bist, gibst du $zwsumme aus, rechnest $zwsumme dann zu $gesamtzeit hinzu und nullst $zwsumme dann wieder.
kurz:
01.
while  ... { //äussere Schleife 
02.
      $zper=<MA-Nummer>; 
03.
      for ($i = 1; $i <= <Anzahl Listeneinträge>; $i++) { //Innere Schleife 
04.
            Echo <Eintrag Nr. $i von $zper>;  //Ausgabe Listeneintrag 
05.
            $zeittemp=<Zeit von Eintrag $i von MA $zper>; 
06.
            $zwsumme+=$zeittemp
07.
08.
      Echo "$zwsumme"
09.
      $gesamtzeit+=$zwsumme
10.
      $zwsumme=0; 
11.
}
stark vereinfacht... aber das Prinzip sollte klar sein
hoffe das hilft

Snow
sollte mal wieder php üben...
Bitte warten ..
Mitglied: kopie0123
08.09.2009 um 14:33 Uhr
Ich würde die gesamte Rechnenlogik in Datenbankabfrage verlagern. Schau dir mal GROUP BY an, damit sollte man es auch lösen können.

Oder du lässt die erst alle MAs ausgeben und fragst dann alle Datensätze der jeweiligen MAs ab. Das sollte schneller sein, als das Schleifen-gemauschel

Gruß
Bitte warten ..
Mitglied: godlie
08.09.2009 um 16:58 Uhr
Hallo,

naja ich würd mir das ganze recht elegant basteln.
Nachdem in $zper die personalnummer drinne ist und dich ja eigentlich nur die Gesamtsumme interessiert,
würde ich das so angehen:
01.
$stunden = array(); 
02.
while(  mysql_fetch.... ) { 
03.
 
04.
if(array_key_exists($zper, $stunden)) 
05.
$stunden[$zper] = $stunden[$zper]+$zeit; 
06.
else 
07.
$stunden[$zper] = $zeit; 
08.
}
das wäre so meien Idee grob umrissen. Ich glaub du wirst da noch ein paar Umwandlungen brauchen aber sonst dürft das so funktionieren wie ich das Verstanden habe.

@StingerMac
Ich glaube das mit dem Berechnungen in der DB wird nciht hinhauen wenn ers so zerlegen muss.
Bitte warten ..
Mitglied: nxclass
09.09.2009 um 09:02 Uhr
wow! - also das Datum kannst du Dir auch gleich in der SQL Abfrage umwandeln.
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

01.
SELECT 
02.
  ... 
03.
SEC_TO_TIME( MAX(UNIX_TIMESTAMP(zdat)) - MIN(UNIX_TIMESTAMP(zdat)) ) AS 'zeit' 
04.
// ggf geht auch: SEC_TO_TIME( UNIX_TIMESTAMP(MAX(zdat)) - MIN(zdat)) ) AS 'zeit' 
05.
  ... 
06.
GROUP BY 
07.
   DATE( zdat )
..hoffe ich habe das so richtig verstanden wie die Zeiten gespeichert werden !?

Zwischensummen:
Man könnte eine Temporäre MYSQL Tabelle erstellen, diese mit den einzelnen Einträgen (s.o.) füllen und anschließend noch mit den Zwischensummen - oder auch gleich eine UNION Abfrage generieren.
Bitte warten ..
Mitglied: gechger
09.09.2009 um 22:51 Uhr
Hallo an Alle,

es ist ja Wahnsinn, welche Lösungsansätze man wählen kann.

Erstmal @nxclass:
Die User nutzen ein Zeiterfassungsgerät, welches die Zeiten per GSM an die MySQl Datenbank sendet. Morgens einstempeln ergibt einen Datensatz, abends ausstempeln einen weiteren. Ich habe in der DB dann stehen:
Personalnummer 1234, Anmeldung 07:15
Personalnummer 5688, Anmeldung 07:30
usw
Personalnummer 1234, Abmeldung 16:15
Personalnummer 5688, Abmeldung 16:30
usw

Um die Zeiten eines Users berechnen zu können, erfolgt das order by Kriterium nach Personalnummer und Zeit, also zper und zdat.
In einer SQl Abfrage müßte ich dann doch erst die praktisch unsortierten Datensätze ersteinmal vorsortieren, damit die Berechnung 'bis-Zeit' - 'von-Zeit' zu dem richtigen User erfolgt. Ich denke, daß es einfacher ist, die vorsortierten Datensätze in php weiter zu verarbeiten.
Außerdem besteht mein SQL Datensatz in der Form: DD.MM.YYYY HH:MM:SS.
Das Datum muß ich erst ausfiltern, um es in einem Formular verwenden zu können, das erlaubt, den gewünschten Zeitraum von-bis auszuwählen. Die Zeiten benötige ich, um die Arbeitszeit des Tages zu errechnen, und anschließend die Zwischensumme zu bilden über den ausgewählten Zeitraum. Deshalb die aufwendige substr Struktur.


@godlie
Dein Ansatz scheint mir irgendwie erfolgversprechend. Ich habe es zwar noch nicht ganz durchschaut, aber das probiere ich mal aus. Ich habe zwischenzeitlich auchschon was probiert, was halbwegs funktioniert, aber eben nicht so ganz richtig.
Ich habe mit einer Tempvariablen gearbeitet. Vor der Schleife definiere ich diese als leer.
Dann kommt die Schleife, wobei ich prüfe:
01.
        $unixzeit=$zeitb-$zeitv
02.
        $zeit=gmdate("H:i:s",$unixzeit); 
03.
 
04.
        $zwsummead+=$unixzeit
05.
        if (empty($zpertemp)) 
06.
07.
           $zpertemp=$zper
08.
09.
 
10.
        if ($zpertemp==$zpersav
11.
12.
           $zpertemp=$zper
13.
14.
 
15.
        if ($zpertemp != $zpersav
16.
17.
           $zwsumme=$zwsummead
18.
           $zwsummead=""
19.
           $zpertemp=$zper
20.
           continue
21.
22.
 
23.
           include"ausgabedat.php"
24.
         }
Die Zwischensumme wird mir korrekt ausgegeben, aber sie steht nicht unter dem User, sondern immer eine Zeile weiter, nämlich erst dann, wenn $zpertemp != $zpersav erkannt wurde. Der erste Datensatz des neuen Users wird ausgegeben, dann kommt die Zwischensumme. Ich denke, mit Deinem Ansatz komme ich weiter.

@Snowman
Dein Hinweis auf die Möglichkeit += zu verwenden, hat mich bereits einen Riesenschritt weiter gebracht. Da mich mein eigener Ansatz noch nicht weiter gebracht hat, werde ich auch die gestaffelte Schleife mal durch testen.

Ergebnisse werde ich kurzfristig nicht haben, da mich meine normalen Supportaufgaben wieder bundesweit auf deutsche Autobahnen führen werden, und ich keine Zeit habe, mich sofort an mein php Script zu stürzen. Aber sobald wieder etwas Luft ist.......

Euch allen erstmal herzlichen Dank für alle Ansätze.

Schöne Grüße
Christof
Bitte warten ..
Mitglied: Guenni
14.09.2009 um 16:10 Uhr
Hi Christof,

diese Strategie . . .

Zitat von gechger:
. . . Morgens einstempeln ergibt einen Datensatz,

abends ausstempeln einen weiteren. . . .


. . . würde ich mal überdenken. Wenn du Einfluß darauf hast, würde ich

Ein- und Ausstempeln in einen Datensatz packen/packen lassen.


Dann ist das Summieren von Zeiten ohne if und else und temporären Variablen

in ein paar Zeilen erledigt.


Dein Code, um Datum und Zeit(en) aus dem Feld zdat zu filtern, ist auch nicht

notwendig, da MySQL Funktionen bereitstellt, die mit dem Datentyp datetime umgehen können:

- DATE_FORMAT(Spaltenname,"%Y-%m-%d") oder DATE_FORMAT(Spaltenname,"%d.%m.%Y") - Datum

- TIME_TO_SEC(Spaltenname) - Uhrzeit in Sekunden


01.
 
02.
$query_sum = 'select id,sum((time_to_sec(ende)-time_to_sec(beginn))/60/60) as ZwiSum' 
03.
            . ' from tabelle2 join zeiten on tabelle2.id=zeiten.u_id' 
04.
	    . ' where datum between "'.$vonTag.'" and "'.$bisTag.'"' 
05.
	    . ' group by id'
06.
 
07.
$result_sum = mysql_query($query_sum); 
08.
 

So hättest du alle Stunden/MA in ZwiSum abgelegt(Datum hab ich bei mir in einer sep. Spalte).

Jetzt wird das Ergebnis ausgewertet:

01.
 
02.
while($row_sum = mysql_fetch_array($result_sum,MYSQL_ASSOC)){ 
03.
  
04.
 $id=$row_sum['id']; 
05.
 
06.
 /* 
07.
 Innerhalb dieser Schleife erfolgt eine Abfrage der Zeiten nach id, gruppiert wird wie oben 
08.
 
09.
 nach id, zusätzlich noch nach Datum.   
10.
 */ 
11.
 
12.
 $sql = 'SELECT id,z_id,vorname,nachname,datum,beginn,ende,sum((time_to_sec(ende)-time_to_sec(beginn))/60/60) as summe from zeiten' 
13.
        . ' join tabelle2 on tabelle2.id=zeiten.u_id' 
14.
	. ' where datum between "'.$vonTag.'" and "'.$bisTag.'"' 
15.
	. ' and id = "'.$id.'"' 
16.
	. ' group by id,datum'
17.
 
18.
 $result = mysql_query($sql); 
19.
 
20.
 while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
21.
    
22.
  //Alle Stunden zusammenaddieren 
23.
   
24.
  $gesamtsumme+=$row['summe']; 
25.
   
26.
  //MA + Datum + Beginn/Ende + Std/Tag ausgeben 
27.
	 
28.
  echo implode(" | ",$row)."<br>"
29.
  
30.
 }// while2 Ende 
31.
  
32.
 /* 
33.
 Nach Ausgabe der einzelnen Tage die Zwischensummme Std/MA ausgeben, 
34.
  
35.
 die in der ersten Abfrage ermittelt wurde 
36.
 */ 
37.
  
38.
 echo "Zwischensumme/MA: $row_sum[ZwiSum]<br><br>"
39.
 
40.
}// while1 Ende 
41.
 
42.
//Zum Schluß Gesamtstunden aller MA ausgeben 
43.
 
44.
echo $gesamtsumme
45.
 

Gruß
Günni
Bitte warten ..
Mitglied: gechger
14.09.2009 um 22:00 Uhr
Grüß Dich Günni,

die Datensätze können leider nicht direkt zusammengefasst werden. Die elektronischen Geräte, die verwendet werden, senden die Datensätze unmittelbar nach deren Erfassung in eine Mysql Datenbank. Das Zusammenfassen habe ich bereits gelöst.

Durch die order by Ausgabe nach Personalnummer und Zeit bekomme ich die Daten in der richtigen Reihenfolge ausgegeben.
Der "Start" Satz wird in einer temporären Variablen zwischen gespeichert und erst ausgegeben, wenn der passende "Ende" Satz auch vorhanden ist. Die Ausgabe erfolgt dann in der Form:

Datum, Mitarbeiter, Zeit von, Zeit bis, Differenz Zeit bis minus Zeit von.
Das funktioniert bereits sehr gut. Zwischensummen bekomme ich dank der Hilfe des Forums auch schon, nur nicht an der Stelle, wo ich sie ausgegeben haben möchte.

Zur Veranschauchlichung der bisherige Code im Teststadium:
01.
<? 
02.
//Festlegen der Temporären Variablen 
03.
$ztypsav=""
04.
$zdatsav=""
05.
$zstpsav=""
06.
$ztivsav=""
07.
$ztibsav=""
08.
$zpersav=""
09.
$zprosav=""
10.
$nnamesav=""
11.
$vnamesav=""
12.
$lasttyp=""
13.
$lastper=""
14.
$laststp=""
15.
$strtimvsav=""
16.
$strtimbsav=""
17.
$zpertemp=""
18.
$zwsummead=""
19.
$zwsumme=""
20.
$p=""
21.
$p2=""
22.
$zahl=""
23.
 
24.
if (isset($_POST["submit"])) 
25.
26.
 
27.
   @$datumvon=$_POST["jahrvon"]."-".$_POST["monatvon"]."-".$_POST["tagvon"]." "."00:00:00"
28.
   @$datumbis=$_POST["jahrbis"]."-".$_POST["monatbis"]."-".$_POST["tagbis"]." "."23:59:59"
29.
   @$namecheck=$_POST["nachname"]; 
30.
 
31.
   $cldb = mysql_connect($_SESSION['host'], $_SESSION['dbuser'], $_SESSION['passwort']) or die(mysql_error()); 
32.
   mysql_select_db($_SESSION['db']); 
33.
 
34.
   $select = "SELECT ztyp, zdat, zper, zpro, pzmember.nname, pzmember.vname  from pzetool left JOIN pzmember on pzmember.rfid = pzetool.zper where (zpro = $fanr) and (zdat BETWEEN '$datumvon' AND '$datumbis') ORDER BY zper, zdat"
35.
   $result=mysql_query($select); 
36.
   echo mysql_error(); 
37.
 
38.
 
39.
// Erstellung einer Datei mit den Werten des Arrays 
40.
   $anmeldedat=$_SESSION['logindat']; 
41.
   $daten=$anmeldedat.".csv"
42.
   $datei=fopen($daten,"w"); 
43.
   $_SESSION['dateiname']=$daten
44.
 
45.
 
46.
 
47.
   $i=0; 
48.
   //$stunden = array(); 
49.
 
50.
   while($ausgabe = mysql_fetch_row($result))  //Array der Abfrage in Variablen speichern 
51.
52.
 
53.
      $ztyp=$ausgabe[0]; 
54.
      $zstp=$ausgabe[1]; 
55.
      $zdat=substr($zstp,0,10); 
56.
      $ztim=substr($zstp,11,8); 
57.
      $zper=$ausgabe[2]; 
58.
      $zpro=$ausgabe[3]; 
59.
      $nname=$ausgabe[4]; 
60.
      $vname=$ausgabe[5]; 
61.
 
62.
 
63.
 
64.
 
65.
//Prüfung, ob temporäre Variablen gefüllt sind: Datum, Personalnummer und Typ. Wenn ja, wird Schleife abgebrochen 
66.
      if (($zstp==$laststp) && ($zper==$lastper) && ($ztyp==$lasttyp)) 
67.
68.
         continue
69.
70.
// Wenn TempVAR Typ leer ist: Ausgabe nein, Füllen der TempVAR ja. 
71.
      if (empty($ztypsav)) 
72.
73.
         $liste="0"
74.
         $kopieren="1"
75.
76.
//Wenn TempVAR Typ gefüllt ist, wird ausgegeben und weiter geprüft. 
77.
      else 
78.
79.
         $liste="1"
80.
//Erste Prüfung auf Typ: es steht ST drin 
81.
         if ($ztypsav=="ST"
82.
83.
//Zweite Prüfung auf Typ: es steht EN drin 
84.
            if ($ztyp=="EN"
85.
86.
//Wenn EN drin steht, wird dir TemVAR Zeit bis mit der ermittelten Uhrzeit gefüllt, aber nicht weg geschrieben 
87.
               $ztibsav=$ztim
88.
               $strtimbsav=$zstp
89.
               $kopieren="0"
90.
91.
//Wenn ST drin steht, wird die TempVAR gefüllt 
92.
            else 
93.
94.
               $kopieren="1"
95.
96.
97.
//Wenn TempVAR Typ mit EN gefüllt ist, und kein ST vorliegt,wird die von Zeit mit 00:00:00 gefüllt und weg geschrieben 
98.
         else 
99.
100.
            $ztivsav="00:00:00"
101.
            $kopieren="1"
102.
103.
104.
//Wenn Liste schreiben aktiviert ist, wird die ausgabedat aufgerufen und ausgeführt 
105.
      if ($liste=="1"
106.
107.
         $i++; 
108.
         if ((empty($vnamesav)) && (empty($nnamesav))) 
109.
110.
         $nnamesav=$zper
111.
112.
 
113.
        //Umwandlung des vorgegebenen Formates in deutschen Standard 
114.
        $zdatjahr=substr($zdatsav,0,4); 
115.
        $zdatmonat=substr($zdatsav,5,2); 
116.
        $zdattag=substr($zdatsav,8,2); 
117.
        $zdatstr="$zdattag"."."."$zdatmonat"."."."$zdatjahr"
118.
 
119.
        //Aufschlüsselung des gesamten Zeitwertes in die einzelnen Werte 
120.
        $jahrv=substr($strtimvsav,0,4); 
121.
        $monatv=substr($strtimvsav,5,2); 
122.
        $tagv=substr($strtimvsav,8,2); 
123.
        $stdv=substr($strtimvsav,11,2); 
124.
        $minv=substr($strtimvsav,14,2); 
125.
        $sekv=substr($strtimvsav,17,2); 
126.
 
127.
        $jahrb=substr($strtimbsav,0,4); 
128.
        $monatb=substr($strtimbsav,5,2); 
129.
        $tagb=substr($strtimbsav,8,2); 
130.
        $stdb=substr($strtimbsav,11,2); 
131.
        $minb=substr($strtimbsav,14,2); 
132.
        $sekb=substr($strtimbsav,17,2); 
133.
 
134.
        //Errechnung des UNIX-Timestamp Wertes 
135.
 
136.
        $zeitv=mktime($stdv,$minv,$sekv,$monatv,$tagv,$jahrv); 
137.
        $zeitb=mktime($stdb,$minb,$sekb,$monatb,$tagb,$jahrb); 
138.
        $unixzeit=$zeitb-$zeitv
139.
        $unixzeit2=$strtimbsav-$strtimvsav
140.
        $zeit=gmdate("H:i:s",$unixzeit); 
141.
 
142.
//Beginn der Zwischensumme 
143.
 
144.
        if (empty($zpertemp)) 
145.
146.
           $zpertemp=$zper
147.
148.
 
149.
        if ($zpertemp==$zper
150.
151.
           $zwsummead+=$unixzeit
152.
           $p2++; 
153.
           //echo "P2=$p2","<br>"
154.
155.
        if ($p != $p2
156.
157.
           	$zwsumme=$zwsummead
158.
            //$_SESSION['zwsum']=$zwsumme
159.
160.
 
161.
        if ($zpertemp != $lastper
162.
163.
           $zwsummead=""
164.
           $zpertemp=""
165.
           $zwsumme=""
166.
           $p=""
167.
           $p2=""
168.
169.
 
170.
        include"ausgabedat.php"
171.
 
172.
173.
//Wenn kopieren auf Null steht, werden die TempVars gelöscht 
174.
         if ($kopieren=="0"
175.
176.
            $ztypsav=""
177.
            $zdatsav=""
178.
            $zstpsav=""
179.
            $ztivsav=""
180.
            $ztibsav=""
181.
            $zpersav=""
182.
            $zprosav=""
183.
            $nnamesav=""
184.
            $vnamesav=""
185.
            $zstpstrv=""
186.
            $zstpstrb=""
187.
 
188.
189.
//Ansonsten werden sie gefüllt 
190.
         else 
191.
192.
            $ztypsav=$ztyp
193.
            $zdatsav=$zdat
194.
            $zstpsav=$zstp
195.
            $zpersav=$zper
196.
            $zprosav=$zpro
197.
            $nnamesav=$nname
198.
            $vnamesav=$vname
199.
 
200.
 
201.
 
202.
//Wenn der Typ ST lautet, wird die von-Zeit mit der ermittelten Zeit gefüllt, die bis-Zeit wird überschrieben 
203.
            if ($ztyp=="ST"
204.
205.
               $ztivsav=$ztim
206.
               $ztibsav=""
207.
               $strtimvsav=$zstp
208.
209.
//Bei EN wird die von-Zeit gelöscht uns die bis-Zeit gefüllt 
210.
            else 
211.
212.
               $ztivsav=""
213.
               $ztibsav=$ztim
214.
               $strtimbsav=$zstp
215.
216.
               $p++; 
217.
		         //echo "P=$p","<br>"
218.
219.
//Speichern des letzten Datensatzes 
220.
         $lasttyp=$ztyp
221.
         $lastper=$zper
222.
         $laststp=$zstp
223.
 
224.
      }
Die VAriablen $p und $p2 sollen mir hoffentlich die Unterscheidung liefern, die ich brauche, um die Zwischensumme sauber zu plazieren. Aber da muß ich noch dran arbeiten.
Außerdem ist der Code noch nicht aufgeräumt. Einige Deklarationen sind noch von vorherigen Tests drin. Ist halt noch eine Beta Version.

Vielen Dank für Deinen Vorschlag.
Bisher habe ich ja viele Deiner Vorschläge erfolgreichumsetzen können.

Schöne Grüße
Christof
Bitte warten ..
Mitglied: Guenni
21.09.2009 um 14:25 Uhr
Hi Christof,


Zitat von gechger:
. . . die Datensätze können leider nicht direkt zusammengefasst werden. . . .

Das ist natürlich Pech, wenn die Stempeluhrsoftware das nicht kann. Dein Code zum

Ermitteln von Daten und Zeiten, Zuordnen von Zwischensummen zu ID's mit den endlosen

Variablen, if/else-Konstrukten sowie den substr-Operationen ist mir ehrlich gesagt

ein bißchen zu verworren, will sagen: schwer lesbar.


Ich ziehe es vor, die Daten und Zeiten gleich bei der Abfrage mit Hilfe von MySQL-Funktionen

zu ermitteln. Die MA-ID, das Datum und die Ein/Ausstempelzeit habe ich durch zwei

Abfragen/Schleifen in einem Array als Arrays gespeichert.


Erste Abfrage mit Einstempelzeit:

01.
<?php 
02.
/* 
03.
Aus dem Feld zeit(Datentyp datetime) wird das Datum extrahiert sowie die Uhrzeit in Sekunden. 
04.
Die Funktion min ermittelt den kleineren Zeitwert als Beginn 
05.
*/ 
06.
$query='select u_id,date_format(zeit,"%d.%m.%Y") as Datum,min(time_to_sec(zeit)) as Beginn' 
07.
						 .' from zeiten2 where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
08.
						 .' group by u_id,Datum'
09.
$result=mysql_query($query); 
10.
/* 
11.
Die Ergebnisse werden als Arrays in einem Array abgelegt. Der Endzeitwert wird in den Arrays auf Null 
12.
gesetzt, er wird in einer weiteren Abfrage ermittelt. 
13.
*/ 
14.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
15.
 $zeiten[] = array("ID" => $row['u_id'],"Datum" => $row['Datum'],"Beginn" => $row['Beginn'],"Ende" => 0); 
16.
17.
?>
Zweite Abfrage mit Ausstempelzeit:

01.
<?php 
02.
/* 
03.
Die Abfrage wird erneut abgesetzt, diesmal wird der größere Zeitwert in Sekunden durch die Funktion max 
04.
als Ende extrahiert. 
05.
*/ 
06.
$query='select u_id,date_format(zeit,"%d.%m.%Y") as Datum,max(time_to_sec(zeit)) as Ende' 
07.
						 .' from zeiten2 where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
08.
						 .' group by u_id,Datum'
09.
$result=mysql_query($query); 
10.
/* 
11.
Der Index 'Ende' der Arrays kann nun gesetzt werden. 
12.
*/ 
13.
$i=0; 
14.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
15.
 $zeiten[$i][Ende] = $row['Ende']; 
16.
 $i++; 
17.
18.
?>
In dem Array $zeiten befinden sich nun Arrays, die folg. enthalten:

ID der MA, Arbeitstag, Einstempel-/Ausstempelzeit

Errechnen und Ausgabe der Stunden/MA, Ausgabe der Zwischensummen und der Gesamtstunden erfolgt nach dem

nächsten Zitat


Zitat von gechger:
. . . Zwischensummen bekomme ich dank der Hilfe des Forums auch schon,
nur nicht an der Stelle, wo ich sie ausgegeben haben möchte. . . .


Ich vermute mal, du setzt eine Abfrage ab, und willst durch entspr. if/else/then-Kontrollen prüfen, wann

der Wechsel von einer ID zur nächsten ID erfolgt um dann die Zwischensumme auszugeben. Erstens glaube ich nicht,

das das geht, und wenn, dann nur mit erheblichem Aufwand. Da ist es erheblich einfacher, zwei Schleifen zu programmieren,

so wie es Snowman schon geschrieben hat, bzw. wie es in meinem Beispiel steht:

Eine Schleife, die dir das Kriterium liefert, nach dem eine Zusammenfassung erfolgen soll, innerhalb dieser Schleife eine weitere,

die die Zusammenfassung vornimmt. Wenn dann die "innere" Schleife die Zusammenfassung erledigt hat, wird sie beendet und die

Zusammenfassung wird NACH dem Beenden der inneren Schleife ausgegeben. Kurz ausgedrückt:

Die "äußere" Schleife liefert dir einen Wert(z.B. eine ID), die "innere" Schleife findet nur Werte, die zu der ID passen,

die dir die "äußere" Schleife liefert.

Die "innere" Schleife hab ich ja oben schon abgekaspert(Eigentlich waren es ja zwei Schleifen, wegen doppelter Datensätze), und

hab mir daraus ein Array erstellt, mit Arrays, die Werte zu versch. MA haben. Die ID's der MA sind auch in den Arrays vorhanden.

Die Werte der Arrays in diesem Array kann ich nun z.B. mit einer foreach-Schleife abrufen. Jetzt will ich aber, dass mir diese

foreach-Schleife nacheinander nur Werte zusammenfasst, die zu einem bestimmten Wert(einer ID) gehören. Diesen Wert(ID) liefert mir

eine Schleife, in der ich die ID's der MA abrufe:

01.
<?php 
02.
/* 
03.
Aus der Tabelle der MA werden die ID's abgefragt, die auch in der Tabelle 
04.
Zeiterfassung sind.  
05.
*/ 
06.
$query='select id from tabelle2' 
07.
			.' join zeiten2 on tabelle2.id=zeiten2.u_id' 
08.
			.' where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
09.
			.' group by id'
10.
$result=mysql_query($query); 
11.
?> 
12.
 
13.
<code type="php"
14.
<?php 
15.
/* 
16.
Jetzt werden die zwei Schleifen verschachtelt: 
17.
*/ 
18.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
19.
 foreach($zeiten as $zeit){ 
20.
  if($zeit[ID]==$row['id']){ 
21.
	 $std=(($zeit[Ende]-$zeit[Beginn])/60/60); 
22.
	 /* 
23.
	 Die ID/MA, die Stunden MA/Tag werden ausgegeben 
24.
	 */ 
25.
	 echo $zeit[ID]."-".$zeit[Datum]."-".$std." Std<br>"
26.
	 /* 
27.
	  Stunden der MA summieren 
28.
	 */ 
29.
	 $zwisum+=$std
30.
	 /* 
31.
	  Alle Stunden summieren 
32.
	 */ 
33.
	 $gesamtsumme+=$std
34.
  }  
35.
36.
 /* 
37.
 Summe Stunden/Tage/MA ausgeben, Var. $zwisum auf Null setzen 
38.
 **nach** Beenden der "inneren" Schleife 
39.
 */ 
40.
 echo "Zwischensumme MA/$row[id]: $zwisum Std<br><br>"
41.
 $zwisum=0; 
42.
43.
?>
Und wenn die "äußere" Schleife endet, wird die Summe aller Stunden ausgegeben.

01.
<?php 
02.
echo $gesamtsumme
03.
?>

Das Script:


01.
<?php 
02.
 
03.
/*********************************************** Script Zeitauswertung *************************************************
04.
/* 
05.
Datumsbereich 
06.
*/ 
07.
$vonTag="2009-09-01"
08.
$bisTag="2009-09-30"
09.
/* 
10.
Gesamtstunden 
11.
*/ 
12.
$gesamtsumme=0; 
13.
/* 
14.
Zwischensummen 
15.
*/ 
16.
$zwisum=0; 
17.
/* 
18.
Aus dem Feld zeit(Datentyp datetime) wird das Datum extrahiert sowie die Uhrzeit in Sekunden. 
19.
Die Funktion min ermittelt den kleineren Zeitwert als Beginn 
20.
*/ 
21.
$query='select u_id,date_format(zeit,"%d.%m.%Y") as Datum,min(time_to_sec(zeit)) as Beginn' 
22.
						 .' from zeiten2 where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
23.
						 .' group by u_id,Datum'
24.
$result=mysql_query($query); 
25.
/* 
26.
Die Ergebnisse werden als Arrays in einem Array abgelegt. Der Endzeitwert wird in den Arrays auf Null 
27.
gesetzt, er wird in einer weiteren Abfrage ermittelt. 
28.
*/ 
29.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
30.
 $zeiten[] = array("ID" => $row['u_id'],"Datum" => $row['Datum'],"Beginn" => $row['Beginn'],"Ende" => 0); 
31.
32.
/* 
33.
Die Abfrage wird erneut abgesetzt, diesmal wird der größere Zeitwert in Sekunden durch die Funktion max 
34.
als Ende extrahiert. 
35.
*/ 
36.
$query='select u_id,date_format(zeit,"%d.%m.%Y") as Datum,max(time_to_sec(zeit)) as Ende' 
37.
						 .' from zeiten2 where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
38.
						 .' group by u_id,Datum'
39.
$result=mysql_query($query); 
40.
/* 
41.
Der Index 'Ende' der Arrays kann nun gesetzt werden. 
42.
*/ 
43.
$i=0; 
44.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
45.
 $zeiten[$i][Ende] = $row['Ende']; 
46.
 $i++; 
47.
48.
/* 
49.
Aus der Tabelle der MA werden die ID's abgefragt, die auch in der Tabelle 
50.
Zeiterfassung sind.  
51.
*/ 
52.
$query='select id from tabelle2' 
53.
			.' join zeiten2 on tabelle2.id=zeiten2.u_id' 
54.
			.' where date_format(zeit,"%Y-%m-%d") between "'.$vonTag.'" and "'.$bisTag.'"' 
55.
			.' group by id'
56.
$result=mysql_query($query); 
57.
/* 
58.
Ausgabe des Erfassungszeitraums. 
59.
In der foreach-Schleife werden die ID's in den Arrays mit den ID's aus der letzten 
60.
Abfrage verglichen. Bei Übereinstimmung werden 
61.
- die Arbeitsstunden pro Tag berechnet($std
62.
- die Stunden/MA summiert($zwisum
63.
- Stunden aller MA summiert($gesamtsumme
64.
ausgegeben. 
65.
*/ 
66.
echo "Zeiterfassung vom $vonTag bis zum $bisTag<br><br>"
67.
while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ 
68.
 foreach($zeiten as $zeit){ 
69.
  if($zeit[ID]==$row['id']){ 
70.
	 $std=(($zeit[Ende]-$zeit[Beginn])/60/60); 
71.
	 /* 
72.
	 Die ID/MA, die Stunden MA/Tag werden ausgegeben 
73.
	 */ 
74.
	 echo $zeit[ID]."-".$zeit[Datum]."-".$std." Std<br>"
75.
	 $zwisum+=$std
76.
	 $gesamtsumme+=$std
77.
  }  
78.
79.
 /* 
80.
 Summe Stunden/Tage/MA ausgeben, Var. $zwisum auf Null setzen 
81.
 */ 
82.
 echo "Zwischensumme MA/$row[id]: $zwisum Std<br><br>"
83.
 $zwisum=0; 
84.
85.
/* 
86.
Ausgabe Stunden/Aller MA 
87.
*/ 
88.
echo "Stunden aller MA: $gesamtsumme Std<br>"
89.
/*********************************************** Script Zeitauswertung Ende *********************************************
90.
?>

Gruß
Günni
Bitte warten ..
Mitglied: gechger
22.09.2009 um 20:19 Uhr
Hallo Günni,

Du hast Dir ja wieder mal richtig Mühe gegeben. Dafür erstmal vielen Dank.

Du hast auch zuerst mal Recht:

Ermitteln von Daten und Zeiten, Zuordnen von Zwischensummen zu
ID's mit den endlosen

Variablen, if/else-Konstrukten sowie den substr-Operationen ist mir
ehrlich gesagt

ein bißchen zu verworren, will sagen: schwer lesbar.


Leider kann ich auf einen großen Teil der Abfragen nicht verzichten. Zum besseren Verständnis:

Der Mitarbeiter (MA) hält morgens seinen RFID Transponder Chip vor das Gerät und wird angemeldet. In der Datenbank wird dieser Datensatz mit ST für Start registriert. Hält er abends seinen Chip wieder davor, dann wird er abgemeldet, ein Endesatz (EN) wird gespeichert.
Nun kann er das EN aber vergessen. Dann folgt am nächsten Tag das EN, gefolgt von einem ST. Da die Datensätze sofort per GPRS versendet werden, muß ich einige Abfragen durchführen. ST alleine wird nicht ausgegeben, sondern erst, wenn der zugehörige EN-Satz kommt.
Dieser gesamte TEil steuert die verschiedenen Möglichkeiten:
01.
//Prüfung, ob temporäre Variablen gefüllt sind: Datum, Personalnummer und Typ. Wenn ja, wird Schleife abgebrochen 
02.
      if (($zstp==$laststp) && ($zper==$lastper) && ($ztyp==$lasttyp)) 
03.
04.
         continue
05.
06.
// Wenn TempVAR Typ leer ist: Ausgabe nein, Füllen der TempVAR ja. 
07.
      if (empty($ztypsav)) 
08.
09.
         $liste="0"
10.
         $kopieren="1"
11.
12.
//Wenn TempVAR Typ gefüllt ist, wird ausgegeben und weiter geprüft. 
13.
      else 
14.
15.
         $liste="1"
16.
//Erste Prüfung auf Typ: es steht ST drin 
17.
         if ($ztypsav=="ST"
18.
19.
//Zweite Prüfung auf Typ: es steht EN drin 
20.
            if ($ztyp=="EN"
21.
22.
//Wenn EN drin steht, wird dir TemVAR Zeit bis mit der ermittelten Uhrzeit gefüllt, aber nicht weg geschrieben 
23.
               $ztibsav=$ztim
24.
               $strtimbsav=$zstp
25.
               $kopieren="0"
26.
27.
//Wenn ST drin steht, wird die TempVAR gefüllt 
28.
            else 
29.
30.
               $kopieren="1"
31.
32.
33.
//Wenn TempVAR Typ mit EN gefüllt ist, und kein ST vorliegt,wird die von Zeit mit 00:00:00 gefüllt und weg geschrieben 
34.
         else 
35.
36.
            $ztivsav="00:00:00"
37.
            $kopieren="1"
38.
39.
40.
//Wenn Liste schreiben aktiviert ist, wird die ausgabedat aufgerufen und ausgeführt 
41.
      if ($liste=="1"
42.
43.
         $i++; 
44.
         include"ausgabedat.php"
45.
46.
//Wenn kopieren auf Null steht, werden die TempVars gelöscht 
47.
         if ($kopieren=="0"
48.
49.
            $ztypsav=""
50.
            $zdatsav=""
51.
            $zstpsav=""
52.
            $ztivsav=""
53.
            $ztibsav=""
54.
            $zpersav=""
55.
            $zprosav=""
56.
            $nnamesav=""
57.
            $vnamesav=""
58.
            $zstpstrv=""
59.
            $zstpstrb=""
60.
61.
//Ansonsten werden sie gefüllt 
62.
         else 
63.
64.
            $ztypsav=$ztyp
65.
            $zdatsav=$zdat
66.
            $zstpsav=$zstp
67.
            $zpersav=$zper
68.
            $zprosav=$zpro
69.
            $nnamesav=$nname
70.
            $vnamesav=$vname
71.
 
72.
 
73.
//Wenn der Typ ST lautet, wird die von-Zeit mit der ermittelten Zeit gefüllt, die bis-Zeit wird überschrieben 
74.
            if ($ztyp=="ST"
75.
76.
               $ztivsav=$ztim
77.
               $ztibsav=""
78.
               $strtimvsav=$zstp
79.
80.
//Bei EN wird die von-Zeit gelöscht uns die bis-Zeit gefüllt 
81.
            else 
82.
83.
               $ztivsav=""
84.
               $ztibsav=$ztim
85.
               $strtimbsav=$zstp
86.
87.
88.
//Speichern des letzten Datensatzes 
89.
         $lasttyp=$ztyp
90.
         $lastper=$zper
91.
         $laststp=$zstp
92.
      }
Bei der Entwicklung der Logik hat mir unser Entwickler unter die Arme gegriffen. Er kennt sich mit diesen Logiken aus, kennt aber php nicht.



Ich ziehe es vor, die Daten und Zeiten gleich bei der Abfrage mit
Hilfe von MySQL-Funktionen

zu ermitteln. Die MA-ID, das Datum und die Ein/Ausstempelzeit habe
ich durch zwei

Abfragen/Schleifen in einem Array als Arrays gespeichert.


Hier denke ich, daß alles in einer SQL Abfrage erledigt werden kann, da ich die ST und EN Info in der Datenbank bereits habe.


Ich vermute mal, du setzt eine Abfrage ab, und willst durch entspr.
if/else/then-Kontrollen prüfen, wann

der Wechsel von einer ID zur nächsten ID erfolgt um dann die
Zwischensumme auszugeben. Erstens glaube ich nicht,

das das geht, und wenn, dann nur mit erheblichem Aufwand. Da ist es
erheblich einfacher, zwei Schleifen zu programmieren,

so wie es Snowman schon geschrieben hat, bzw. wie es in meinem
Beispiel steht:

Genau das war mein erster Ansatz. Ist auch nicht weiter schwer (prinzipiell), funktioniert aber trotzdem nicht. Komme ich beim letzten MA an, habe ich keinen MA-Wechsel mehr. Die Schleife hört auf ohne Ausgabe einer Zwischensumme. Wenn hier der letzte Groschen fällt, löse ich es auf diese Weise. Ansonsten gehe ich auf die 2-Schleifen Variante.

Bei dieser SQL Abfrage habe ich immer Probleme gehabt. Wenn ich das date_format weg gelassen habe, hatte ich ein Ergebnis.

$query='select u_id,date_format(zeit,"%d.%m.%Y") as
Datum,min(time_to_sec(zeit)) as Beginn'
.' from zeiten2 where
date_format(zeit,"%Y-%m-%d") between
"'.$vonTag.'" and
"'.$bisTag.'"'
.' group by u_id,Datum';
$result=mysql_query($query);
/*
Mag daran liegen, daß die Original Datums-Daten in der Form "Jahr-Monat-Tag Stunde:Minute:Sekunde" vorliegen. Aber wie gesagt, da werde ich versuchen, mit einer einzigen SQL Abfrage alles erledigen zu können. Hier hilft die time_to_sec Funktion weiter. Die kannte ich noch nicht. Das wird sicher viel vereinfachen.

Bevor ich weitermachen kann, werden wieder einige Tage vergehen. Ausseneinsätze

Schöne Grüße
Christof

EDIT:
weitere Informationen zum besseren Verständnis:
Ich verwende zwei Tabellen. Die MA werden in einer Member Tabelle gepflegt.
Dort habe ich:
eine eindeutige ID, Nachname, Vorname, RFID Transponder Nummer, Projektzugehörigkeit

Die Daten werden in einer anderen Tabelle abgelegt. Sie sieht so aus:
Eindeutige ID, Typ ST oder EN (ztyp), Gerätenummer in der die Daten erfasst werden(zter), Erfassungszeit "Jahr-Monat-Tag Stunde:Minute:Sekunde" (zdat), Transpondernummer (zper), Projektnummer auf der gearbeitet wird (zpro) für weiter Verwendungen, das Datum wann der Datensatz gespeichert wurde (Timestamp)(datum), und noch ein Flag, um später markieren zu können, ob der Datensatz weiter verarbeitet worden ist (Abrechnung oder manuelle Änderung).

Bei Sortierung nach zper und zdat habe ich die zusammengehörenden Datensätze untereinander stehen, wenn sie komplett sind. Sind sie es nicht, fange ich in php die Sonderfälle ab.

Die Verknüpfung erfolgt über das Fels rfid in der Membertabelle und dem Feld zper in der Datentabelle.
Bitte warten ..
Mitglied: Guenni
28.09.2009 um 01:01 Uhr
Hi Christof,


Knackpunkt deiner Anwendung scheint ja die Zwischensumme zu sein. Ich versuch jetzt mal

zu erklären, warum das mit zwei Schleifen einfacher, wenn nicht sogar logischer zu

lösen ist.



Ich frage jetzt die Zeiten zu einer ID ab und summiere diese:

01.
<?php 
02.
 
03.
 $query="select . . . from tabelle2 where u_id=1"
04.
 
05.
 . . .  
06.
 
07.
 while($row=mysql_fetch_array( . . . usw.)){ 
08.
 
09.
   echo "Ausgabe der abgefragten Felder"
10.
 
11.
   $zwisum+=$row['std']; /* Wobei die Stunden bei dir berechnet werden. *
12.
 
13.
14.
  
15.
  
16.
 /* Nach Beenden der Schleife wird die Zwischensumme ausgegeben. *
17.
   
18.
   echo $zwisum
19.
 
20.
?>
Innerhalb der while-Schleife können noch deine Berechnungen etc. erfolgen.


Um jetzt die gleichen Werte für jede ID abzufragen/zu berechnen, müßte ich

den Ausdruck "where u_id=1" jedesmal ändern bzw. die ID über ein Formular eingeben.


Da liegt es doch nahe, den Ausdruck "dynamisch" zu erstellen, sprich, einen Algorithmus

zu entwickeln, der mir "solange wie vorhanden" ID's liefert:

01.
<?php 
02.
 
03.
$query1="select id, . . . from tabelle1 join tabelle2 on tabelle1.id=tabelle2.u_id"
04.
?>
Eine while-Schleife liefert mit die ID, und weitere Details, der MA, die in der Personaltabelle ist

sowie in der Zeitentabelle, sprich, wer gestempelt hat.


Innerhalb dieser äußeren Schleife packe ich nun den oben prog. Code und ersetzte den

Ausdruck "where u_id=1" durch "where u_id=".$row1['id'].


Vereinfacht heißt das:

Solange die äußere Schleife eine ID liefert, wird die innere Schleife ausgeführt, macht Berechnungen,

gibt Details zur ID aus etc.. Wenn keine ID mehr kommt, wird die innere Schleife auch nicht mehr ausgeführt.


Zum Problem date_format( . . .

Auch in meiner Tabelle liegt die Ein-/Ausstempelzeit im Format "Jahr-Monat-Tag Stunde:Minute:Sekunde" vor.

Die Funktion ist in der Lage, den Datumsanteil in deutscher Schreibweise auszugeben:

select date_format(feldname,"%d.%m.%Y") as Datum , . . . usw.

Ich kann aber den Alias Datum nicht in der where-Klausel verwenden,

auch wenn ich schreiben würde:

select date_format(feldname,"%Y-%m-%d") as Datum, weil Datum kein gültiger Spaltenname ist.

Da muß ich tatsächlich schreiben ". . . where date_format(spaltenname,"%Y-%m-%d) . . . "


Zur Tabelle der MA:

Das Feld "Projektzugehörigkeit" gehört in die Tabelle, in der die Zeiten erfasst werden.

Denn nur so erfahre ich, wieviele Std ein MA anwelchem Projekt gearbeitet hat.


Gruß
Günni
Bitte warten ..
Mitglied: gechger
27.10.2009 um 15:48 Uhr
Hallo Günni,

habe jetzt wieder an meinem Zwischensummenproblem weitermachen können und es tatsächlich auch gelöst. Ich habe keine Zwei Schleifen Funktion benutzt, sondern den Userwechsel direkt abgefragt.

01.
  
02.
//Wenn temporäre Variable mit Personalnummer leer ist, wird diese durch aktuelle Personalnummer gefüllt. 
03.
        if (empty($zpertemp)) 
04.
05.
           $zpertemp=$zper
06.
07.
 
08.
        //Wenn aktuelle Personalnummer mit PersNummer des letzten Durchlaufs identisch ist, prüfe.. 
09.
        if ($zpertemp==$zper
10.
11.
 
12.
             //..ob die Unixzeit größer Null ist, Daten also komplett sind. Dann soll die ZwSumme hoch addiert werden... 
13.
             if ($unixzeit > 0) 
14.
15.
               $zwsummead+=$unixzeit
16.
 
17.
18.
 
19.
20.
 
21.
//echo "zpertemp=$zpertemp","<br>"
22.
//echo "zper=$zper","<br>"
23.
//echo "zwsummead=$zwsummead","<br>"
24.
 
25.
        if ($zpertemp != $zper
26.
27.
 
28.
               $zwsummeun=$zwsummead
29.
               $algstunden=round(($zwsummeun/3600),2); 
30.
               $algminuten=round((fmod($zwsummeun, 3600)/60),2); 
31.
               $algsekunden=round((fmod($algminuten, 60)/60),2); 
32.
               $algstwert=explode(".",$algstunden); 
33.
               $algminwert=explode(".",$algminuten); 
34.
               $zwsumme=$algstwert[0].":".sprintf("%02d",$algminwert[0]); 
35.
 
36.
               $adzwsum+=$zwsummeun
37.
               if ($unixzeit > 0) 
38.
39.
 
40.
                  $zwsummead=$unixzeit
41.
42.
               else 
43.
44.
                  $zwsummead=0; 
45.
46.
               $zpertemp=$zper
47.
               //$endsumme=$gsumme - $adzwsumme
48.
               echo "Zwischensumme=$zwsumme","<br>"
49.
 
50.
               include"ausgabedat.php"
51.
 
52.
               $zwsummeun=""
53.
               $zwsumme=""
54.
 
55.
             $c="1"
56.
 
57.
            }
Dies ist der Kern der Zwischensummenberechnung.

Problem:
Beim letzten User wird keine Zwischensumme ausgegeben.
Lösung:
ich addiere alle Zwischensummen, die ausgegeben worden sind. Ebenso addiere ich alle Einzelzeiten.
Die Summe aller Einzelzeiten ist identisch mit meiner Gesamtzeit. Davon ziehe ich die bisher ausgegebenen Zwischensummen ab. Die Differenz entspricht der Zwischensumme des letzten Users, die ich am Ende ausgeben kann.

01.
   $lastsum=$gsummead - $adzwsum
02.
   $alglaststd=round(($lastsum/3600),2); 
03.
   $alglastmin=round((fmod($lastsum, 3600)/60),2); 
04.
   $algwertstd=explode(".",$alglaststd); 
05.
   $algwertmin=explode(".",$alglastmin); 
06.
   $endsumme=$algwertstd[0].":".sprintf("%02d",$algwertmin[0]); 
07.
 
08.
echo "Zwischensumme= $endsumme","<br><br>"
09.
 
10.
   $gsumstd=round(($gsummead/3600),2); 
11.
   $gsummin=round((fmod($gsummead, 3600)/60),2); 
12.
   $gwertstd=explode(".",$gsumstd); 
13.
   $gwertmin=explode(".",$gsummin); 
14.
   $gsumme=$gwertstd[0].":".sprintf("%02d",$gwertmin[0]); 
15.
 
16.
echo "Gesamtstunden= $gsumme","<br><br>";
Hört sich im ersten Moment kompliziert an, ist aber letztendlich gar nicht so schwierig

Jedenfalls vielen Dank an Alle für Eure Ideen

Schöne Grüße
Christof
Bitte warten ..
Neuester Wissensbeitrag
Humor (lol)

Linkliste für Adventskalender

(3)

Information von nikoatit zum Thema Humor (lol) ...

Ähnliche Inhalte
Heiß diskutierte Inhalte
Windows Server
DHCP Server switchen (25)

Frage von M.Marz zum Thema Windows Server ...

SAN, NAS, DAS
gelöst HP-Proliant Microserver Betriebssystem (14)

Frage von Yannosch zum Thema SAN, NAS, DAS ...

Grafikkarten & Monitore
Win 10 Grafikkarte Crash von Software? (13)

Frage von Marabunta zum Thema Grafikkarten & Monitore ...

Windows 7
Verteillösung für IT-Raum benötigt (12)

Frage von TheM-Man zum Thema Windows 7 ...