Last active 1753356033

Revision 9cb0bc9ca000cb5406ce0698571c65cf39a196c0

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