Urlaubstage ausgeben in Tabelle

Baumi Manuel

Mitglied
Hallo Community!

Erstmals ein großes Hallo! Hab zwar schon sehr viel nützliches aus diesem Forum verwenden können aber jetzt ist es mal soweit selbst eine Frage zu stellen:

Folgendes habe ich zu lösen:
In einer Datenbank stehen die Urlaube (Startdatum, Endedatum).
in einer html - Tabelle wo immer nur ein Monat dargestellt wird, muss ich die Urlaubstage auflisten welche in diesem Monat sind, und das für jeden Mitarbeiter in einer eigenen Zeile.
also einfach gesagt: in der y-Achse stehen die Mitarbeiter untereinander und in der x-Achse die Monatstage

ich habe bereits für jeden mitarbeiter den Urlaub gefiltert der dieses monat betrifft (denn es sind ja vom ganzen Jahr die urlaube in der datenbank gespeichert) und ich weiß wie viele tage jeder in diesem monat urlaub hat!
mein Problem: wie bringe ich dann den eintrag in die richtige zelle der tabelle bei dem richtigen mitarbeiter...****?

Irgendwie stehe ich auf der Leitung kommt mir vor! Das kann ja nicht so schwer sein!!****

ICh wäre über eine kleine Hilfestellung sehr dankbar!!

p.s. ich will kein feritges script oda so haben; aber viellicht könnt ihr mir nen tipp geben wie ich das lösen kann!!


Danke und Liebe Grüße
 
Hi und Willkommen bei tutorials.de,

horizontal sind also alle 28-31 Monatstage, und wenn an dem Tag bei dem Mitarbeiter Urlaub ist,
soll in der Zelle was drinstehen('x' oder so).
Hab ich das so richtig verstanden?

Per SQL bekommst du alle Mitarbeiter und Von-Bis, eingegrenzt auf das Monat.
Änder die Query noch so, dass für Von-Bis nur die puren Tage als Zahlen rauskommen,
statt das vollständige Datum (kann man auch in PHP machen,aber warum nicht gleich in der DB?).

Fer Schleife alle Mitarbeiter durchgehen.
Innen noch eine Schleife für die Monatstage, die eine ganze Tabellenzeile macht.
Und wenn der aktuelle Tag >= Urlaubsanfang und <= Urlaubsende ist,
wirds kein leeres td, sondern mit Inhalt.
 
In MySQL ist das relativ einfach zu machen, damit du eine Liste hast, die du nachher nur noch abarbeiten musst

Ich weiss, dass du eigentlich kein Script willst. Aber erklären ist noch viel schwerer

Die Tagesliste ist analog der Jahres-Liste: http://www.tutorials.de/content/1138-mysql-virtuelle-tabelle-mit-allen-daten-im-jahr.html

SQL:
SELECT
   @month_date := DATE(CONCAT_WS('-', YEAR(select_month), MONTH(select_month), day_of_month)) AS month_date,
	my_data.name,
	IF(@month_date BETWEEN holiday_start AND holiday_end, 'X', '')    AS is_in_holiday
FROM
	(
		-- [Variablen]
		-- Ein Datum, dass den Monat und das Jahr vorgibt. 
		-- Kann ein beliebiger Tag im entsprechenden Monat sein
		SELECT DATE('2012-01-1') AS select_month
		-- [/Variablen]
	) AS my_vars,
   (
       -- [Tagesnummern]
       -- Zahlen von 1 bis 32
       SELECT
           @day_of_month := @day_of_month +1 AS day_of_month
       FROM
           (SELECT @day_of_month :=0) AS vars,
           -- [VirtualRows]
           -- 32 Zeilen um die Tageszeilen zu erstellen (4*4*2)
           (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS d1,
           (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS d2,
           (SELECT 1 UNION SELECT 2) AS d3
           -- [/VirtualRows]
       -- [/Tagesnummern]
   ) AS days_of_month,
	(
		-- [Daten]
		-- Simulieren der DB-Daten
		SELECT 'Hans' AS name, DATE('2012-01-05') AS holiday_start, DATE('2012-01-15') AS holiday_end 
		UNION SELECT 'Paul', DATE('2012-01-25'), DATE('2012-02-05')
		-- [/Daten]
	) AS my_data   
WHERE
 day_of_month <= DAY(LAST_DAY(select_month))
ORDER BY
	name,
	month_date;
Das ergibt dann die Daten in der folgenden Form
Code:
month_date | name | is_in_holiday
---------------------------------
2012-01-01 | Hans | 
2012-01-02 | Hans | 
2012-01-03 | Hans | 
2012-01-04 | Hans | 
2012-01-05 | Hans | X
2012-01-06 | Hans | X
2012-01-07 | Hans | X
2012-01-08 | Hans | X
2012-01-09 | Hans | X
2012-01-10 | Hans | X
2012-01-11 | Hans | X
2012-01-12 | Hans | X
2012-01-13 | Hans | X
2012-01-14 | Hans | X
2012-01-15 | Hans | X
2012-01-16 | Hans | 
2012-01-17 | Hans | 
2012-01-18 | Hans | 
2012-01-19 | Hans | 
2012-01-20 | Hans | 
2012-01-21 | Hans | 
2012-01-22 | Hans | 
2012-01-23 | Hans | 
2012-01-24 | Hans | 
2012-01-25 | Hans | 
2012-01-26 | Hans | 
2012-01-27 | Hans | 
2012-01-28 | Hans | 
2012-01-29 | Hans | 
2012-01-30 | Hans | 
2012-01-31 | Hans | 
2012-01-01 | Paul | 
2012-01-02 | Paul | 
2012-01-03 | Paul | 
2012-01-04 | Paul | 
2012-01-05 | Paul | 
2012-01-06 | Paul | 
2012-01-07 | Paul | 
2012-01-08 | Paul | 
2012-01-09 | Paul | 
2012-01-10 | Paul | 
2012-01-11 | Paul | 
2012-01-12 | Paul | 
2012-01-13 | Paul | 
2012-01-14 | Paul | 
2012-01-15 | Paul | 
2012-01-16 | Paul | 
2012-01-17 | Paul | 
2012-01-18 | Paul | 
2012-01-19 | Paul | 
2012-01-20 | Paul | 
2012-01-21 | Paul | 
2012-01-22 | Paul | 
2012-01-23 | Paul | 
2012-01-24 | Paul | 
2012-01-25 | Paul | X
2012-01-26 | Paul | X
2012-01-27 | Paul | X
2012-01-28 | Paul | X
2012-01-29 | Paul | X
2012-01-30 | Paul | X
2012-01-31 | Paul | X


Und die Umsetzung ins PHP ist dann recht simple
Auf Zeile 14 wird das Datum in das SQL eingefügt und ab Zeile 47 beginnt die Auswertung
Code:
//Als Beispiel mal der Janaur 2012
$selectDate = mktime(0,0,0, 1, 1, 2012);

$sql = <<<SQL
SELECT
   @month_date := DATE(CONCAT_WS('-', YEAR(select_month), MONTH(select_month), day_of_month)) AS month_date,
    my_data.name,
    IF(@month_date BETWEEN holiday_start AND holiday_end, 'X', '')    AS is_in_holiday
FROM
    (
        -- [Variablen]
        -- Ein Datum, dass den Monat und das Jahr vorgibt. 
        -- Kann ein beliebiger Tag im entsprechenden Monat sein
        SELECT FROM_UNIXTIME({$selectDate}) AS select_month
        -- [/Variablen]
    ) AS my_vars,
   (
       -- [Tagesnummern]
       -- Zahlen von 1 bis 32
       SELECT
           @day_of_month := @day_of_month +1 AS day_of_month
       FROM
           (SELECT @day_of_month :=0) AS vars,
           -- [VirtualRows]
           -- 32 Zeilen um die Tageszeilen zu erstellen (4*4*2)
           (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS d1,
           (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS d2,
           (SELECT 1 UNION SELECT 2) AS d3
           -- [/VirtualRows]
       -- [/Tagesnummern]
   ) AS days_of_month,
    (
        -- [Daten]
        -- Simulieren der DB-Daten
        SELECT 'Hans' AS name, DATE('2012-01-05') AS holiday_start, DATE('2012-01-15') AS holiday_end 
        UNION SELECT 'Paul', DATE('2012-01-25'), DATE('2012-02-05')
        -- [/Daten]
    ) AS my_data   
WHERE
 day_of_month <= DAY(LAST_DAY(select_month))
ORDER BY
    name,
    month_date
SQL;

$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)){
    $month_date[] = $row['month_date'];
    $data[$row['name']][] = $row['is_in_holiday'];
}
// Dublikate entfernen (Die Daten sind im Moment mit Faktor [Anzahl Mitabreiter] im Array
$month_date = array_unique($month_date);
echo '<table>';
//Datumszeile ausgeben
echo '<tr><th /><th>'.implode('</th><th>', $month_date).'</th></tr>';
//Mitarbeiterliste mit Ferientagen ausgeben
foreach($data as $rowHeader => $values){
    echo '<tr>';
    echo "<th>{$rowHeader}</th>";
    foreach($values as $value){
        echo "<td>{$value}</td>";
    }
    echo '</tr>';
}
echo '</table>';




Achja, hab glaub ich hab in der Vergangenheit bereits mal erwähnt, dass ich solche SQL-Spielereien spassig finde
 
Zuletzt bearbeitet von einem Moderator:
Hi!

Erstmal Danke für die Antworten!

Mittlerweile hab ich es sogar selbst hinbekommen mit einigen Änderungen in der Datenbank!
Ich habe, und das ist jetzt sicher keine "schöne" Lösung, die Datenbank so geändert, dass beim Eintragen der Urlaubstage das Jahr, Monat und der Tag je in einer Spalte gespeichert wird. Somit hab ich mir leichter getan beim Darstellen. Also im Grunde e so wie @sheel gemeind hat!
Aber der Lösungsansatz von dir @Yaslaw ist natürlich total professionell! Wenn du nichts dagege hast würd ich deine Version adaptieren!! Ist das OK für dich****

Aber ich bin mittlerweile auf ein weiteres Problem gestoßen! Ich habe festgestellt, dass es Sinn machen würde aus dieser Ansicht auch eine editierbare Ansicht zu machen. Das heißt es soll dem User möglich sein jeden Dienst bzw. jeden Urlaubstag ändern zu können!

Meine Idee diesbezüglich: ich schreibe jeden Urlaub bzw jeden Tagdienst und Nachtdienst (diese stehen auch in der Ansicht drinnen) in ein Textfeld und per POST wird dann gespeichert! Ist das eine PHP-Programmierer würdige Lösung, oder fällt euch da noch was besseres ein!

Mein Wunsch wäre halt das die Änderungen gleich, so wie es in enigen OpenSource Scripten angeboten wird, sozusagen inline geändert und gespeichert werden können. Praktisch wäre auch ein paar Felder am Schluss jedes Mitarbeiters wo alle Urlaubstage und Urlaubsstunde bzw Arbeitsstunden immer gleich nach einer Änderung adaptiert werden. Aber soweit ich das bis jetzt im Zuge meiner Recherchen mitbekommen habe kann man das nur mittels JavaScript realisieren, und davon hab ich leider noch zu wenig Ahnung!! :-(

Gibts da vielleicht ne andre Möglichkeit? Ich weiß nicht, vielleicht mit versteckten iframe oder so?

p.s. Ich habe nichts gegen Codebeispiele, von so etwas lernt man! Aber ich wollte nicht den Eindruck erwecken ich möchte von euch ein fertiges Script haben das ich einfach per Drag&Drop in mein Projekt einfügen kann. Ich hab mir das Programmieren selbst beigebracht, und dabei hab ich gemerkt, lernen tut man nicht wenn man ständig nur Codes kopiert! ;-)

Danke!
Liebe Grüße!
 
Natürlich darfst du das Script adoptieren - darum stehts im Forum.

iFrame - nope, vergiss es. Es ist nicht schön , nicht praktisch und mMn eher schwer zu handeln.

Das mit dem inline speichern geht über Ajax (PHP und Javascript gemixt). Ich hatte mal ein kleines (nicht unbedingt perfektes) Beispiel geschrieben: PHP Ajax Beispiel

Ich versteh noch nicht ganz, wie du die Schichten änder willst. WIllst du ein Schicht-Anfang und Achicht-Ende Feld haben? Oder wie was?
 
Hi!

Also es gibt bei uns im Krankenhaus im Grunde nur folgende "Schichten" die in dem Programm ausgegeben werden sollen:

TD --> Tagdienst
ND --> Nachtdienst
SD --> Stationsdienst
U --> Urlaubstag
xF --> Fortbildung


Mein Programm macht folgendes:
Die Stationsleitung erstellt einen Dienstplan für ein Monat; alle Mitarbeiter bekommen eine automatische SMS das sie im neeuen Dienstplan eintragen können, es gibt 4 Gruppen von Mitarbeitern, immer der erste in der Gruppe darf eintragen, wenn er fertig ist wird automatische SMS an den nächsten in der Gruppe gesendet der eintragen darf usw... bis alle eingetragen haben. Dann schaut die Stationsleitung auf die Übersicht die ich gerade programmiere und kann noch Änderungen vorhnehmen. (da bin ich gerade). wenn alles geängert wurde und jetzt passt wird er freigestellt und jeder kann sich seine Dienste ansehen wann er arbeitet.


Dein Ajax Script werd ich mir gleich mal ansehen...
Meine erste Frage dazu: Wie schauts mit der Complience betreffend Ajax und den diversen Browsern aus? Im Krankenhaus ist großteils IE installiert, teilweise auch Mozilla.
In meiner Userauswertung aller Besucher auf der Seite kam heraus das es aber auch einige Apple User mit Safari gibt und ein paar die nicht identifiziert werden konnten!! Gibts da häufig Troubles oder e nicht****

Danke,
LG
 
Für Ajax muss Javascript freigeschaltet sein.

Ich würde hinter jeden Namen einen Link setzen. Beim draufklicken kommt man in eine Listenansicht mit der Auflistung der Ferien (also so wie sie in der Tabelle sind). Jeder Eintrag hat einen edit- und einen delete-Link.
Zudem hast du da noch ein Formular um einen neuen Eintrag vorzunehmen.

Wenn du direkt aus der Übersichstsliste (die wir hier zusammen erstellt haben) ändern möchtest, müsst es extrem erweiterte Logik haben. Bei einem Klick auf ein ein Feld müsste das System erkennen ob ein neuer Ferieneintrag erstellt werden muss, ob ein bestehender vergrössert wird, ob ein bestehender gelöscht wird, ob ein bestehender getrennt wird etc.

Noch eine ergänzung zum Script.
Du kannst im SQL das Datum als Unix-Timestamp ausgeben lassen. Damit kannst du das Datum je nach Wunsch anderst ausgeben. Auch die Wochentage lassen sich ermitteln etc.
SQL:
SELECT
    @month_date := DATE(CONCAT_WS('-', YEAR(select_month), MONTH(select_month), day_of_month)) AS month_date,
    UNIX_TIMESTAMP(@month_date) AS unix_date,
    my_data.name,
...
mit diesem unix_date kannst du nachher in PHP das Datum sauber darstellen

PHP:
/** Auslesen ändern */
while($row = mysql_fetch_assoc($result)){
    $month_date[] = $row['unix_date'];

// Ersetzen mit
    $month_date[] = $row['month_date'];


/** Ausgabe ändern */
//Datumszeile ausgeben
echo '<tr><th /><th>'.implode('</th><th>', $month_date).'</th></tr>';

// -- Ersetzen mit ---
$weekendWeekDays= array(7, 0)
echo '<tr><th />'
foreach($month_date as $date){
  //Datum ohne Jahr, dafür mit kurzem Monatsnamen ausgeben
  $value = date('d. M', $date);
  //Falls es ein Wochenende ist, Fett darstellen (Kann beliebig angepasst werden)
  if(in_array(date('w', $date), array(0,7)) $value = "<b>{$value}</b>";
  echo "<th>{$value}</th>";
}
echo '</tr>';
 
Zuletzt bearbeitet von einem Moderator:
Zurück