Last active 1753356033

Revision 0c87bd65bae6da5869610903e4a0d0203aeec5fb

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