Last active 1753357397

gistfile1.txt Raw
1' Serien-Kalendereinträge aus Excel erstellen mit Serienlogik, Löschung alter Einträge, Logging, Laufzeitmessung, Zusammenfassung und Simulationsmodus
2
3Sub SerienKalendereintraegeErstellen()
4 ' Benutzer wird gefragt, ob Simulation gewünscht ist
5 Dim userResponse As VbMsgBoxResult
6 userResponse = MsgBox("Möchtest du eine Simulation durchführen (keine Einträge werden erstellt oder gelöscht)?", vbYesNo + vbQuestion, "Simulationsmodus")
7 Dim DRYRUN As Boolean
8 DRYRUN = (userResponse = vbYes) ' True = Simulation, False = Echtbetrieb
9
10 Dim olApp As Object, olNS As Object
11 Dim allCalendars As Collection, selectedCalendar As Object
12 Dim calendarNames() As String, selectedIndex As Variant
13 Dim olItems As Object, ws As Worksheet
14 Dim lastRow As Long, i As Long, j As Long, erstelltCount As Long, serienCount As Long, geloeschtCount As Long, uebersprungenCount As Long
15 Dim eintraege As Collection
16 Dim datum As Date, startzeit As Date, endzeit As Date
17 Dim produkt As String, hinweis As String, veranstaltungsnummer As String
18 Dim titel As String, ort As String
19 Dim alreadyProcessed() As Boolean
20 Dim startTime As Double
21 Dim logSheet As Worksheet
22
23 startTime = Timer
24
25 On Error Resume Next
26 Set olApp = GetObject(, "Outlook.Application")
27 If olApp Is Nothing Then Set olApp = CreateObject("Outlook.Application")
28 On Error GoTo 0
29 If olApp Is Nothing Then
30 MsgBox "Outlook konnte nicht gestartet werden.", vbCritical
31 Exit Sub
32 End If
33 Set olNS = olApp.GetNamespace("MAPI")
34 Set allCalendars = New Collection
35
36 Dim store As Object, folder As Object
37 For Each store In olNS.Folders
38 For Each folder In store.Folders
39 If folder.DefaultItemType = 1 Then allCalendars.Add folder
40 Next folder
41 Next store
42
43 ReDim calendarNames(1 To allCalendars.Count)
44 For i = 1 To allCalendars.Count
45 calendarNames(i) = allCalendars(i).Parent.Name & " – " & allCalendars(i).Name
46 Next i
47 selectedIndex = Application.InputBox("Wähle den Zielkalender aus (Zahl):" & vbCrLf & Join(calendarNames, vbCrLf), "Kalenderauswahl", Type:=1)
48 If Not IsNumeric(selectedIndex) Or selectedIndex < 1 Or selectedIndex > allCalendars.Count Then Exit Sub
49
50 Set selectedCalendar = allCalendars(selectedIndex)
51 MsgBox "Ausgewählter Kalender: " & selectedCalendar.Name, vbInformation, "Kalenderbestätigung"
52 Set olItems = selectedCalendar.Items
53 olItems.Sort "[Start]"
54 olItems.IncludeRecurrences = True
55
56 Dim gefilterteItems As Object
57 Dim filterStart As String
58 filterStart = "[Start] >= '" & Format(Date, "ddddd h:nn AMPM") & "'"
59 Set gefilterteItems = olItems.Restrict(filterStart)
60
61 Debug.Print "Kalender geladen: " & selectedCalendar.Name & ", " & gefilterteItems.Count & " gefilterte Einträge"
62 Set ws = ThisWorkbook.Sheets(1)
63 lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
64 ReDim alreadyProcessed(1 To lastRow)
65
66 Set eintraege = New Collection
67
68 For i = 2 To lastRow
69 Debug.Print "---"
70 Debug.Print "Verarbeite Zeile: " & i
71 Debug.Print "Datum: " & ws.Cells(i, "B").Text
72 Debug.Print "Startzeit: " & ws.Cells(i, "C").Text
73 Debug.Print "Endzeit: " & ws.Cells(i, "D").Text
74 Debug.Print "Produkt: " & ws.Cells(i, "G").Text
75 Debug.Print "Hinweis für Trainer: " & ws.Cells(i, "L").Text
76 Debug.Print "Veranstaltungsnummer: " & ws.Cells(i, "F").Text
77 Debug.Print "Ort: " & ws.Cells(i, "J").Text
78 If alreadyProcessed(i) Then GoTo Weiter
79 If Not IsDate(ws.Cells(i, "B").Value) Then
80 ws.Cells(i, "M").Value = "übersprungen (Datum fehlt)"
81 uebersprungenCount = uebersprungenCount + 1
82 GoTo Weiter
83 End If
84 If ws.Cells(i, "C").Value = "" Then
85 ws.Cells(i, "M").Value = "übersprungen (Startzeit fehlt)"
86 uebersprungenCount = uebersprungenCount + 1
87 GoTo Weiter
88 End If
89 If ws.Cells(i, "G").Value = "" Then
90 ws.Cells(i, "M").Value = "übersprungen (kein Produkt)"
91 uebersprungenCount = uebersprungenCount + 1
92 GoTo Weiter
93 End If
94
95 datum = DateValue(ws.Cells(i, "B").Value)
96 If IsDate(ws.Cells(i, "C").Value) Then
97 startzeit = TimeValue(ws.Cells(i, "C").Value)
98 Else
99 ws.Cells(i, "M").Value = "übersprungen (ungültige Startzeit)"
100 GoTo Weiter
101 End If
102 If IsDate(ws.Cells(i, "D").Value) Then
103 endzeit = TimeValue(ws.Cells(i, "D").Value)
104 Else
105 ws.Cells(i, "M").Value = "übersprungen (ungültige Endzeit)"
106 GoTo Weiter
107 End If
108
109 produkt = Trim(ws.Cells(i, "G").Value)
110 veranstaltungsnummer = Trim(ws.Cells(i, "F").Value)
111 hinweis = Trim(ws.Cells(i, "L").Value)
112 ort = Trim(ws.Cells(i, "J").Value)
113
114 If InStr(1, hinweis, "Lehrgang: ", vbTextCompare) > 0 Then
115 hinweis = Mid(hinweis, InStr(1, hinweis, "Lehrgang: ", vbTextCompare) + 10)
116 End If
117 titel = produkt & " - " & hinweis
118 If titel = " - " Or titel = "-" Then
119 ws.Cells(i, "M").Value = "übersprungen (kein gültiger Titel)"
120 GoTo Weiter
121 End If
122
123 ' Duplikatprüfung: Wenn in Outlook bereits ein Termin mit Datum und Veranstaltungsnummer vorhanden ist
124 Dim skip As Boolean: skip = False
125 If Not DRYRUN Then
126 Dim existingItem As Object, itemDate As Date
127 For Each existingItem In gefilterteItems
128 If existingItem.Class = 26 Then
129 itemDate = Int(existingItem.Start)
130 If itemDate = datum Then
131 If InStr(existingItem.Body, veranstaltungsnummer) > 0 Then
132 If existingItem.Subject <> titel Then
133 Dim msg As VbMsgBoxResult
134 msg = MsgBox("Ein Eintrag mit gleicher Veranstaltungsnummer aber abweichendem Titel existiert: " & existingItem.Subject & vbCrLf & _
135 "Neuer Titel wäre: " & titel & vbCrLf & "Trotzdem ersetzen?", vbYesNo + vbExclamation)
136 If msg = vbNo Then skip = True
137 Else
138 skip = True
139 End If
140 End If
141 End If
142 End If
143 Next existingItem
144 End If
145 If skip Then
146 ' Bestehenden Termin ggf. löschen
147 If Not DRYRUN Then
148 For Each existingItem In gefilterteItems
149 If existingItem.Class = 26 And Int(existingItem.Start) = datum Then
150 If InStr(existingItem.Body, veranstaltungsnummer) > 0 Then
151 existingItem.Delete
152 geloeschtCount = geloeschtCount + 1
153 Exit For
154 End If
155 End If
156 Next
157 End If
158 ws.Cells(i, "M").Value = "ersetzt (gelöscht + neu)"
159 GoTo Weiter
160 End If
161
162 ' Erstellung des Outlook-Termins oder Simulation
163 If DRYRUN Then
164 ws.Cells(i, "M").Value = "(Simulation) " & titel
165 ws.Cells(i, "M").Interior.Color = RGB(200, 200, 200)
166 Else
167 Dim appt As Object
168 Set appt = olApp.CreateItem(1)
169 With appt
170 .Start = datum + startzeit
171 .End = datum + endzeit
172 .Subject = titel
173 .Location = ort
174 .Body = veranstaltungsnummer
175 .ReminderSet = False
176 .BusyStatus = 2
177 .Save
178 End With
179 ws.Cells(i, "M").Value = titel
180 erstelltCount = erstelltCount + 1
181 End If
182 alreadyProcessed(i) = True
183
184 ' Serientermin-Erkennung: gleiche Veranstaltungsnummer an aufeinanderfolgenden Werktagen
185 Dim serieEndRow As Long: serieEndRow = i
186 Do While serieEndRow + 1 <= lastRow And Not alreadyProcessed(serieEndRow + 1)
187 Dim nextDatum As Date
188 If Not IsDate(ws.Cells(serieEndRow + 1, "B").Value) Then Exit Do
189 nextDatum = DateValue(ws.Cells(serieEndRow + 1, "B").Value)
190 If ws.Cells(serieEndRow + 1, "F").Value <> veranstaltungsnummer Then Exit Do
191 If Weekday(datum, vbMonday) = 5 Then ' Freitag
192 If DateDiff("d", datum, nextDatum) <> 3 Then Exit Do ' Freitag → Montag
193 Else
194 If DateDiff("d", datum, nextDatum) <> 1 Then Exit Do
195 End If
196 If ws.Cells(serieEndRow + 1, "G").Value = "" Then Exit Do
197 serieEndRow = serieEndRow + 1
198 Loop
199
200 If serieEndRow > i Then
201 ' Serien-Eintrag
202 If Not DRYRUN Then
203 Dim recurrenceAppt As Object
204 Set recurrenceAppt = olApp.CreateItem(1)
205 With recurrenceAppt
206 .Start = datum + startzeit
207 .End = datum + endzeit
208 .Subject = titel
209 .Location = ort
210 .Body = veranstaltungsnummer
211 .ReminderSet = False
212 .BusyStatus = 2
213 .Save
214 Dim pattern
215 Set pattern = .GetRecurrencePattern
216 pattern.RecurrenceType = 1 ' daily
217 pattern.PatternStartDate = datum
218 pattern.Occurrences = serieEndRow - i + 1
219 .Save
220 End With
221 For j = i To serieEndRow
222 alreadyProcessed(j) = True
223 ws.Cells(j, "M").Value = titel & " (Serie)"
224 Next j
225 serienCount = serienCount + 1
226 GoTo Weiter
227 Else
228 For j = i To serieEndRow
229 alreadyProcessed(j) = True
230 ws.Cells(j, "M").Value = "(Simulation) " & titel & " (Serie)"
231 ws.Cells(j, "M").Interior.Color = RGB(180, 180, 180)
232 Next j
233 serienCount = serienCount + 1
234 GoTo Weiter
235 End If
236 End If
237
238Weiter:
239 Next i
240
241 Dim elapsedTime As Double
242 elapsedTime = Timer - startTime
243 MsgBox "Fertig. " & erstelltCount & " Termine erstellt, " & serienCount & " Serientermine erstellt, " & geloeschtCount & " ersetzt, " & uebersprungenCount & " übersprungen." & vbCrLf & _
244 "Laufzeit: " & Format(elapsedTime, "0.00") & " Sekunden", vbInformation
245End Sub
246