Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Zeiterfassung in DB, generelle Vorgehensweise? (https://www.delphipraxis.net/101319-zeiterfassung-db-generelle-vorgehensweise.html)

Salomon 11. Okt 2007 10:53

Datenbank: MS SQL 2005 • Zugriff über: ADO

Zeiterfassung in DB, generelle Vorgehensweise?
 
Hallo DPler,
ich bin gerade dabei eine Art Zeiterfassung zu programmieren. Jeder User soll pro Tag mehrere Zeiträume eingeben können in denen er gearbeitet hat, und woran.

Später soll mit FastReports ein monatlicher Report erstellt werden, indem die Stunden für die einzelnen Arbeitstage aufgelistet sind.

Nun stellt sich mir die Frage wie ich dies am besten in der Datenbank abbilde. Empfiehlt es sich für jeden Zeitraum einen Datensatz anzulegen? z.B. in einer solchen Tabelle

TB_Hours
=========
UserID
Date
FromTo
ToHour
Task


Sollte ich die Zeiträume Minutengenau aufnehmen oder die Industriezeit verwenden?

Ich weiß das das noch relative ungenaue Fragen sind, brauche aber einfach ein paar Ideen zur Vorgehensweise. Evtl. hat ja schon einer Erfahrung.

Gruß
Marcus

mkinzler 11. Okt 2007 10:57

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich würde nur die jeweiligen Beginn- und Endzeitpunkte erfassen und die Dauer bei Bedarf ohne Überschneidungen berechnen.

Salomon 11. Okt 2007 11:18

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Quasi so wie meine Tabelle oben. Ich habe mich da ein wenig mit den Namen vertan...

Wie prüfe ich mit SQL Allerdings ab, ob die neue Zeitspanne nicht schon in eine existierende fällt, oder sich mit einer überschneidet? das ist mir noch nicht so klar.

Andreas H. 11. Okt 2007 11:22

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Hallo,

mit diesem Thema habe ich mich auch mal beschäftigt. Ich gebe mkinzler recht.
Damals habe ich Ereignisse gespeichert und die Salden durch Abklappern aller Ereignisse berechnet.
Damit lassen sich dann auch automatische Pausen, unplanmäßgie Pausen, Kommentare/Meilensteine und Zeiträume über Taggrenzen hnweg leicht bearbeiten. Auch lassen sich so Anwesenheiten und Aufwandserfassung mit dem gleichen Datenmodell beschreiben.
Der Datensatz sah etwa so aus:
Delphi-Quellcode:
Satzart: set(kommt, geht, Pause Anfang, Pause Ende, etc.)
Zeitpunkt: timestamp
Kommentar: string
Zur Speicherung habe ich damals XML benutzt, da das Ganze stand alone laufen sollte. Ist auch nie richtig fertig geworden :cry:

Allerdings ist der Progrmmieraufwand natürlich größer, als wenn Du Deine atensätze "formularmäßig" aufbaust.

Ich bin an dem Thema immer noch interessiert. Vielleicht kannst Du mich auf dem Laufenden halten?

Gruß Andreas

ps. mit meinem Modell ist hast Du die Problematik nicht, oder?

Phoenix 11. Okt 2007 11:23

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Wenn der Tag gleich ist, dann darf
  • Ein neuer Startzeipunkt nicht zwischen einem Start- und Ende oder
  • ein neuer Endzeitpunkt nicht zwischen einem Start- und Ende
eines bereits existierenden Datensatzes liegen.

That's it.

Bzw. in SQL

SQL-Code:
select count(*) from table where
(start < NeuStart and NeuStart < ende) OR
(start < NeuEnde and NeuEnde < ende)
Ist Count > 0 gibts ne Überschneidung.

Salomon 11. Okt 2007 11:28

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ah, das sollte gehen. Danke :)

Dann mach ich mich erstmal an die Umsetzung und melde mich wenn ich wieder irgendwo hänge.

mkinzler 11. Okt 2007 11:36

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
http://www.delphipraxis.net/internal...t.php?t=120385

Salomon 12. Okt 2007 09:19

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Mmh, von meinem MSSQL Server bekomme ich mit dem folgenden SQL Statement immer 0 zurück, obwohl für den Zeitraum ein Datensatz vorhanden ist. Kann das daran liegen das FromHour und ToHour in der DB als DateTime Datentyp deklariert sind?

Sieht für mich sonst ganz gut aus :gruebel:

Delphi-Quellcode:
  ADOQuery.SQL.Text :='SELECT COUNT(*) as DataExists FROM TB_AM_Hours WHERE' +
                      ' ((:FromHour BETWEEN FromHour and ToHour) ' +
                      ' or ' +
                      ' (:ToHour BETWEEN FromHour and ToHour))' +
                      ' and FK_UserID = :FK_UserID '+
                      ' and FK_ProgramID = :FK_ProgramID ' +
                      ' and Date = :Date ;';

                       ADOQuery.Parameters.ParamByName('FK_UserID').Value   := 1
                       ADOQuery.Parameters.ParamByName('FK_ProgramID').Value := 1;
                       ADOQuery.Parameters.ParamByName('Date').Value        := ActualDate;
                       ADOQuery.Parameters.ParamByName('FromHour').Value    := FromTime.Time;
                       ADOQuery.Parameters.ParamByName('ToHour').Value      := ToTime.time;

  ADOQuery.Open;

  if ADOQuery.FindField('DataExists').AsInteger > 0 then
  begin
    showmessage('Zeitraum belegt!');
  end;
MfG
Marcus

stahli 12. Okt 2007 09:40

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Salomon,

ich habe mal sowas für unser Amt geschrieben. (SK=Stechkarte)
Allerdings mit der BDE und Paradox. Läuft amer auch im Netzwerk ordentlich.

Die Zeiten speichere ich als Minuten. So lassen sich die Differenzen am besten berechnen. In dem Fall sind nur Zeiten über Mitternacht hinaus nicht möglich. (Aber so lange arbeiten wir ja nicht ;-) )
Über GetText und SetText wird die Ein- und Ausgabe dann formatiert. Ein großer Vorteil dabei:
16:45 Uhr kann auch als "16,45" über den Nummernblock oder "16 45" eingegeben werden. Das ist für den Nutzer sehr komfortabel.

Mein Programm erzeugt im Adminmodus monatliche Reports über die Überstunden der Nutzer für das Personalamt, gruppiert nach Nutzergruppen (Teilzeitarbeiter, Vorruheständler etc.)

Ich bin nicht wirklich stolz drauf (ist ziemliches Stückelwerk), aber wenn Du es als Anregung mal haben willst, kann ich es am WE mal hochladen...

Stahli

Nachtrag:
- die Überstunden werden automatisch in den nächsten Monat übernommen
- ist ein Monat vollständig eingegeben, kann der "Chef" die Einträge vergleichen und bestätigen
- danach kann der Nutzer nichts mehr ändern
- Feiertage, Urlaub etc. werden im Feld Status eingetragen
- Feld Extra steht für sonstige Zeiten, die nicht in´s normale Schema passen
- gewerkschaftliche Mindestpausen werden automatisch von der Arbeitszeit abgezogen

Salomon 12. Okt 2007 09:55

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Hallo Stahli,
das ist natürlich ein super Angebot :) Ein Beispiel kann ich gut gebrauchen.
Mein Programm wird etwas anders laufen, da die Mitarbeiter Ihre Zeiten selbst eintragen müssen. Darauf bassierend soll dann ihr monatlicher Report generiert werden, der auch zur Gehaltsabrechnung verwendet wird.

Mein Programmcode ist auch nicht der beste. Das ist kein Problem für mich. Man lernt halt immer weiter und merkt erst später wie umständlich man Teile realisiert hat.

Gruß
Marcus

stahli 12. Okt 2007 10:06

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ja, jeder Nutzer gibt seine Zeiten auch selbständig ein. Man kann auf jedem Rechner mehrere Nutzer freigeben (steht alles allerdings ganz simpel in einer Ini).
Ist ein Monat komplett eingegeben, kann der jeweilige Chef den Monat abhaken, dann kann nichts mehr manipuliert werden (jedenfalls nicht von meinen Leuten :-) ).

Ich muss Dich mal auf´s WE vertrösten und stelle das Geraffel dann hier rein. Das Programm läuft für die Nutzer gut, zu Quelltext und Wartung sage ich mal lieber nichts... :oops:

stahli

Salomon 12. Okt 2007 10:17

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Das klingt echt gut. Dann freu ich mich schon auf das Wochenende :)

Reinhard Kern 12. Okt 2007 12:12

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Hallo,

ein solches System, ob Bedienterminal oder PC, sollte beim Anmelden als erstes den Status des Users prüfen: arbeitet oder arbeitet nicht. Wer sich bereits als arbeitend angemeldet hat, kann sich nur abmelden und umgekehrt. Die Frage von Überschneidungen erübrigt sich damit, dafür braucht man eine Statusabfrage "arbeitet XY?". Die ist auch sowieso sehr praktisch für einen Anwesenheitsanzeige o.ä. Professionelle System haben oft ein Panel (ein reales, kein TPanel) mit Ausweisleser und LED-Anzeige für jeden User.

Gruss Reinhard

Salomon 12. Okt 2007 12:35

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Hi,
für meinen Fall können die Zeiträume vom User auch noch nachträglich eingeben werden. D.h. die User schreiben quasi auf wann Sie wie lange was gemacht haben. Darauf basierend soll dann der monatliche Report generiert werden.

Für eine Zeiterfassung die "realtime" arbeitet solltet man es so machen wie du schreibst. In meinem Fall könnte jedoch ein User probieren einen Zeitraum doppelt zu belegen.

guidok 12. Okt 2007 12:45

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich würde in der DB zwei Felder anlegen, nämlich "FROM" und "TO" und die beiden als DateTime. Darin ist das Datum und die Zeit gespeichert und meines Wissens kann man in Delphi damit ganz normal rechnen und auch der Tageswechsel wird berücksichtigt.

Also:

TO - FROM = Anwesenheitszeit

Warum noch ein extra Feld für das Datum?

stahli 12. Okt 2007 13:17

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Liste der Anhänge anzeigen (Anzahl: 3)
@guidok:
Weil Du dann ein Datum+Uhrzeit als Differenz erhältst.
12.10.07 12:30 Uhr - 12.10.07 12:00 Uhr ergibt dann sowas wie 01.01.1800 00:30 Uhr.
Wenn man das als "30 Minuten" interpretieren will muss man auch wieder herumrechnen.
Daher besser gleich alles in Minuten oder Sekunden speichern...


@Salomon:
So, ich mach´s gleich in der Mittagspause...

Das Programm am besten wenn vorhanden auf M:\Sk laufen lassen (sonst wird das Formular rot gefärbt, damit man sieht, dass man mit Kopiedaten arbeitet). M:\ ist unser Netzlaufwerk.
Der Ordner Sk-Lokal mit der Ini muss auf C:\ liegen.
Gemeinsame Netzzugriffe sind möglich, wenn die BDE entsprechend konfiguriert ist.
Rechtsklick unten rechts auf das Formular erlaubt ein paar Einstellungen.

Wie gesagt, das ganze ist für die Anwender recht bequem, aber die Wartung war nur durch mich geplant. Ich kann im Dienst auch nur mal nebenbei schnell was programmieren - entsprechend sieht das ganze aus :-(

Bei Fragen - jederzeit gern.


@Reinhard:
Ein Chip-System soll in der Stadtverwaltung auch mmaaaaallllll kommen. Früher mussten wir noch Stunden+Minuten in Dezimalzahlen umrechnen... (müssen wir - bzw. mein Programm - jetzt bei der Weitergabe an das Personalamt auch noch) da war mein Programm schon ein riesiger Fortschritt.
Bei den IT-Admins habe ich angefragt, ob ich einen DB-Server nutzen darf - is nich wegen fehlender Sicherheitszertifizierung. Sonst hätte ich das Projekt schon mal generalüberholt. Na ja, die Nutzer können ja aktuell nicht klagen...


stahli

Salomon 12. Okt 2007 14:03

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich habe das ganze eben mal runtergeladen. Werde wohl aber erst nächste Woche dazu kommen näher rein zu schauen. Ist ja schon etwas code ;) Danke dafür!

Wenn man das Datum als "Date/Time" Wert speichert, muss bei Zeitraumvergleichen auch immer das Datum mit angegeben werden. Finde ich recht unpraktisch. Daher werde ich die Zeiten wohl als Float speichern.

Ich wünsche allen ein schönes WE!

mkinzler 12. Okt 2007 14:15

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich würde den von der Datenbank angebotenen Typen für Zeit verwenden, da nur so eine richtige Sortierung möglich ist und die DBMS weitere Verarbeitungsfunktionen für diese Typen anbieteten.

stahli 12. Okt 2007 14:32

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
In einem aktuellen Firebird-Projekt nutze ich für Start- und Endezeiten TDateTime-Felder.
Alle Felder, die eine Dauer beinhalten (berechnete oder vorgegebene) sind Integer und beinhalten die Sekunden. Differenzen zwischen zwei TDateTime kann man ja leicht in Sekunden umrechnen.

Die Darstellung der Dauer erfolgt dann über eine Funktion (bei Wert 75: "noch 1:15 min").
Änderungen von Dauervorgaben sind leicht über TUpDown möglich.

alzaimar 12. Okt 2007 16:32

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Zitat von stahli
@guidok:
Weil Du dann ein Datum+Uhrzeit als Differenz erhältst.
12.10.07 12:30 Uhr - 12.10.07 12:00 Uhr ergibt dann sowas wie 01.01.1800 00:30 Uhr.

Die Differenz zweier TDateTime-Werte ist aber kein Datum sondern ein Float-Wert, der die Anzahl der Tage (ink. Dezimalwerten) wiederspiegelt. Insofern ist die Differenz hier 1 + 30/1440, oder 1,020833. Und das ist doch genau das Ergebnis, das wir haben wollen.
Wenn Du das in Minuten umrechnest, musst Du nur mit 1440 multiplizieren und erhälst als Ergebnis 1470. Was willst Du mehr?

guidok 12. Okt 2007 18:34

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Wenn man das Datum als "Date/Time" Wert speichert, muss bei Zeitraumvergleichen auch immer das Datum mit angegeben werden. Finde ich recht unpraktisch. Daher werde ich die Zeiten wohl als Float speichern.

Du kannst doch aus dem DateTime den Date oder die Time extrahieren, dann musst du nichts mit angeben. Alles andere hat Alzaimar schon gesagt.

stahli 12. Okt 2007 18:46

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
eigentlich gehuppt wie gesprungen

Man muss in jedem Fall irgend etwas umrechnen oder umformatieren.
Wenn man DateTime für die Verwaltung von xx Minuten verwendet sieht das zumindest in eine TTable nicht sehr geschickt aus.

Aus jetziger Sicht würde ich daher für Dauer-Daten (die sich nicht über Tage und Monate erstrecken) Minuten oder Sekunden in Integerfeldern speichern.

grenzgaenger 12. Okt 2007 19:22

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
sag mal, weshalb nimmste nicht 'n (modified) julian date(time) oder 'n UNIX date(time)? da kannste einfach rechnen und biste immer auf der sicheren seite ... :-)

guidok 12. Okt 2007 19:51

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich kann auch nur sagen wie ich es machen würde und TTable kommt bei mir eh nicht ins Haus. Ist ja wohl ein leichtes aus einer Query die Daten auszulesen und selbst in ein entsprechendes Control zu bringen.

Zitat:

Aus jetziger Sicht würde ich daher für Dauer-Daten (die sich nicht über Tage und Monate erstrecken) Minuten oder Sekunden in Integerfeldern speichern.
Letztendlich gibt es hier keine "Dauer-Daten" sondern Beginn- und Endezeiten und ich habe heute morgen am 12.1007 um 6:23 Uhr mit der Arbeit begonnen. Merkst du was?

stahli 13. Okt 2007 12:27

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
@grenzgaenger

Ich weiß jetzt nicht, was Du meinst.
Ich habe damals die BDE genutzt und jetzt FB.


@guidok

Ja klar, in dem eigenen Programm wird man die Ausgabe immer formatieren. Bei Einsicht in die Datenbank (z.B. mit einer DBConsole) werden Inhalte von DateTime-Feldern aber auch entsprechend formatiert. Das fände ich schon störend, wenn es sich nicht wirklich um ein Datum und eine Uhrzeit handelt.

In meinem Stechkartenprojekt bin ich davon ausgegangen, dass hier "Überstunden" bzw. "Überminuten" (positive + negative) verwaltet werden sollen. Deshalb sollten diese Werte auch in Integerfeldern stehen. Die kleinste Einheit ist in dem Fall eine Minute.
Hier interessieren weniger die einzelnen Uhrzeiten sondern das Saldo am Ende. Die Soll-Arbeitszeit ist ja auch in Stunden+Minuten vorgegeben und nicht in einer Uhrzeit.
Klar, für den Arbeitsbeginn und das Arbeitsende kann man mit Datum+Uhrzeit arbeiten. Das macht schon Sinn.

Ich denke schon, es gibt mehrere Lösungen, die sich an Vor- und Nachteilen bzw. Aufwand alle nicht viel nehmen...

stahli

Jelly 13. Okt 2007 15:37

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Zitat von Salomon
Für eine Zeiterfassung die "realtime" arbeitet solltet man es so machen wie du schreibst. In meinem Fall könnte jedoch ein User probieren einen Zeitraum doppelt zu belegen.

Wenn dem so ist, würde ich das auf jeden Fall von der Datenbank selbst blockieren lassen, wenn da unsinniges Zeug eingetragen wird, denn nur so kannst du sicher sein, dass nicht doch irgendwas eingetragen wird, was nicht soll. Ich würde einen Trigger auf die Tabelle setzen (sowohl ein Update als Insert Trigger), und im Trigger ein Rollback und ein RAISERROR machen (bei MSSQL), wenn sich Zeiten überschneiden. Rollback bricht den Insert oder Update ab, und das RAISERROR löst eine Exception im Delphi Client aus, die du schön sauber abfangen kannst.

Reinhard Kern 13. Okt 2007 17:59

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Zitat von Jelly
Wenn dem so ist, würde ich das auf jeden Fall von der Datenbank selbst blockieren lassen, wenn da unsinniges Zeug eingetragen wird, denn nur so kannst du sicher sein, dass nicht doch irgendwas eingetragen wird, was nicht soll.
....

Hallo,

dem ganzen Konzept liegt schon ein grosses Vertrauen in die Mitarbeiter zugrunde, wenn jeder seine Arbeitszeitdaten nach Belieben selbst verändern darf - für ein industriell verkaufbares System würde ich grundsätzlich nur An- und Abmelden mit der Systemzeit zulassen, Korrekturen darf nur das Personalbüro (oder der Chef) durchführen. Nur für diese Eingriffe wäre eine Plausibilitätskontrolle notwendig.

Wenn jemand morgens um 7 kommt und feststellt, dass er offiziell seit gestern durcharbeitet, dann ab zum Chef und mit dem Aushandeln, was als gestrige Abmeldung nachgetragen wird. Solange der Sequenzfehler bestehen bleibt, gibts bei der Auswertung eine entsprechende Fehlermeldung.

Grundsätzliche Anmerkung:

Bei einer Zeiterfassung geht es um viel Geld und öfters mal auch um Auseinandersetzungen vorm Arbeitsgericht. Der Programmierer ist also gut beraten, wenn seine Daten und Auswertungen so gerichtsfest wie möglich sind. Mir wäre z.B. wohler, wenn irgendwo ein Drucker mit viel Papier mitläuft und druckt "Müller kommt 2007-10-13 7:45; Meier geht 2007-10-13 11:57;" usw.

Ausserdem bedarf sowas meiner Ansicht nach einer Vereinbarung mit dem Betriebsrat, ist aber nicht mein Fachgebiet.

Gruss Reinhard

guidok 16. Okt 2007 07:38

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Hier interessieren weniger die einzelnen Uhrzeiten sondern das Saldo am Ende. Die Soll-Arbeitszeit ist ja auch in Stunden+Minuten vorgegeben und nicht in einer Uhrzeit.
Klar, für den Arbeitsbeginn und das Arbeitsende kann man mit Datum+Uhrzeit arbeiten. Das macht schon Sinn.
Stimmt natürlich, dass hier eher das Saldo am Ende interessiert. Aber es geht doch in einer DB auch darum Daten nicht unbedingt doppelt und dreifach zu speichern. Mit der Start- und Endzeit kann ich den Saldo berechnen, also muss ich diesen nicht zusätzlich speichern.
Natürlich könnte man aus der Benutzereingabe auch gleich den Saldo speichern und nur diesen speichern, aber damit gehen (evtl.) Informationen verloren, nämlich die Start- und Endzeit und vielleicht brauchst du die irgendwann einmal, um etwas nachzuvollziehen.

Direkten DB-Zugriff würde ich hier nicht als Argument sehen. Der Zugriff soll über ein Frontend erfolgen und fertig.

Guido

stahli 16. Okt 2007 08:33

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Stimmt natürlich, dass hier eher das Saldo am Ende interessiert. Aber es geht doch in einer DB auch darum Daten nicht unbedingt doppelt und dreifach zu speichern. Mit der Start- und Endzeit kann ich den Saldo berechnen, also muss ich diesen nicht zusätzlich speichern.
Natürlich könnte man aus der Benutzereingabe auch gleich den Saldo speichern und nur diesen speichern, aber damit gehen (evtl.) Informationen verloren, nämlich die Start- und Endzeit und vielleicht brauchst du die irgendwann einmal, um etwas nachzuvollziehen.
Na ja, man muss ja mindestens einen "Eingangssaldo" speichern (wenn z.B. ein Beamter neu in unser Amt wechselt und Überstunden mitbringt). Ab dem Zeitpunkt kann man dann das Saldo ständig neu berechnen lassen. Nach 40 Dienstjahren hat das Programm dann aber viel zu tun ;-)
Daher wäre mindestens zum Monatswechsel sinnvoll einen neuen Saldo zu speichern und von diesem aus weiter zu rechnen. Wenn dieser durch einen Verantwortlichen bestätigt ist, können keine rückwirkenden Änderungen (über das Programm) vorgenommen werden.

Ich habe mich darüber hinaus entschlossen, die berechneten Zeiten auch für jeden einzelnen Tag zu speichern. Der Nutzer gibt seine Arbeits-Uhrzeiten (Arbeitsbeginn, Pausenbeginn, Pausenende, Arbeitsende etc.) ein. Das Programm berechnet die Istzeiten und Überstundensaldo... (und zwar immer für den gesamten aktuell eingestellten Monat, ausgehend vom Monats-Eingangssaldo und einen Übertrag zum nächsten Monat).

stahli

mkinzler 16. Okt 2007 08:38

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Grundsatz von relationalen Datenbanken: Mehrfachspeicherungen von daten (Redundanzen) vermeiden!

stahli 16. Okt 2007 08:53

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Ich (als Hobbyprogrammierer) würde das aber nicht als Mehrfachspeicherung ansehen.

Mehrfachspeicherung würde ich so sehen, dass ein Name oder eine Uhrzeit MEHRFACH in der Datenbank abgelegt sind. Das ist ja aber nicht der Fall.

Ich berechne speichere lediglich berechnete Werte in der Datenbank ab und gehe für weitere Berechnungen von diesen aus. Sonst müsste man ja bei jeder Datensatzänderung "unendlich weit" zurück gehen und alles neu ausrechnen.

Und was ist, wenn sich inzwischen Regeländerungen bezüglich der Berechnung ergeben haben oder ein früherer Datensatz verändert wurde?

Wie geht man denn mit solchen berechneten Werten korrekt vor? Soll man die nicht in einer Datenbank speichern dürfen?

stahli

Jelly 16. Okt 2007 08:57

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Die Vorgehensweise ist vielleicht nicht so verkehrt, wenn du dann die alten Daten vor deinem Saldo irgendwann löschst, und stattdessen nur einen Sammelrecord einfügst mit den Übernahmestunden. Kein Mensch wird von dir verlangen, dass du die letzten 40 Jahre deiner Beamtenstunden archivierst.

Öhm... Wieso brauchen Beamten so ein Tool. Ich dacht die machen eh keine Überstunden.
:duck:

stahli 16. Okt 2007 09:05

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
... ja doch, brauchen wir wenn der Wecker kaputt ist, und man länger als bis zum Feierabend schläft ;-)

Ich könnte z.B. jetzt alle Datensätze vor 1899 löschen und das würde die Funktionsweise nicht weiter stören.
Man könnte natürlich auch eine extra Tabelle T_BerechneteWerte einführen. Das hielt ich aber nicht unbedingt für sinnvoll, das es für jeden Tag nur einen Datensatz gibt.

guidok 16. Okt 2007 11:23

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Letztendlich hängt es davon ab, wie die jeweiligen Anforderungen sind. Beim Threadersteller sieht es wohl so aus:

Person X, Tätigkeit A, von, bis
Person X, Tätigkeit B, von, bis
Person Y, Tätigkeit A, von, bis

Ohne jetzt genau zu wissen, wie schnell die Berechnung innerhalb der DB durchgeführt wird, würde ich die Salden aus den "von" und "bis" Zeiten berechnen lassen.

Salomon 17. Okt 2007 09:31

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
@guidok: Genau so siehts jetzt bei mir aus. Ich habe mich nun doch entschieden für die von/bis Felder den MS SQL DateTime Typ zu verwenden. Mein Formular zum Aufnehmen der Zeiten funktioniert jetzt soweit :)


Nun bin ich dabei die Zeitspannen zu Berechenen. (In stunde/min zwischen zwei DateTime Werten) Einige Infos dazu habt ihr ja schon weiter oben aufgeführt.
So ganz klar ist mir das allerdings noch nicht :gruebel:

Zitat:

Die Differenz zweier TDateTime-Werte ist aber kein Datum sondern ein Float-Wert, der die Anzahl der Tage (ink. Dezimalwerten) wiederspiegelt. Insofern ist die Differenz hier 1 + 30/1440, oder 1,020833. Und das ist doch genau das Ergebnis, das wir haben wollen.
Wenn Du das in Minuten umrechnest, musst Du nur mit 1440 multiplizieren und erhälst als Ergebnis 1470. Was willst Du mehr?
Mit welchen Befehl wandel ich den DateTime Wert in einen Time Wert um? Wie ich guidok verstanden habe ist die Differenzberechnung dann wohl einfacher.

stahli 17. Okt 2007 09:39

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Der ganzzahlige Teil von TDateTime enthält den Tag, der Nachkommateil die Stunden, Minuten, Sekunden und Millisekunden (0,5 entspricht 12 Uhr Mittags).

Du kannst die Differenzzeit von DateTime genau so ermitteln wie von Time. Bei Umwandlung in Time musst Du noch beachten, dass Du nicht über einen Tageswechsel hinaus kommst. Sonst funktioniert das ganze natürlich nicht mehr (1:00 Uhr - 23:00 Uhr). Also kannst Du die Zeiten besser einfach aus den TDateTime berechnen.

Die Formatierung der Ausgabe (z.B. "2:45 h") musst Du dann programmseitig übernehmen.

stahli

alzaimar 17. Okt 2007 10:00

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Zitat von Salomon
So ganz klar ist mir das allerdings noch nicht :gruebel:

Zitat:

Die Differenz zweier TDateTime-Werte ist aber kein Datum sondern ein Float-Wert, ....
Mit welchen Befehl wandel ich den DateTime Wert in einen Time Wert um? Wie ich guidok verstanden habe ist die Differenzberechnung dann wohl einfacher.

Also:
1. Mit Delphi
Delphi-Quellcode:
Var
  a,b : TDateTime;
  d : Double;
  m : Integer;

Begin
  a := StrToDateTime('24.10.2007 13:50');
  b := StrToDateTime('26.10.2007 19:19');
  d := b-a; // Delphi kann das
  m := Trunc (1440*d+0.5); // Aufgeerundete Minuten ausrechnen
End;
2. Mit MSSQL

SQL-Code:
Select DateDiff (Minute, ZeitBis, ZeitVon) as DauerInMinuten
From MeineZeiterfassung
Der SQL-Server berechnet sowas 'wupps' mal eben (dazu sind sie ja da).

Ich würde also eine Auswertung, wer wieviel gearbeitet hat, so machen:

SQL-Code:
select Person,
       Sum (DateDiff (Minute, ZeitBis, ZeitVon)) as Arbeitsdauer
from MeineZeiterfassung
Group By Person
Wenn Du nun immer wieder auf die Differenz in Minuten zugreifen willst, dann richte dir in der Datenbank ein 'berechnetes Feld' ein. Dazu gehst Du im Enterprise-Manager von MSSQL in den Designer-Modus der Tabelle, richtest ein Feld 'Dauer' vom Datentyp 'int' ein und weist den Feldeigenschaften (unten) in der Zeile 'Formula' den Wert 'DateDiff (Minute, ZeitBis, ZeitVon)' zu.

Dann siehst du bei einem Select immer die Dauer ;-)

guidok 17. Okt 2007 10:35

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Und mit Hilfe geeigneter SQL-Abfragen kannst du jetzt alle möglichen weiteren Informationen (Kombinationen) aus deinen Daten holen, z.B. Tätigkeitsbeschreibung und Dauer die Person X im Zeitraum von A-B ausgeführt hat usw.

Zum Thema redundante Informationen: Falls zur "Person" noch mehr Informationen gehören, z.B. Personalnummer, Adresse, usw. dann solltest du dafür eine weitere Tabelle anlegen mit eben diesen Daten und in der Zeittabelle anstatt der Person die Personalnummer als Verknüpfungsfeld speichern. Aber das weißt du ja eh...

Salomon 17. Okt 2007 10:42

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Wow, danke euch beiden. Jetzt ist Blick ich da durch :)

Was mich wundert, ist das man bei der Datums/Zeitdifferenz * 1440 Nachkommastellen erhält, obwohl z.B. genau eine halbe Stunde rauskomen müsste. Ich denke das wird wohl an den Millisekunden liegen.
Mit dem Aufrunden wie in alzaimar Code scheint das ganze aber zuverlässig zu funktionieren.

@alzaimar: Die SQL DateDiff Funktion ist ja super :-D Die kann ich für Auswertung wirklich gut gebrauchen. Das Einrichten des Feldes Dauer ist bei mir glaube ich nicht Möglich, da ich die Express Version des Servers nutze. Ansonsten ist das auch eine gute Sache. Hoffen wir mal das mein DB Server für die Berechnungen später schnell genug ist. Sonst muss der aufgerüstet werden, oder ein "vollwertiger" MS SQL Server her ;)

@guidok: Danke für den Hinweis auf weitere Tabellen. Das ganze habe ich auch schon so vor. Es gibt dann noch ein paar weitere Tabellen:

ua.

TB_Activities
TB_ActivityType (z.B. billable, travel holiday) etc.
TB_Users
Tb_Projects (die Zeiten sollen einem User und einem Project zugewiesen werden)

Um die Infos alle wieder per SQL auszuwerten werde ich sicher noch einige Fragen stellen ;)

alzaimar 17. Okt 2007 10:53

Re: Zeiterfassung in DB, generelle Vorgehensweise?
 
Zitat:

Zitat von Salomon
@alzaimar: Einrichten des Feldes Dauer ist bei mir glaube ich nicht Möglich, da ich die Express Version des Servers nutze.

Doch doch, passt scho'. Kukustu;

Delphi-Quellcode:
ALTER TABLE dbo.MeineZeiterfassung ADD   Dauer AS DateDiff(Minute, ZeitVon, ZeitBis),
Einfach ausführen, und schon hast Du die Spalte.

Die Express-Version ist fast genauso gut wie die teure Version. Du müsstest eigentlich die Tools (Enterprise Manager o.ä.) dabei haben. Aber wenn nicht, auch egal. Die Expressversion hat nur Einschränkungen hinsichtlich der Anzahl der CPU (wird maximal eine unterstützt) und -glaube ich- RAM. Aber für deine Anwendung reicht es allemal aus (ist tendenziell sogar ein Overkill).


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:11 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz