Last active 1753356033

Revision cca06b97802ddbed5f7538d4386c0601b9a9c910

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 If Not DRYRUN Then
26 On Error Resume Next
27 Set olApp = GetObject(, "Outlook.Application")
28 If olApp Is Nothing Then Set olApp = CreateObject("Outlook.Application")
29 On Error GoTo 0
30 If olApp Is Nothing Then
31 MsgBox "Outlook konnte nicht gestartet werden.", vbCritical
32 Exit Sub
33 End If
34 Set olNS = olApp.GetNamespace("MAPI")
35 Set allCalendars = New Collection
36
37 Dim store As Object, folder As Object
38 For Each store In olNS.Folders
39 For Each folder In store.Folders
40 If folder.DefaultItemType = 1 Then allCalendars.Add folder
41 Next folder
42 Next store
43
44 ReDim calendarNames(1 To allCalendars.Count)
45 For i = 1 To allCalendars.Count
46 calendarNames(i) = allCalendars(i).Parent.Name & " – " & allCalendars(i).Name
47 Next i
48 selectedIndex = Application.InputBox("Wähle den Zielkalender aus (Zahl):" & vbCrLf & Join(calendarNames, vbCrLf), "Kalenderauswahl", Type:=1)
49 If Not IsNumeric(selectedIndex) Or selectedIndex < 1 Or selectedIndex > allCalendars.Count Then Exit Sub
50
51 Set selectedCalendar = allCalendars(selectedIndex)
52 MsgBox "Ausgewählter Kalender: " & selectedCalendar.Name, vbInformation, "Kalenderbestätigung"
53 Set olItems = selectedCalendar.Items
54 olItems.Sort "[Start]"
55 olItems.IncludeRecurrences = True
56
57 Dim gefilterteItems As Object
58 Dim filterDatum As String
59 filterDatum = Format(Now, "mm/dd/yyyy hh:nn AMPM")
60 Set gefilterteItems = olItems.Restrict("[Start] >= '" & filterDatum & "'")
61
62 On Error Resume Next
63 Set logSheet = ThisWorkbook.Sheets("Gelöschte Termine")
64 If logSheet Is Nothing Then
65 Set logSheet = ThisWorkbook.Sheets.Add
66 logSheet.Name = "Gelöschte Termine"
67 logSheet.Range("A1:D1").Value = Array("Datum", "Startzeit", "Titel", "Kalender")
68 End If
69 On Error GoTo 0
70 End If
71
72 Set ws = ThisWorkbook.Sheets(1)
73 lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
74 ReDim alreadyProcessed(1 To lastRow)
75
76 For i = 2 To lastRow
77 If alreadyProcessed(i) Then GoTo Weiter
78
79 If ws.Cells(i, "B").Value < DateSerial(Year(Date), Month(Date), Day(Date)) Then
80 ws.Cells(i, "M").Value = "übersprungen (Vergangenheit)"
81 uebersprungenCount = uebersprungenCount + 1
82 GoTo Weiter
83 End If
84
85 If Not IsDate(ws.Cells(i, "B").Value) Or ws.Cells(i, "G").Value = "" Then
86 ws.Cells(i, "M").Value = "übersprungen (kein Datum/kein Produkt)"
87 uebersprungenCount = uebersprungenCount + 1
88 GoTo Weiter
89 End If
90
91 Set eintraege = New Collection
92 veranstaltungsnummer = Trim(ws.Cells(i, "F").Value)
93 produkt = Trim(ws.Cells(i, "G").Value)
94 hinweis = Trim(ws.Cells(i, "L").Value)
95 If InStr(hinweis, "Lehrgang: ") > 0 Then
96 hinweis = Mid(hinweis, InStr(hinweis, "Lehrgang: ") + 10)
97 End If
98 titel = produkt & " - " & hinweis
99 If Trim(titel) = "-" Or Trim(titel) = "- -" Or Trim(titel) = "" Then
100 ws.Cells(i, "M").Value = "übersprungen (leerer Titel)"
101 uebersprungenCount = uebersprungenCount + 1
102 GoTo Weiter
103 End If
104 ort = ws.Cells(i, "J").Value
105
106 datum = ws.Cells(i, "B").Value
107 eintraege.Add i
108 alreadyProcessed(i) = True
109
110 For j = i + 1 To lastRow
111 If alreadyProcessed(j) Then GoTo SkipJ
112 If Trim(ws.Cells(j, "F").Value) <> veranstaltungsnummer Then GoTo SkipJ
113 If ws.Cells(j, "G").Value = "" Then GoTo SkipJ
114 If Not IsDate(ws.Cells(j, "B").Value) Then GoTo SkipJ
115 If ws.Cells(j, "B").Value - datum = 1 Or _
116 (Weekday(datum, vbMonday) = 5 And ws.Cells(j, "B").Value - datum = 3) Then
117 eintraege.Add j
118 alreadyProcessed(j) = True
119 datum = ws.Cells(j, "B").Value
120 Else
121 Exit For
122 End If
123SkipJ:
124 Next j
125
126 If eintraege.Count = 1 Then
127 Dim idx As Variant: idx = eintraege(1)
128 If IsDate(ws.Cells(idx, "C").Value) Then
129 startzeit = TimeValue(ws.Cells(idx, "C").Value)
130 Else
131 ws.Cells(idx, "M").Value = "übersprungen (ungültige Startzeit)"
132 GoTo Weiter
133 End If
134
135 If IsDate(ws.Cells(idx, "D").Value) Then
136 endzeit = TimeValue(ws.Cells(idx, "D").Value)
137 Else
138 ws.Cells(idx, "M").Value = "übersprungen (ungültige Endzeit)"
139 GoTo Weiter
140 End If
141 datum = DateValue(ws.Cells(idx, "B").Value)
142 If DRYRUN Then
143 ws.Cells(idx, "M").Value = "[Simulation] Einzel: " & titel
144 Else
145 Call OutlookEintragErstellen(selectedCalendar, gefilteteItems, datum, startzeit, endzeit, titel, ort, veranstaltungsnummer)
146 ws.Cells(idx, "M").Value = titel
147 End If
148 ws.Cells(idx, "N").Value = IIf(DRYRUN, "(Simulation)", selectedCalendar.Name)
149 erstelltCount = erstelltCount + 1
150 With ws.Cells(idx, "M").Interior: .Color = RGB(198, 239, 206): End With
151 Else
152 For Each idx In eintraege
153 datum = ws.Cells(idx, "B").Value
154 If Not DRYRUN Then
155 Call OutlookEintragLoeschen(gefilteteItems, datum, titel, logSheet, selectedCalendar.Name)
156 geloeschtCount = geloeschtCount + 1
157 End If
158 Next idx
159 If DRYRUN Then
160 For Each idx In eintraege
161 ws.Cells(idx, "M").Value = "[Simulation] Serie: " & titel
162 ws.Cells(idx, "N").Value = "(Simulation)"
163 serienCount = serienCount + 1
164 With ws.Cells(idx, "M").Interior: .Color = RGB(255, 235, 156): End With
165 Next idx
166 Else
167 Dim appt As Object
168 Set appt = selectedCalendar.Items.Add
169 With appt
170 .Start = ws.Cells(eintraege(1), "B").Value + ws.Cells(eintraege(1), "C").Value
171 .End = ws.Cells(eintraege(1), "B").Value + ws.Cells(eintraege(1), "D").Value
172 .Subject = titel
173 .Location = ort
174 .Body = "Veranstaltungsnummer: " & veranstaltungsnummer
175 .BusyStatus = 2
176 .ReminderSet = False
177 Dim pattern As Object
178 Set pattern = .GetRecurrencePattern
179 pattern.RecurrenceType = 0
180 pattern.Interval = 1
181 pattern.PatternStartDate = ws.Cells(eintraege(1), "B").Value
182 pattern.PatternEndDate = ws.Cells(eintraege(eintraege.Count), "B").Value
183 pattern.NoEndDate = False
184 .Save
185 End With
186 For Each idx In eintraege
187 ws.Cells(idx, "M").Value = "Serie: " & titel
188 ws.Cells(idx, "N").Value = selectedCalendar.Name
189 serienCount = serienCount + 1
190 With ws.Cells(idx, "M").Interior: .Color = RGB(255, 235, 156): End With
191 Next idx
192 End If
193 End If
194Weiter:
195 Next i
196
197 MsgBox "Fertig in " & Format(Timer - startTime, "0.00") & " Sekunden." & vbCrLf & _
198 erstelltCount & " Einzeltermine erstellt" & vbCrLf & _
199 serienCount & " Serien-Einträge erstellt" & vbCrLf & _
200 geloeschtCount & " alte Termine gelöscht" & vbCrLf & _
201 uebersprungenCount & " Zeilen übersprungen", vbInformation
202End Sub
203
204
205' Hilfsfunktion zum Erstellen eines Einzeltermins
206Sub OutlookEintragErstellen(ByVal selectedCalendar As Object, ByVal gefilteteItems As Object, ByVal datum As Date, ByVal startzeit As Date, ByVal endzeit As Date, ByVal titel As String, ByVal ort As String, ByVal veranstaltungsnummer As String)
207 Dim item As Object, existingItem As Object
208 Dim itemDate As Date
209 Dim bodyText As String
210
211 For Each existingItem In gefilteteItems
212 If existingItem.Class = 26 Then ' nur AppointmentItems
213 itemDate = Int(existingItem.Start)
214 If itemDate = datum Then
215 bodyText = "" & existingItem.Body
216 If InStr(bodyText, veranstaltungsnummer) > 0 Then
217 If existingItem.Subject <> titel Then
218 Dim msg As VbMsgBoxResult
219 msg = MsgBox("Ein Kalendereintrag mit derselben Veranstaltungsnummer existiert, aber der Titel unterscheidet sich:" & vbCrLf & _
220 "Bestehender Titel: " & existingItem.Subject & vbCrLf & _
221 "Neuer Titel: " & titel & vbCrLf & vbCrLf & _
222 "Trotzdem neuen Eintrag erstellen?", vbYesNo + vbExclamation, "Unstimmigkeit bei Titel")
223 If msg = vbNo Then Exit Sub
224 Else
225 Exit Sub ' Duplikat mit gleichem Titel und Veranstaltungsnummer
226 End If
227 End If
228 ' Duplikat erkannt
229 Exit Sub
230 End If
231 End If
232 Next
233
234 Set item = selectedCalendar.Items.Add
235 With item
236 .Start = datum + startzeit
237 .End = datum + endzeit
238 .Subject = titel
239 .Location = ort
240 .Body = "Veranstaltungsnummer: " & veranstaltungsnummer
241 .BusyStatus = 2
242 .ReminderSet = False
243 .Save
244 End With
245End Sub
246
247
248' Hilfsfunktion zum Löschen vorhandener Einzeltermine mit gleichem Titel am gegebenen Datum
249Sub OutlookEintragLoeschen(ByVal gefilteteItems As Object, ByVal datum As Date, ByVal titel As String, ByVal logSheet As Worksheet, ByVal kalenderName As String)
250 Dim item As Object
251 Dim itemDate As Date
252 For Each item In gefilteteItems
253 If item.Class = 26 Then ' nur AppointmentItems
254 itemDate = Int(item.Start)
255 If itemDate = datum And item.Subject = titel Then
256 logSheet.Cells(logSheet.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1).Resize(1, 4).Value = _
257 Array(Format(item.Start, "dd.mm.yyyy"), Format(item.Start, "hh:nn"), titel, kalenderName)
258 item.Delete
259 Exit For
260 End If
261 End If
262 Next
263End Sub
264