Urlaubskalender Multiuserfähig

Moderator: ModerationP

Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 27. Apr 2021, 07:37

Hallo Leute,

es ist mal wieder Euer umfangreiches Fachwissen gefragt. Ich bin gerade dabei eine Urlaubsdatenbank für unser Team zu erstellen. Als Grundlage dafür habe ich im Netz - leider weiß ich nicht mehr wo und von wem die DB war - eine kleine Projekt-Datenbank gefunden, die ich mir schon soweit zurecht gebogen habe. Die DB hänge ich hier auch mit an.

In dem frm_urlaubuebersicht wird die Dauer eines Urlaubs für das gesamte Team angezeigt. Ich möchte aber noch in einem Formular die bisherigen geplanten und genehmigten Urlaube sowie den verfügbaren Resturlaub für jedes Teammitglied einzeln anzeigen. Dazu muss ich ja wissen, welcher User ist es denn gerade, der dort auf die DB schaut. Um das herauszufinden habe ich ein Modul erstellt in das die UserID, Vor- und Nachname sowie das Team gespeichert wird. Auch ein Login-Form gibt es, in dem man sich zur Anwendung "anmeldet" ... So eine richtige Nutzerverwaltung ist das ja nicht, was ich da erstellt habe. Und ich denke, dass wenn sich ein zweiter User anmeldet, die Daten, die in meinen globalen Variablen stehen, von ihm überschrieben werden und ich, bzw. Access, nun nicht mehr weiß, wer gerade in der DB ist und was sehen darf...

Könnt ihr mir folgen? Kann mir da jemand von Euch helfen?

Vielen Dank für Eure Unterstützung.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon Bitsqueezer » 27. Apr 2021, 10:09

Hallo,

ohne mir die Datenbank angesehen zu haben, klingt das für mich so, als ob Du eine einzelne Access-Datenbank auf einem Netzwerklaufwerk für alle zur Verfügung stellst, die dann jeder öffnen kann.

Erst mal sollte, wie üblich, eine Auftrennung in Frontend/Backend erfolgen, so daß nur die Daten in einer gemeinsam genutzten Datei stehen (mal abgesehen davon, daß man das besser auf einem DB-Server unterbringt). Und dann bekommt jeder Nutzer sein eigenes Frontend.

Aber auch bei gemeinsam genutzten Frontend wird ja die Datei lokal in Deinem Access geöffnet, VBA läuft auch lokal, daher müßten sich alle Variablen genauso verhalten, als hättest Du ein eigenes Frontend geöffnet - um eine globale Variable ZWISCHEN Instanzen zu öffnen, müßte ja ansonsten ein aufwendiger Synchronisationsprozess stattfinden bzw. die Variablen im geteilten Frontend auf dem Netzwerklaufwerk irgendwie gespeichert werden - solche Mechanismen wären mir nicht bekannt. Entsprechend ist Deine "globale" Variable nur in Deinem eigenen Access global, sollte also nicht überschrieben werden können von einem anderen User, der nur die gleiche Frontend-Datei gestartet hat.

Ich hoffe, Du denkst auch an die DSGVO wg. Speicherung personenbezogener Daten, erschwerend auch noch, wenn andere Benutzer Informationen über Urlaub von Dritten abrufen können (auch wenn für Urlaubsplanung natürlich irgendwie nötig, sieht die DSGVO halt vor, daß jeder Benutzer damit einverstanden sein muß und auch Widerspruch dagegen einlegen können muß).

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 8276
Registriert: 21. Jun 2007, 12:17

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 27. Apr 2021, 10:29

Hallo Christian,

vielen Dank für Deine Antwort.
Natürlich wird die DB in ein BE und ein FE aufgeteilt, so dass jeder Nutzer sein eigenes FE hat aber alle auf das selbe Backend zugreifen.
Deine Ausführungen zu meinen "globalen" Variablen hat mir sehr geholfen und ich habe mal wieder etwas dazu gelernt.

Was die DSGVO angeht weiß ich darüber bescheid und jeder aus dem Team wird sein OK dazu geben. Das ist schon geklärt. Außerdem wird dieser Kalender nur im Team genutzt, um hier eine Urlaubsplanung für das Team zu ermöglichen.

Jetzt kann ich ja beruhigt weiter machen, mit meinem Teamkalender :)


Nochmals ganz lieben Dank
und schöne Grüße aus Köln


Jörg
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 30. Apr 2021, 08:02

Hallo Leute,

ich bräuchte doch nochmal Eure Hilfe.
In der Datenbank, die ich erstellt habe, sollen ja die Urlaube der Teammitglieder aufgelistet werden. Das klappt leider nur eingeschränkt. Denn hat ein Teammitglied (hier ID 1 / Max und ID 2 / Jupp) z.B. Urlaub vom 12.04. bis 23.04. und dann z.B. am 30.04. noch einen Tag Gleitzeit, zeigt das Formular frm_urlaubuebersicht den Urlaub vom 12.04. bis 23.04. korrekt an aber den einen Tag Gleitzeit (30.04.) zeigt er ab dem 25.04. als Urlaub/GZ an. Ich habe keine Ahnung, warum DateDiff dort so seltsam rechnet.

Teamkalender-Uebersicht.JPG


Hier ist der Code, in dem die Zeitberechnung stattfindet:
Code: Alles auswählen
Public Sub SetProjekt(F As Form, IDP As Long)
On Error GoTo ErrHandler
Dim db     As DAO.Database
Dim rs     As DAO.Recordset
Dim sSQL   As String
Dim i      As Integer
Dim iLast  As Integer
Dim iFirst As Integer

    For i = 1 To 31
        F("D" & i).BackColor = RGB(255, 255, 255)
    Next i
   
    sSQL = " SELECT * FROM abfr_abwesenheit As Q " _
         & " WHERE Month(Q.dDatum) =" & Month(xDate) _
               & " AND Year(Q.dDatum) =" & Year(xDate) _
               & " AND Q.ID_MA =" & IDP _
         & " ORDER BY Q.dDatum;"

    Set db = CurrentDb
    Set rs = db.OpenRecordset(sSQL)
    If rs.RecordCount = 0 Then Exit Sub
        With rs
            .MoveLast: iLast = !T: .MoveFirst: iFirst = !T
    For i = 1 To iLast
        F("D" & i).BorderColor = RGB(18, 48, 76)
    Next i
         For i = iFirst To iLast
         On Error Resume Next
            If DateSerial(Year(xDate), Month(xDate), i) = !dDatum Then
                If !abwesenheit_art = 1 And !genehmigt = True Then
                    F("D" & i).BackColor = RGB(16, 179, 38)
                ElseIf !abwesenheit_art = 2 And !genehmigt = True Then
                    F("D" & i).BackColor = RGB(22, 234, 52)
                ElseIf !abwesenheit_art = 3 And !genehmigt = True Then
                    F("D" & i).BackColor = RGB(10, 112, 24)
                ElseIf !abwesenheit_art = 3 And !genehmigt = True Then
                    F("D" & i).BackColor = RGB(10, 112, 24)
                ElseIf !abwesenheit_art = 4 And !genehmigt = True Then
                    F("D" & i).BackColor = RGB(17, 184, 41)
                ElseIf !genehmigt = False Then
                    F("D" & i).BackColor = RGB(227, 184, 14)
                Else
                    F("D" & i).BackColor = RGB(255, 255, 255)
                End If
                'F("D" & i).BackColor = vbRed
            End If
         Err = 0
        .MoveNext
    Next i
    End With
ExitErrHandler:
    Set rs = Nothing
    Exit Sub
ErrHandler:
    'MsgBox Err.Description
    Resume ExitErrHandler
End Sub


Leider steige ich nicht so ganz durch, wie das berechnet wird. Die Datenbank habe ich auch mal angehängt und einen Screenshot, des Formulars "frm_urlaubuebersicht" ...
Ich bin für jede Hilfe dankbar.

LG


Jörg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon Bitsqueezer » 30. Apr 2021, 11:22

Hallo,

das ist der böse Reinfall mit "On Error Resume Next".

Code: Alles auswählen
On Error Resume Next
If FrageFestplatteFormatieren = vbYes Then
   FestplatteFormatieren
End If


Was passiert wohl, wenn "FrageFestplatteFormatieren" einen Fehler produziert?

Nicht viel besser ist es, im Errorhandler unten ohne Rückmeldung die Prozedur zu verlassen.

Tatsächlich wird ein Fehler produziert und der verursacht genau das: Es wird in eine Zeile gesprungen, die nicht ausgeführt werden sollte.

Problem ist, Deine Abfrage gibt nicht für JEDEN Tag ein Datum raus, sondern nur für die Tage, die einen Eintrag haben. Entsprechend ist die Abfrage für z.B. ID 3 nach dem 7.4. ohne Daten, hat aber noch einen Eintrag für den 13.4., der dann noch gelesen wird, aber im Vergleich natürlich nicht zutrifft, weil die Schleife gerade nach dem 8.4. fragt. Für alle weiteren Tage gibt es keine Daten und so wird daraus ein "Kein aktueller Datensatz"-Fehler.

Ersetze die Abfrage "abfr_abwesenheit" gegen diese:
Code: Alles auswählen
PARAMETERS StartDatum DATETIME
   ,EndDatum DATETIME
   ,MaID Long;

SELECT D1.dDatum
   ,Nz(ABW1.ID_MA, 0) AS ID_MA
   ,ABW1.vorname
   ,Nz(ABW1.abwesenheit_art, 0) AS abwesenheit_art
   ,ABW1.genehmigt
FROM tblDatum AS D1
LEFT JOIN (
   SELECT M.ID_MA
      ,M.vorname
      ,ABW.genehmigt
      ,ABW.abwesenheit_art
      ,D.dDatum AS Datum_Abwesenheit
      ,Day([dDatum]) AS T
   FROM tblDatum AS D
      ,tbl_mitarbeiter AS M
   INNER JOIN tbl_abwesenheit AS ABW ON M.ID_MA = ABW.id_ma
   WHERE D.dDatum BETWEEN ABW.von AND ABW.bis
    AND ABW.ID_MA = MaID
   ) AS ABW1 ON D1.dDatum = ABW1.Datum_Abwesenheit
WHERE D1.dDatum BETWEEN [StartDatum] AND [EndDatum]
ORDER BY D1.dDatum
   ,ABW1.ID_MA;


Und Deine Prozedur gegen diese:
Code: Alles auswählen
Public Sub SetProjekt(F As Form, IDP As Long)
    On Error GoTo ErrHandler
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim i As Long
    Dim qd As DAO.QueryDef


    For i = 1 To 31
        F("D" & i).BackColor = RGB(255, 255, 255)
        F("D" & i).BorderColor = RGB(18, 48, 76)
    Next i

    Set db = CurrentDb
    Set qd = db.QueryDefs("abfr_abwesenheit")
    With qd
        .Parameters("StartDatum") = DateSerial(Year(xDate), Month(xDate), 1)
        .Parameters("EndDatum") = DateAdd("m", 1, DateSerial(Year(xDate), Month(xDate), 1)) - 1
        .Parameters("MaID") = IDP
        Set rs = qd.OpenRecordset
    End With

    With rs
        .MoveFirst
        Do Until .EOF
            If !abwesenheit_art = 1 And !genehmigt = True Then
                F("D" & Day(!dDatum)).BackColor = RGB(16, 179, 38)
            ElseIf !abwesenheit_art = 2 And !genehmigt = True Then
                F("D" & Day(!dDatum)).BackColor = RGB(22, 234, 52)
            ElseIf !abwesenheit_art = 3 And !genehmigt = True Then
                F("D" & Day(!dDatum)).BackColor = RGB(10, 112, 24)
            ElseIf !abwesenheit_art = 3 And !genehmigt = True Then
                F("D" & Day(!dDatum)).BackColor = RGB(10, 112, 24)
            ElseIf !abwesenheit_art = 4 And !genehmigt = True Then
                F("D" & Day(!dDatum)).BackColor = RGB(17, 184, 41)
            ElseIf !genehmigt = False Then
                F("D" & Day(!dDatum)).BackColor = RGB(227, 184, 14)
            Else
                F("D" & Day(!dDatum)).BackColor = RGB(255, 255, 255)
            End If
           
            .MoveNext
        Loop
    End With
   
ExitErrSetProjekt:
    If Not rs Is Nothing Then
        rs.Close
    End If
    Set rs = Nothing
    Set qd = Nothing
    Set db = Nothing
    Exit Sub

ErrHandler:
    MsgBox Err.Description
    Resume ExitErrSetProjekt
    'Debug
    Resume

End Sub


Dann klappt es auch mit Deinem Urlaubsformular.

Noch verbessern könnte man hier, der Tabelle "tbl_abwesenheitart" gleich auch die gewünschte Farbe hinzuzufügen, die man dann mit in die Abfrage nehmen könnte, damit erspart man sich das ganze If-Gedöns. Außerdem kannst Du die Farbe dann per Tabelle anpassen, ohne Neukodierung.

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 8276
Registriert: 21. Jun 2007, 12:17

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 30. Apr 2021, 11:57

Hallo Christian,

vielen Dank für Deine Unterstützung. Ich baue das mal in meine DB ein.
Der Tipp mit der Farbe in der Tabelle tbl_abwesenheitart ist super. Das hilft wirklich und hält den Code schlanker.

Ich noch viel lernen muss :)

nochmals vielen Dank und ein schönes Wochenende


LG


Jörg
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 03. Mai 2021, 06:39

Hallo Leute,

Dank Christians Hilfe, bin ich ein gutes Stück weitergekommen, mit dem Teamkalender.
Aber leider bekomme ich das SQL für die Abwesenheitsabfrage nicht hin.

Ich habe - wie Christian empfohlen hat, die Tabelle "tbl_abwesenheitsart" um das Feld "farbe" (in dem der RGB-Wert gespeichert wird) erweitert. Aber leider bekomme ich das SQL nicht hin, um die Farbe der Abwesenheit dann auch mit der Abfrage in das Übersichtsformular bekomme. Und dort dann den IF-Else-Block sparen kann.
Hier ist mein geändertes SQL:
Code: Alles auswählen
PARAMETERS StartDatum DATETIME
   ,EndDatum DATETIME
   ,MaID Long;

SELECT D1.dDatum
   ,Nz(ABW1.ID_MA, 0) AS ID_MA
   ,ABW1.vorname
   ,Nz(ABW1.abwesenheit_art, 0) AS abwesenheit_art
   ,ABW1.genehmigt
   ,ABWA.farbe
FROM tblDatum AS D1
LEFT JOIN (
   SELECT M.ID_MA
      ,M.vorname
      ,ABW.genehmigt
      ,ABW.abwesenheit_art
      ,ABWA.farbe
      ,D.dDatum AS Datum_Abwesenheit
      ,Day([dDatum]) AS T
   FROM tblDatum AS D
      ,tbl_mitarbeiter AS M
      ,tbl_abwesenheitsart AS ABWA
   INNER JOIN tbl_abwesenheitsart AS ABWA ON ABW.abwesenheit_art = ABWA.ID_Abwesenheit
   INNER JOIN tbl_abwesenheit AS ABW ON M.ID_MA = ABW.id_ma   
   WHERE D.dDatum BETWEEN ABW.von AND ABW.bis
    AND ABW.ID_MA = MaID
   ) AS ABW1 ON D1.dDatum = ABW1.Datum_Abwesenheit
WHERE D1.dDatum BETWEEN [StartDatum] AND [EndDatum]
ORDER BY D1.dDatum
   ,ABW1.ID_MA;

Ich bekomme immer Fehlermeldungen z.B. diese hier
Fehlermeldung_SQL_Abwesenheit.JPG


Könnt ihr mir hier bitte nochmal helfen? Vielen Dank, für Eure Unterstützung.


LG


Jörg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon Bitsqueezer » 03. Mai 2021, 08:47

Hallo,

versuch's mal damit:

Code: Alles auswählen
PARAMETERS StartDatum DATETIME
   ,EndDatum DATETIME
   ,MaID Long;

SELECT D1.dDatum
   ,Nz(ABW1.ID_MA, 0) AS ID_MA
   ,ABW1.vorname
   ,Nz(ABW1.abwesenheit_art, 0) AS abwesenheit_art
   ,ABW1.genehmigt
   ,ABW1.farbe
FROM tblDatum AS D1
LEFT JOIN (
   SELECT M.ID_MA
      ,M.vorname
      ,ABW.genehmigt
      ,ABW.abwesenheit_art
      ,D.dDatum AS Datum_Abwesenheit
      ,Day([dDatum]) AS T
      ,ABWA.farbe
   FROM tblDatum AS D
      ,(tbl_mitarbeiter AS M INNER JOIN tbl_abwesenheit AS ABW ON M.ID_MA = ABW.id_ma)
   INNER JOIN tbl_abwesenheitsart AS ABWA ON ABW.abwesenheit_art = ABWA.ID_Abwesenheit
   WHERE D.dDatum BETWEEN ABW.von
         AND ABW.bis
      AND ABW.ID_MA = MaID
   ) AS ABW1 ON D1.dDatum = ABW1.Datum_Abwesenheit
WHERE D1.dDatum BETWEEN [StartDatum]
      AND [EndDatum]
ORDER BY D1.dDatum
   ,ABW1.ID_MA;


Leider hat Access SQL eine ziemlich kranke JOIN-Klammerungsmethode, die man nicht nachvollziehen kann, weswegen man die Abfragen hier eigentlich nur mit dem Abfrageeditor erstellen kann.

In T-SQL hätte es auch ohne die Klammern geklappt. Darüber hinaus muß in Deiner Hauptabfrage statt "ABWA" "ABW1" stehen.

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 8276
Registriert: 21. Jun 2007, 12:17

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 03. Mai 2021, 10:24

Hallo Christian,

vielen Dank, für Deine erneute Unterstützung und Hilfe.
Ich bekomme immer die Fehlermeldung "Typen unverträglich".
In der Tabelle "tbl_abwesenheitsart" habe ich ein Feld "farbe" in dem steht als "kurzer Text" z.B. "RGB(16, 179, 38)" drin.
In der Prozedur steht dann folgendes:
Code: Alles auswählen
If IsNull(!farbe) Then
                color = RGB(255, 255, 255)
            ElseIf !genehmigt = False Then
                color = RGB(227, 184, 14)
            Else
                color = !farbe
            End If
            F("D" & Day(!dDatum)).BackColor = color

"color" ist als String deklariert....
IsNull frage ich deshalb ab, weil ich zuerst immer die Fehlermeldung "Unzulässige Verwendung von Null" erhalten habe

Wenn ich nun color als Messagebox ausgeben lasse, steht da eine seltsame lange Zahl drin - also nicht z.B. "RGB(255, 255, 255)"...
MessageBoxColor.JPG


Was mache ich denn falsch? Würde es helfen, die RGB-Werte jeweils in ein eigenes Feld zu schreiben?

Die Abfrage jedenfalls zeigt das Feld farbe korrekt an.


Besten Dank für Eure Unterstützung

LG


Jörg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47

Re: Urlaubskalender Multiuserfähig

Beitragvon Bitsqueezer » 03. Mai 2021, 10:47

Hallo,

das entspricht der Farbe weiß:

Code: Alles auswählen
?rgb(255,255,255)
 16777215


und dürfte der Wert sein, den "color" vorher bereits hatte. Das ist die Long-Entsprechung der drei Byte-Werte.
Code: Alles auswählen
?&HFFFFFF
 16777215


Wie kommst Du darauf, daß ein so gespeicherter String von VBA als Funktion ausgeführt werden kann? Du versuchst, einer Long-Variablen einen Text zuzuordnen, der auch "Mickymaus" lauten könnte. Entsprechend der Typfehler.

Wenn Du es unbedingt schon so speichern möchtest (warum nicht einfach die Zahl aus der RGB-Funktion als Long?), dann kannst Du das so verwenden:

Code: Alles auswählen
color = Eval(Nz(!farbe,RGB(255,255,255)))


Mit Nz brauchst Du dann auch nicht mehr IsNull zu testen.

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 8276
Registriert: 21. Jun 2007, 12:17

Re: Urlaubskalender Multiuserfähig

Beitragvon joergqvc » 03. Mai 2021, 11:27

Hallo Christian,

vielen Dank für die Lösung. Jetzt funktioniert alles einwandfrei.

Besten Dank

LG

Jörg
joergqvc
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 49
Registriert: 14. Jan 2021, 11:47


Zurück zu Access Forum (provisorisch)

Wer ist online?

Mitglieder in diesem Forum: Beaker s.a. und 6 Gäste