Last active 1753356033

Revision 254d2feaf8da5d9c783eba067b64bb57b2c86f28

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