Utoljára aktív 1753356033

Revízió 73abf441d1d96ab4ba32e1dbc214405e0db9270b

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