Ideensammlung Urlaubsplaner

  • VB.NET
  • .NET (FX) 4.0

Es gibt 44 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.

    tragl schrieb:

    Ich hab dir das Projekt mal angehangen, würdest du dir das mal anschauen, bevor ich einer der Helpers zerschieße?
    Nachwievor kannste dich scheints nicht mit SolutionExplorer - OpenSource anfreunden, was?
    Damit kannste mit 1 Click ein "smartes Zip" anlegen, numeriert, und ohne Binaries.
    Einmal draufklicksen, und du kannst deine Sources getrost verwüsten, ohne Angst vor unwiederbringlichen Verlusten.

    (Zb Binaries in auf VBP hochgeladenen Zips sind eiglich nicht erlaubt.)



    Ich hab jetzt die Spalte Bundesland.Bundesland in Bundesland.Name umbenannt - dann gehts.
    Achtung! Dazu musste 1) Backup machen 2) in beiden frmBundesland einen DataPropertyName ändern 3) in dlgBundesland das TextboxBinding ändern - jeweils inne Designer.vb

    Warum er da rumzickt habich nicht herausgefunden.

    Man könnte EditCurrent auch mal mit Kürzel.Kürzel probieren - wenner da auch rumzickt, dann kommt er wohl nicht klar, wenn er eine Spalte binden soll mit demselben Namen wie die Tabelle.
    Das wäre ein ziemlich blöder Bug im BindungsSystem.



    Übrigens rate ich ja immer davon ab, Umlaute innerhalb von Bezeichnern zu verwenden - auch in DatenObjekt-Bezeichnern.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Nachwievor kannste dich scheints nicht mit SolutionExplorer - OpenSource anfreunden, was?
    Damit kannste mit 1 Click ein "smartes Zip" anlegen, numeriert, und ohne Binaries.
    Einmal draufklicksen, und du kannst deine Sources getrost verwüsten, ohne Angst vor unwiederbringlichen Verlusten.

    (Zb Binaries in auf VBP hochgeladenen Zips sind eiglich nicht erlaubt.)


    Die Exe-Version davon läuft nicht, bin grad dabei das neu zu compilen. Kann man diesen Setup-Mist nicht weglassen, sodass man direkt das fertige Programm erhält?


    Edit: Läuft nicht...


    Bzgl. der Tabellen schau' ich gleich mal. Umlaute nehm ich raus und benenne die Spalten anders als die Tabelle
    Edit: Neuanlage klappt ohne Fehler - scheint tatsächlich mit der Benamung zusammenzuhängen, jedoch wird nix gespeichert. Beispiel: Standort -> Neu -> ich geb' alles ein, DGV bleibt leer und die XML auch :(
    Kürzel geht immernoch nicht, trotz Umbenennung der Spalte und Umbenennung von Ü auf UE
    Was nu' schon wieder?

    Edit2: Bei EditCurrent funzt das. Einen existierenden Eintrag kann man editieren, die Änderungn sind auch dann direkt im DGV zu sehen und speicherbar. Bei EditNew passiert nix .. bin
    am Überlegen das Projekt komplett neu aufzusetzen - irgendwo ist da der Wurm drin
    Edit3: Bringt auch nix, macht in einem neuen Projekt das gleiche Theater

    Dateien
    • Planer.zip

      (1,14 MB, 80 mal heruntergeladen, zuletzt: )
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „tragl“ ()

    tragl schrieb:

    Kann man diesen Setup-Mist nicht weglassen, sodass man direkt das fertige Programm erhält?

    Ich wusste garnet, dass da iwas mit Setup drinne ist.
    Normalerweise sucht man die *.sln - Datei einer Solution, und öffnet sie per Doppelklick im VisualStudio.
    Dann F5 drücken und es kompiliert und läuft.

    Vielleicht verbirgt dein DateiBrowser DateiEndungen - das macht es natürlich nicht einfacher, die *.sln - Datei zu finden.

    So sieht das in meim DateiBrowser aus, bei dem das Verbergen von DateiEndungen deaktiviert ist.



    "passiert garnichts" stimmt ja nicht - es öffnet sich durchaus das richtige Form, mit einem neuen, leeren Datensatz.
    Entferne in dlgBundesland das form_Closing, und vereinfache frmBundesland:

    VB.NET-Quellcode

    1. Case sender Is tsNeu
    2. bsBundesland.EditNew(Of dlgBundeslandDetail)
    3. 'neuerEintrag()
    4. End Select
    kein CheckChanges, kein Reload aufrufen.
    Dann kommt immerhin der neue Datensatz auch ins Dataset (wenn auch er dann noch nicht auf Platte ist).

    Hintergrund: .EditItem arbeitet nicht auf einer DataTable, sondern stöpselt des Dialogs Datasource auf ein einzelnes DataRowView um.
    Erst wenn .EditItem weiter durchläuft wird mit bs2.EndEdit der Datensatz in die BindingSource übernommen.
    Wenn du aber zuvor im _Closing Dataset.AcceptChanges ausgeführt hast, hat bs2 bereits .CancelEdit ausgeführt, und der neue Datensatz wird verworfen.
    Weil AcceptChanges cancelt alle offenen Bearbeitungsvorgänge angebundener BindingSources.

    Das ist ja die Absicht von diesem Umstand mittm DataRowView: Dass man das Editieren mit CancelEdit auch verwerfen kann.

    Ah - guck: So gehts auch, wie du's gedacht hast:

    VB.NET-Quellcode

    1. Public Class dlgBundeslandDetail
    2. Private Sub dlgBundeslandDetail_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    3. If Me.DialogResult <> DialogResult.OK Then Return
    4. bsBundeslandDetail.EndEdit()
    5. dtsPlaner.dts.SaveDts(Me)
    6. End Sub
    7. End Class

    Wie gesagt, wenn das ein Pattern werden soll, dass du beim Schliessen eines Dialogs immer Saven tust, dann täte ich mir eine ShowDetailDialog-Methode basteln, damit man nicht in jedem DetailDialog ein Form_Closing schreiben muss.
    Es geht ja nur darum, wenn .EditNew Dialog.Ok return, dann ein .SaveDts() aufzurufen.

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Manchmal steht man sich auch einfach auf dem Schlauch... :|
    Mit EndEdit klappt nu wieder alles :thumbup:

    Mit Patterns hab' ich noch nix am Hut gehabt - wird also schwer, das Einzige was ich derzeit hinbekommen würde wäre
    mir eine Sub zu bauen, die das alles abhandelt. Dazu müsste ich aber in FormClosing auf die Sub verweisen - dann kann ich's auch so
    machen wie bis jetzt auch
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Mit "Pattern bei dir" meine ich eben Pattern bei dir - also dass du es bestimmst, dass in deinen Anwendungen es immer, oder zumindest normalerweise so laufen soll:
    "Wenn DetailDialog mit DialogResult.Ok schliesst, soll das Dataset abgespeichert werden".
    Das wäre dann der "tddP" - der "Tragl-DetailDialog-Pattern".

    tragl schrieb:

    das Einzige was ich derzeit hinbekommen würde wäre
    mir eine Sub zu bauen, die das alles abhandelt. Dazu müsste ich aber in FormClosing auf die Sub verweisen
    Sub bauen ist richtig - aber du musst nicht ins FormClosing grabschen.
    Deine Sub kann einfach mein .EditNew aufrufen, und wenn dieses Dialog.Ok returnt, dann speicherste halt das Dataset.
    Hab ich so eingerichtet:

    VB.NET-Quellcode

    1. Imports Planer.dtsPlaner
    2. Public Class Forms
    3. Public Shared Sub ShowDataDialogNew(Of T As {Form, New})(BS As BindingSource)
    4. Using dlg As New T
    5. dts.CheckDtsChanges(dlg)
    6. dts.Register(dlg, True)
    7. ControlStyling.StyleControls(dlg)
    8. BS.EditNew(Of T)
    9. If dlg.ShowDialog() = DialogResult.OK Then dts.SaveDts(dlg)
    10. dts.ReloadDts()
    11. End Using
    12. End Sub
    13. Public Shared Sub ShowDataDialogEdit(Of T As {Form, New})(BS As BindingSource)
    14. Using dlg As New T
    15. dts.CheckDtsChanges(dlg)
    16. dts.Register(dlg, True)
    17. ControlStyling.StyleControls(dlg)
    18. BS.EditCurrent(Of T)
    19. If dlg.ShowDialog() = DialogResult.OK Then dts.SaveDts(dlg)
    20. dts.ReloadDts()
    21. End Using
    22. End Sub
    23. Public Shared Sub ShowDialog(Of T As {Form, New})()
    24. Using dlg As New T
    25. ControlStyling.StyleControls(dlg)
    26. If dlg.ShowDialog() = DialogResult.OK Then My.Settings.Save()
    27. End Using
    28. End Sub
    29. End Class


    Aufruf mach' ich so:

    VB.NET-Quellcode

    1. Forms.ShowDataDialogNew(Of dlgPlanDetail)(bsPlan)

    VB.NET-Quellcode

    1. Forms.ShowDataDialogEdit(Of dlgPlanEditDetail)(bsPlan)


    allerdings werden die DialogForms 2x aufgerufen bzw. nach dem Schließen eines Dialogs kommt der gleiche nochmal...
    Hab aber in deinem EditNew / EditCurrent nix dazu gefunden...
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Logisch, dass der Dialog zweimal öffnet - mein .EditNew erstellt sich eine Instanz und öffnet sie, und wenn du auch eine erstellst und öffnest, dann ist das zweimal.

    probierma einfach so wie ich gesagt hab
    Deine Sub kann einfach mein .EditNew aufrufen, und wenn dieses Dialog.Ok returnt, dann speicherste halt das Dataset.

    VB.NET-Quellcode

    1. Public Class Forms
    2. Public Shared Sub ShowDataDialogNew(Of T As {Form, New})(BS As BindingSource)
    3. If BS.EditNew(Of T) = DialogResult.OK Then dts.SaveDts(Nothing)
    4. End Sub
    5. Public Shared Sub ShowDataDialogEdit(Of T As {Form, New})(BS As BindingSource)
    6. If BS.EditCurrent(Of T) = DialogResult.OK Then dts.SaveDts(Nothing)
    7. End Sub
    8. End Class
    Dazu musste aber dts.SaveDts noch minimal anpassen - dasses bei Nothing nicht abschmiert.

    (Und bitte aufhören mit dem ständigem Dts.ReloadDts())



    Hmm - jetzt ist da das ControlStyling rausgeflogen.
    Innem annern Thread habich ja eine Verbesserung von .EditNew/Current gepostet - damit könnte man das lösen mit dem ControlStyling:

    VB.NET-Quellcode

    1. Public Class Forms2
    2. Public Shared Sub ShowDataDialogNew(Of T As {Form, New})(BS As BindingSource)
    3. Using dlg = New T
    4. ControlStyling.StyleControls(dlg)
    5. If BS.EditNew(dlg) = DialogResult.OK Then dts.SaveDts(dlg)
    6. End Using
    7. End Sub
    8. Public Shared Sub ShowDataDialogEdit(Of T As {Form, New})(BS As BindingSource)
    9. Using dlg = New T
    10. ControlStyling.StyleControls(dlg)
    11. If BS.EditCurrent(dlg) = DialogResult.OK Then dts.SaveDts(dlg)
    12. End Using
    13. End Sub
    14. End Class
    So musste auch SaveDts nicht anpassen, aber dafür musste meine Verbesserlichung suchen und einbasteln.

    Ach - hier isseja:
    Verbesserlichung

    VB.NET-Quellcode

    1. ''' <summary> editiert bs.Current im angegebenen Dialog-Form. </summary>
    2. <Extension()>
    3. Public Function EditNew(bs As BindingSource, dlg As Form) As DialogResult
    4. EnsureValidFKDefaults(bs)
    5. Return EditItem(bs, bs.AddNew, dlg)
    6. End Function
    7. ''' <summary> editiert bs.Current im angegebenen Dialog-Form. </summary>
    8. <Extension()>
    9. Public Function EditNew(Of TDialog As {Form, New})(bs As BindingSource) As DialogResult
    10. Using dlg = New TDialog
    11. Return bs.EditNew(dlg)
    12. End Using
    13. End Function
    14. ''' <summary> stellt in den FremdschlüsselSpalten DefaultValues sicher, die auf existierende ParentRows verweisen </summary>
    15. Private Sub EnsureValidFKDefaults(bs As BindingSource)
    16. For Each rl As DataRelation In bs.DataTable.ParentRelations
    17. Dim defaultValues = rl.ParentColumns.Select(Function(clmn) clmn.DefaultValue).ToArray
    18. Dim rwDefaultParent = rl.ParentTable.FindX(rl.ParentColumns, defaultValues)
    19. If rwDefaultParent IsNot Nothing Then Continue For ' es gibt bereits eine Default-ParentRow
    20. rwDefaultParent = rl.ParentTable.All.FirstOrDefault ' ansonsten die nächstbeste
    21. If rwDefaultParent Is Nothing Then Throw New InvalidOperationException("es kann keine gültige Default-ParentRow gefunden werden.")
    22. For i = 0 To rl.ParentColumns.Length - 1
    23. rl.ChildColumns(i).DefaultValue = rwDefaultParent(rl.ParentColumns(i))
    24. Next
    25. Next
    26. End Sub
    27. ''' <summary> editiert bs.Current im angegebenen Dialog-Form. </summary>
    28. <Extension()>
    29. Public Function EditCurrent(bs As BindingSource, dlg As Form) As DialogResult
    30. Return EditItem(bs, bs.Current, dlg)
    31. End Function
    32. ''' <summary> editiert bs.Current im angegebenen Dialog-Form. </summary>
    33. <Extension()>
    34. Public Function EditCurrent(Of TDialog As {Form, New})(bs As BindingSource) As DialogResult
    35. Using dlg = New TDialog
    36. Return bs.EditCurrent(dlg)
    37. End Using
    38. End Function
    39. Private Function EditItem(bs As BindingSource, currentOrNewItem As Object, dlg As Form) As DialogResult
    40. Dim tb = DirectCast(currentOrNewItem, DataRowView).Row.Table
    41. tb.DataSet.Register(dlg, False)
    42. Dim allCtls = New GetChilds(Of Control)(Function(ctl) ctl.Controls).AllAsList(dlg)
    43. Dim bindFlags As BindingFlags = BindingFlags.Instance Or BindingFlags.Public _
    44. Or BindingFlags.NonPublic Or BindingFlags.GetField
    45. For Each ctl In allCtls.Where(Function(c) TypeOf c Is ContainerControl AndAlso TypeOf c Is Form OrElse TypeOf c Is UserControl)
    46. For Each fld In ctl.GetType.GetFields(bindFlags).Where(Function(f) f.FieldType = GetType(BindingSource))
    47. Dim bs2 = DirectCast(fld.GetValue(ctl), BindingSource)
    48. If bs2 Is Nothing Then Continue For
    49. If tb Is bs2.DataTable Then
    50. bs2.DataSource = currentOrNewItem
    51. EditItem = dlg.ShowDialog()
    52. If EditItem = Windows.Forms.DialogResult.OK Then
    53. bs2.EndEdit()
    54. bs.ResetCurrentItem() 'den von der anneren BS geänderten Datensatz neu einlesen.
    55. Else
    56. bs.CancelEdit()
    57. End If
    58. Exit Function
    59. End If
    60. Next
    61. Next
    62. Throw New Exception("es konnte keine geeignete BindingSource gefunden werden.")
    63. End Function
    Äh - ungetestet

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ist jetzt so geändert - normalerweise probier' ich so spirenzchen immer, diesmal nicht (Mit dem If BS.EditNew(Of T) = DialogResult.OK Then dts.SaveDts(Nothing) z.B.)

    VB.NET-Quellcode

    1. Imports Planer.dtsPlaner
    2. Public Class Forms
    3. Public Shared Sub ShowDataDialogNew(Of T As {Form, New})(BS As BindingSource)
    4. Using dlg = New T
    5. dts.CheckDtsChanges(dlg)
    6. ControlStyling.StyleControls(dlg)
    7. If BS.EditNew(Of T) = DialogResult.OK Then dts.SaveDts(dlg)
    8. End Using
    9. End Sub
    10. Public Shared Sub ShowDataDialogEdit(Of T As {Form, New})(BS As BindingSource)
    11. Using dlg As New T
    12. dts.CheckDtsChanges(dlg)
    13. ControlStyling.StyleControls(dlg)
    14. If BS.EditCurrent(Of T) = DialogResult.OK Then dts.SaveDts(dlg)
    15. End Using
    16. End Sub
    17. Public Shared Sub ShowDialog(Of T As {Form, New})()
    18. Using dlg As New T
    19. ControlStyling.StyleControls(dlg)
    20. If dlg.ShowDialog() = DialogResult.OK Then My.Settings.Save()
    21. End Using
    22. End Sub
    23. End Class


    ErfinderDesRades schrieb:

    Hmm - jetzt ist da das ControlStyling rausgeflogen.
    Innem annern Thread habich ja eine Verbesserung von .EditNew/Current gepostet - damit könnte man das lösen mit dem ControlStyling:

    Die geänderte Version benutz' ich ja :)

    ErfinderDesRades schrieb:

    (Und bitte aufhören mit dem ständigem Dts.ReloadDts())

    Tja, wenn das Wörtchen "wenn" nicht wäre....

    Warum ich das verwende:
    Beispiel ohne ReloadDts

    Der "sample-eintrag" anhand der Standard-Einträge bleibt drin.

    Bei der alten Dialog-Aufruf-Variante von mir mit dem ReloadDts konnte ich das umgehen - hast du eine Lösung parat?
    Dateien
    • Planer00.zip

      (161,51 kB, 77 mal heruntergeladen, zuletzt: )
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    Dassisn Bug, der muss behoben werden.
    ReLoad ist nicht dazu da - und hat auch Nebenwirkungen.
    (Etwa bei einem Reload geht die Selection flöten, weil ja alle Daten gelöscht und neu eingelesen werden.)

    Ein logischer Fehler ist schomal, dass wenn der Filter auf einem bestimmten Mitarbeiter sitzt, dass du im DetailDialog dann einen anderen anwählen können willst - vielleicht führt das ja zu dem komischen Verhalten.
    Sieht so aus - wenn ich den Filter deaktiviere scheint mir nix komisch.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Der Filter im DgvForm ist nu für die Übersicht gedacht - dass er die Kriterien mit in den DetailDialog nimmt, wäre
    eine nette Geste - aber nicht zwingend notwendig.

    Dass der - ich nenn' ihn mal "Sample-Eintrag" mit gespeichert wird ist doof
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    ErfinderDesRades schrieb:

    ich halte für möglich, dasses doch zwingend notwendig ist.
    Habs aber bislang nur soweit untersucht, dass eben wenn kein Filter besteht, dass dann der Fehler nicht auftritt.

    Dann sollten wir mal gucken, ob wir das hin bekommen.
    Ich kann ggf. heute abend die "alten" Helpers mal testen - die liefen ja auch, es musste nur eben ein adäquater Eintrag in den Tabellen sein und die Default-Values müssen halt passen.
    Edit: bringt nix, auch ohne EnsureValidFKDefaults(bs) kommt der "Sample-Eintrag" mit
    Edit: Der Bug muss irgendwo in dem Code von "dlgPlanDetail" stecken, bei allen anderen DetailForms kommt kein Standard-Eintrag mit (da wird auch kein FormClosing mehr behandelt..., nur hier)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub dlgPlanDetail_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    2. If Me.DialogResult <> DialogResult.OK Then Return
    3. Dim startDatum = Date.Parse(dtbVon.Text).Date
    4. Dim endDatum = Date.Parse(dtbBis.Text).Date
    5. If Not startDatum > endDatum Then
    6. Dim datumDifferenz = (endDatum - startDatum).TotalDays
    7. Dim rwMitarbeiter = bsCmbMitarbeiter.At(Of MitarbeiterRow)
    8. Dim rwPlanStatus = bsCmbSatus.At(Of PlanStatusRow)
    9. If datumDifferenz > 14 Then
    10. If msgQuestionWarning($"Der Datumsbereich beträgt {datumDifferenz.ToString} Tage, wirklich weitermachen?") = DialogResult.No Then Return
    11. End If
    12. Dim loopDatum = startDatum
    13. Do While loopDatum < endDatum.AddDays(1)
    14. Dim ft = GetFeiertag(loopDatum)
    15. For Each rwPlan In dts.Plan
    16. If rwPlan.Datum = loopDatum Then
    17. If rwPlan.MitarbeiterID = rwMitarbeiter.ID Then
    18. msgInformation($"Es existiert schon ein Eintrag für den {loopDatum.ToShortDateString}")
    19. Return
    20. End If
    21. End If
    22. Next
    23. Select Case True
    24. Case cbWochenende.Checked = True And cbFeiertag.Checked = True
    25. If loopDatum.DayOfWeek <> DayOfWeek.Saturday And loopDatum.DayOfWeek <> DayOfWeek.Sunday Then
    26. If ft = Feiertag.KeinFeiertag Then
    27. dts.Plan.AddPlanRow(loopDatum, rwMitarbeiter, rwPlanStatus, BemerkungTextBox.Text)
    28. End If
    29. End If
    30. Case cbWochenende.Checked = True
    31. If loopDatum.DayOfWeek <> DayOfWeek.Saturday And loopDatum.DayOfWeek <> DayOfWeek.Sunday Then
    32. dts.Plan.AddPlanRow(loopDatum, rwMitarbeiter, rwPlanStatus, BemerkungTextBox.Text)
    33. End If
    34. Case cbFeiertag.Checked = True
    35. If ft = Feiertag.KeinFeiertag Then
    36. dts.Plan.AddPlanRow(loopDatum, rwMitarbeiter, rwPlanStatus, BemerkungTextBox.Text)
    37. End If
    38. Case Else
    39. dts.Plan.AddPlanRow(loopDatum, rwMitarbeiter, rwPlanStatus, BemerkungTextBox.Text)
    40. End Select
    41. loopDatum = loopDatum.AddDays(1)
    42. Loop
    43. Else
    44. msgInformation("Datum VON muss kleiner BIS sein!")
    45. dtbVon.SelectAll()
    46. e.Cancel = True
    47. End If
    48. End Sub

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „tragl“ ()

    Update vom 05.05.2020:
    Es hat sich mal wieder Einiges im Planer-Projekt getan (ja - Planer-Projekt, denn es könnte auch schon bald als Dienst-/Schicht-/Urlaubsplaner genutzt werden ;) ).

    Änderungen:
    • [Überarbeitet] Ich hab' den Code ein bisschen aufgeräumt
    • [Neu] man kann zumindest im Planer selbst mehrere Einträge gleichzeitig editieren -> rechtsklick -> Schnelländerung
      (wird noch ausgeweitet, wo es Sinn macht)
    • [Neu] Es gibt nun Felder für "genehmigt" und "Bearbeitung gesperrt" im Plan. Das kann mit entsprechendem Rechtesystem so ausgearbeitet werden,
      dass z.B. nur Vorgesetzte den Status auf "genehmigt" setzen können, damit würde die weitere Bearbeitung automatisch gesperrt.
    • [Neu] Dazugekommen ist auch eine Überprüfung auf Wochenende und/oder Feiertag (überprüft auch das Bundesland des Standorts),
      kann man bei Neuanlage eines Datensatzes im Plan ausschalten (Ist beides standardmäßig aktiviert).
      Es gibt ja Leute, die müssen an Feiertagen und Wochenenden arbeiten, folglich muss es dazu auch eine Urlaub-/Schicht-/Dienstplanung geben
    Bekannte Bugs:
    • legt man einen neuen Datensatz im Plan an, kommt eine automatisierte Reihe mit Datum 01.01.1900 mit

      ErfinderDesRades schrieb:

      Sieht so aus - wenn ich den Filter deaktiviere scheint mir nix komisch.


      macht er auch ohne gesetzte Filter :(
    • möchte man 2x hintereinander die gleichen selektierten Zeilen via "Schnelländerung" bearbeiten, kommt eine Exception
    • Die Filter im Plan und in der Übersicht arbeiten noch nicht sauber
    ToDo:
    • kann in der ToDo.txt (im Projekt) nachgelesen werden

    Wäre schön, ein bisschen Feedback und ggf. weitere Ideen von euch zu erhalten :thumbup:



    PS: Kann mir jemand von euch sagen, wie man einzelne ListView-Zellen einfärben kann?
    Dateien
    • Planer06.zip

      (196,98 kB, 76 mal heruntergeladen, zuletzt: )
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    ErfinderDesRades schrieb:

    Dassisn Bug, der muss behoben werden.


    Moin, ich wollte nur Rückmeldung geben dass ich mittlerweile rausgefunden habe, warum der Beispieleintrag erstellt wird.
    Im Planer hab' ich die Möglichkeit eingebaut einen Zeitraum einzugeben und für jeden Tag in dem Zeitraum erstellt er einen Eintrag.
    Dazu gibt's im DetailDialog 2 meiner DateTextBoxes, welche aber keinen Bezug auf die BS haben.

    Ich hab nun die erste (von Datum) den Text der BS zugeordnet und die Sammeleintragung startet erst ab dem 2. Datum - damit klappt das :)
    Ist mir aufgefallen, als ich in meinem Hauptprojekt eine DateTextBox eingebaut hatte und der das Datum nicht übernahm :rolleyes:
    Bilder
    • Unbenannt.PNG

      2,43 MB, 812×651, 134 mal angesehen
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Update vom 15.05.2020:

    tragl schrieb:

    Bekannte Bugs:

    • legt man einen neuen Datensatz im Plan an, kommt eine automatisierte Reihe mit Datum 01.01.1900 mit
    • möchte man 2x hintereinander die gleichen selektierten Zeilen via "Schnelländerung" bearbeiten, kommt eine Exception
    • Die Filter im Plan und in der Übersicht arbeiten noch nicht sauber
    [list]
    [/list]
    Die o.g. Bugs sind nun behoben.
    Dazu gekommen sind Farbkennzeichnungen (zumindest schon für Urlaubseinträge, kann aber beliebig erweitert werden).
    So wäre das Tool schon sehr gut nutzbar.

    Was noch fehlt:
    • Gruppierungsfunktion
    • Spaltenbezeichnung in den einzelnen Monaten nicht mit dem kompletten Datum, sondern mit dem Tag (01,02,03 usw.) benennen
      (Datum wird aktuell genutzt, um die Einträge sauber auszulesen - mal schauen wie ich das weg bekomme)
    • Feiertagsmarkierung mit ggf. Beschriftung
    • Export nach Excel
    • Kopierfunktion, um markierte Zeilen aus der Übersicht rauszukopieren

    Ansonsten gerne testen und Feedback geben ;)
    Dateien
    • Planer08.zip

      (223,38 kB, 99 mal heruntergeladen, zuletzt: )
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Und wie ist das jetzt für mehrere Mitarbeiter gedacht?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Da der hier gedachte Urlaubsplaner aber offensichtlich für alle Mitarbeiter gleichzeitig eine Anzeige zur Verfügung stellen soll, damit der Chef/zuständige Teamleiter eine Übersicht hat bzw. die Leute schauen können, wo wer schon Urlaub genommen hat, damit man sich für einen anderen Zeitraum entscheinden kann … ach egal. tragl kann ja vielleicht trotzdem was damit anfangen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.