Я не проверял ваш существующий код, хотя и заметил:
- Если бы вы составили список моих встреч и пропустили мои дневные встречи, я был бы серьезно недоволен.
AddToReportIfNotBlank
не является функцией, поскольку она не возвращает значение.
С моим решением вы не добавляете встречи в Report
по мере их обнаружения.Вместо этого они добавляются в массив структур.Как только все соответствующие встречи найдены, создается массив индексов в массиве структур, который сортируется по дате встречи.Затем отчет строится из массива структур в индексной последовательности.Я надеюсь, что в этом есть смысл.Дополнительные детали в коде.
Мое решение требует структуры.Определение типа должно быть помещено перед любой подпрограммой или функцией.
Type typAppointment
Start As Date
AllDay As Boolean
End As Date
Subject As String
Location As String
End Type
Мне нужны эти переменные в дополнение к вашей:
Dim AppointmentDtl() As typAppointment
Dim InxADCrnt As Long
Dim InxADCrntMax As Long
Dim InxAppointmentSorted() As Long
Dim InxSrtCrnt1 As Long
Dim InxSrtCrnt2 As Long
Dim Stg as String
Этот код подготавливает массив структур для использования.Поместите перед циклом, который ищет встречи:
ReDim AppointmentDtl(1 To 100)
' * I avoid having too many ReDim Preserves because they
' involve creating a copy of the original array.
' * 100 appointments should be enough but the array will
' be resized if necessary.
InxADCrntMax = 0 ' The current last used entry in AppointmentDtl
Удалите ваш код:
Call AddToReportIfNotBlank(Report, "Subject", currentAppointment.Subject)
Call AddToReportIfNotBlank(Report, "Start", currentAppointment.Start)
Call AddToReportIfNotBlank(Report, "End", currentAppointment.End)
Call AddToReportIfNotBlank(Report, "Location", currentAppointment.Location)
Report = Report & "-----------------------------------------------------"
Report = Report & vbCrLf & vbCrLf
и замените его следующим, который сохраняет детали выбранных встреч в структуре.Этот код обрабатывает дневные и неполные собрания:
InxADCrntMax = InxADCrntMax + 1
If InxADCrntMax > UBound(AppointmentDtl) Then
' Have filled array. Add another 100 entries
ReDim Preserve AppointmentDtl(1 To 100 + UBound(AppointmentDtl))
End If
AppointmentDtl(InxADCrntMax).Start = .Start
If .AllDayEvent Then
AppointmentDtl(InxADCrntMax).AllDay = True
Else
AppointmentDtl(InxADCrntMax).AllDay = False
AppointmentDtl(InxADCrntMax).End = .End
End If
AppointmentDtl(InxADCrntMax).Subject = .Subject
AppointmentDtl(InxADCrntMax).Location = .Location
End If
Выше Call CreateReportAsEmail("List of Appointments", Report)
вставка:
' Initialise index array as 1, 2, 3, 4, ...
ReDim InxAppointmentSorted(1 To InxADCrntMax)
For InxSrtCrnt1 = 1 To InxADCrntMax
InxAppointmentSorted(InxSrtCrnt1) = InxSrtCrnt1
Next
' Sort index array by AppointmentDtl(xxx).Start.
' This is not an efficient sort but it should be sufficient for your purposes.
' If not, I have a Shell Sort written in VBA although a Quick Sort
' is considered the best.
InxADCrnt = 1
Do While InxADCrnt < InxADCrntMax
InxSrtCrnt1 = InxAppointmentSorted(InxADCrnt)
InxSrtCrnt2 = InxAppointmentSorted(InxADCrnt + 1)
If AppointmentDtl(InxSrtCrnt1).Start > AppointmentDtl(InxSrtCrnt2).Start Then
InxAppointmentSorted(InxADCrnt) = InxSrtCrnt2
InxAppointmentSorted(InxADCrnt + 1) = InxSrtCrnt1
If InxADCrnt > 1 Then
InxADCrnt = InxADCrnt - 1
Else
InxADCrnt = InxADCrnt + 1
End If
Else
InxADCrnt = InxADCrnt + 1
End If
Loop
' InxAppointmentSorted() is now: 5, 20, 2, ... where appointment 5 is
' the earliest, appointment 20 the next and so on
' Process appointments in Start order
For InxSrtCrnt1 = 1 To InxADCrntMax
InxADCrnt = InxAppointmentSorted(InxSrtCrnt1)
With AppointmentDtl(InxADCrnt)
' I have tested all other code on my calendar. This code is untested.
' I have included all day meetings but you could easily restore the
' original approach.
Call AddToReportIfNotBlank(Report, "Subject", .Subject)
If .AllDay Then
Stg = "All day " & Format(.Start, "dddd d mmm")
Else
' Date formatted as "Friday 27 Jan". Use "dddd mmmm, d" if you
' prefer "Friday January, 27". That is: "d" gives day of month
' with leading zero omitted. "dddd" gives full day of week. "mmm"
' gives three letter month. "mmmm" gives full month. "yy", if
' required, give two day year. "yyyy" gives four day year. Include
' spaces and punctuation as desired.
Stg = Format(.Start, "dddd d mmm") & _
Format(.Start, " hh:mm") & " to " & _
Format(.End, "hh:mm")
End If
Call AddToReportIfNotBlank(Report, "When", Stg)
Call AddToReportIfNotBlank(Report, "Location", .Location)
Report = Report & "-----------------------------------------------------"
Report = Report & vbCrLf & vbCrLf
End With
Next
Надеюсь, я включил достаточно комментариев, так что все это имеет смысл.Вернись с вопросами необходимо.