Dernière activité 1753357397

Révision a005b26fce5feaca78a4f3ec4498399cdbd3b8ed

gistfile1.txt Brut
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 On Error Resume Next
26 Set olApp = GetObject(, "Outlook.Application")
27 If olApp Is Nothing Then Set olApp = CreateObject("Outlook.Application")
28 On Error GoTo 0
29 If olApp Is Nothing Then
30 MsgBox "Outlook konnte nicht gestartet werden.", vbCritical
31 Exit Sub
32 End If
33 Set olNS = olApp.GetNamespace("MAPI")
34 Set allCalendars = New Collection
35
36 Dim store As Object, folder As Object
37 For Each store In olNS.Folders
38 For Each folder In store.Folders
39 If folder.DefaultItemType = 1 Then allCalendars.Add folder
40 Next folder
41 Next store
42
43 ReDim calendarNames(1 To allCalendars.Count)
44 For i = 1 To allCalendars.Count
45 calendarNames(i) = allCalendars(i).Parent.Name & " – " & allCalendars(i).Name
46 Next i
47 selectedIndex = Application.InputBox("Wähle den Zielkalender aus (Zahl):" & vbCrLf & Join(calendarNames, vbCrLf), "Kalenderauswahl", Type:=1)
48 If Not IsNumeric(selectedIndex) Or selectedIndex < 1 Or selectedIndex > allCalendars.Count Then Exit Sub
49
50 Set selectedCalendar = allCalendars(selectedIndex)
51 MsgBox "Ausgewählter Kalender: " & selectedCalendar.Name, vbInformation, "Kalenderbestätigung"
52 Set olItems = selectedCalendar.Items
53 olItems.Sort "[Start]"
54 olItems.IncludeRecurrences = True
55 Dim gefilterteItems As Object
56 Set gefilterteItems = olItems
57
58 Dim gefilterteItems As Object
59 Set gefilterteItems = olItems
60 End If
61 Set ws = ThisWorkbook.Sheets(1)
62 lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
63 ReDim alreadyProcessed(1 To lastRow)
64
65 Set eintraege = New Collection
66
67 For i = 2 To lastRow
68 Debug.Print "---"
69 Debug.Print "Verarbeite Zeile: " & i
70 Debug.Print "Datum: " & ws.Cells(i, "B").Text
71 Debug.Print "Startzeit: " & ws.Cells(i, "C").Text
72 Debug.Print "Endzeit: " & ws.Cells(i, "D").Text
73 Debug.Print "Produkt: " & ws.Cells(i, "G").Text
74 Debug.Print "Hinweis für Trainer: " & ws.Cells(i, "L").Text
75 Debug.Print "Veranstaltungsnummer: " & ws.Cells(i, "F").Text
76 Debug.Print "Ort: " & ws.Cells(i, "J").Text
77 If alreadyProcessed(i) Then GoTo Weiter
78 If Not IsDate(ws.Cells(i, "B").Value) Then
79 ws.Cells(i, "M").Value = "übersprungen (Datum fehlt)"
80 uebersprungenCount = uebersprungenCount + 1
81 GoTo Weiter
82 End If
83 If ws.Cells(i, "C").Value = "" Then
84 ws.Cells(i, "M").Value = "übersprungen (Startzeit fehlt)"
85 uebersprungenCount = uebersprungenCount + 1
86 GoTo Weiter
87 End If
88 If ws.Cells(i, "G").Value = "" Then
89 ws.Cells(i, "M").Value = "übersprungen (kein Produkt)"
90 uebersprungenCount = uebersprungenCount + 1
91 GoTo Weiter
92 End If
93
94 datum = DateValue(ws.Cells(i, "B").Value)
95 If IsDate(ws.Cells(i, "C").Value) Then
96 startzeit = TimeValue(ws.Cells(i, "C").Value)
97 Else
98 ws.Cells(i, "M").Value = "übersprungen (ungültige Startzeit)"
99 GoTo Weiter
100 End If
101 If IsDate(ws.Cells(i, "D").Value) Then
102 endzeit = TimeValue(ws.Cells(i, "D").Value)
103 Else
104 ws.Cells(i, "M").Value = "übersprungen (ungültige Endzeit)"
105 GoTo Weiter
106 End If
107
108 produkt = Trim(ws.Cells(i, "G").Value)
109 veranstaltungsnummer = Trim(ws.Cells(i, "F").Value)
110 hinweis = Trim(ws.Cells(i, "L").Value)
111 ort = Trim(ws.Cells(i, "J").Value)
112
113 If InStr(1, hinweis, "Lehrgang: ", vbTextCompare) > 0 Then
114 hinweis = Mid(hinweis, InStr(1, hinweis, "Lehrgang: ", vbTextCompare) + 10)
115 End If
116 titel = produkt & " - " & hinweis
117 If titel = " - " Or titel = "-" Then
118 ws.Cells(i, "M").Value = "übersprungen (kein gültiger Titel)"
119 GoTo Weiter
120 End If
121
122 ' Duplikatprüfung: Wenn in Outlook bereits ein Termin mit Datum und Veranstaltungsnummer vorhanden ist
123 Dim skip As Boolean: skip = False
124 If Not DRYRUN Then
125 Dim existingItem As Object, itemDate As Date
126 For Each existingItem In gefilterteItems
127 If existingItem.Class = 26 Then
128 itemDate = Int(existingItem.Start)
129 If itemDate = datum Then
130 If InStr(existingItem.Body, veranstaltungsnummer) > 0 Then
131 If existingItem.Subject <> titel Then
132 Dim msg As VbMsgBoxResult
133 msg = MsgBox("Ein Eintrag mit gleicher Veranstaltungsnummer aber abweichendem Titel existiert: " & existingItem.Subject & vbCrLf & _
134 "Neuer Titel wäre: " & titel & vbCrLf & "Trotzdem ersetzen?", vbYesNo + vbExclamation)
135 If msg = vbNo Then skip = True
136 Else
137 skip = True
138 End If
139 End If
140 End If
141 End If
142 Next existingItem
143 End If
144 If skip Then
145 ' Bestehenden Termin ggf. löschen
146 If Not DRYRUN Then
147 For Each existingItem In gefilterteItems
148 If existingItem.Class = 26 And Int(existingItem.Start) = datum Then
149 If InStr(existingItem.Body, veranstaltungsnummer) > 0 Then
150 existingItem.Delete
151 geloeschtCount = geloeschtCount + 1
152 Exit For
153 End If
154 End If
155 Next
156 End If
157 ws.Cells(i, "M").Value = "ersetzt (gelöscht + neu)"
158 GoTo Weiter
159 End If
160
161 ' Erstellung des Outlook-Termins oder Simulation
162 If DRYRUN Then
163 ws.Cells(i, "M").Value = "(Simulation) " & titel
164 ws.Cells(i, "M").Interior.Color = RGB(200, 200, 200)
165 Else
166 Dim appt As Object
167 Set appt = olApp.CreateItem(1)
168 With appt
169 .Start = datum + startzeit
170 .End = datum + endzeit
171 .Subject = titel
172 .Location = ort
173 .Body = veranstaltungsnummer
174 .ReminderSet = False
175 .BusyStatus = 2
176 .Save
177 End With
178 ws.Cells(i, "M").Value = titel
179 erstelltCount = erstelltCount + 1
180 End If
181 alreadyProcessed(i) = True
182
183 ' Serientermin-Erkennung: gleiche Veranstaltungsnummer an aufeinanderfolgenden Werktagen
184 Dim serieEndRow As Long: serieEndRow = i
185 Do While serieEndRow + 1 <= lastRow And Not alreadyProcessed(serieEndRow + 1)
186 Dim nextDatum As Date
187 If Not IsDate(ws.Cells(serieEndRow + 1, "B").Value) Then Exit Do
188 nextDatum = DateValue(ws.Cells(serieEndRow + 1, "B").Value)
189 If ws.Cells(serieEndRow + 1, "F").Value <> veranstaltungsnummer Then Exit Do
190 If Weekday(datum, vbMonday) = 5 Then ' Freitag
191 If DateDiff("d", datum, nextDatum) <> 3 Then Exit Do ' Freitag → Montag
192 Else
193 If DateDiff("d", datum, nextDatum) <> 1 Then Exit Do
194 End If
195 If ws.Cells(serieEndRow + 1, "G").Value = "" Then Exit Do
196 serieEndRow = serieEndRow + 1
197 Loop
198
199 If serieEndRow > i Then
200 ' Serien-Eintrag
201 If Not DRYRUN Then
202 Dim recurrenceAppt As Object
203 Set recurrenceAppt = olApp.CreateItem(1)
204 With recurrenceAppt
205 .Start = datum + startzeit
206 .End = datum + endzeit
207 .Subject = titel
208 .Location = ort
209 .Body = veranstaltungsnummer
210 .ReminderSet = False
211 .BusyStatus = 2
212 .Save
213 Dim pattern
214 Set pattern = .GetRecurrencePattern
215 pattern.RecurrenceType = 1 ' daily
216 pattern.PatternStartDate = datum
217 pattern.Occurrences = serieEndRow - i + 1
218 .Save
219 End With
220 For j = i To serieEndRow
221 alreadyProcessed(j) = True
222 ws.Cells(j, "M").Value = titel & " (Serie)"
223 Next j
224 serienCount = serienCount + 1
225 GoTo Weiter
226 Else
227 For j = i To serieEndRow
228 alreadyProcessed(j) = True
229 ws.Cells(j, "M").Value = "(Simulation) " & titel & " (Serie)"
230 ws.Cells(j, "M").Interior.Color = RGB(180, 180, 180)
231 Next j
232 serienCount = serienCount + 1
233 GoTo Weiter
234 End If
235 End If
236
237Weiter:
238 Next i
239
240 Dim elapsedTime As Double
241 elapsedTime = Timer - startTime
242 MsgBox "Fertig. " & erstelltCount & " Termine erstellt, " & serienCount & " Serientermine erstellt, " & geloeschtCount & " ersetzt, " & uebersprungenCount & " übersprungen." & vbCrLf & _
243 "Laufzeit: " & Format(elapsedTime, "0.00") & " Sekunden", vbInformation
244End Sub
245