下面的代码很乐意使用本周的任命填充电子邮件,但它会按预约创建日期而不是实际约会日期列出电子邮件中的日历项目。有没有办法按预约日期列出项目? 我谦虚地感谢任何帮助或建议。 (我把这些代码粘贴在一起,因为我粘贴在网上找到的东西。我对Excel和Access VBA比对Outlook更熟悉。再次感谢。)John
Public Sub ListAppointments()
On Error GoTo On_Error
Dim Session As Outlook.NameSpace
Dim Report As String
Dim AppointmentsFolder As Outlook.Folder
Dim currentItem As Object
Dim currentAppointment As AppointmentItem
Set Session = Application.Session
Set AppointmentsFolder = Session.GetDefaultFolder(olFolderCalendar)
For Each currentItem In AppointmentsFolder.Items
If (currentItem.Class = olAppointment) Then
Set currentAppointment = currentItem
'get the week's appointments
If currentAppointment.Start >= Now() And currentAppointment.Start <= Now() + 7 Then
If currentAppointment.AllDayEvent = False Then 'exclude all day events
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
End If
End If
End If
Next
Call CreateReportAsEmail("List of Appointments", Report)
Exiting:
Exit Sub
On_Error:
MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Sub
Private Function AddToReportIfNotBlank(Report As String, FieldName As String, FieldValue)
AddToReportIfNotBlank = ""
If (IsNull(FieldValue) Or FieldValue <> "") Then
AddToReportIfNotBlank = FieldName & " : " & FieldValue & vbCrLf
Report = Report & AddToReportIfNotBlank
End If
End Function
'publish items to Outlook email
Public Sub CreateReportAsEmail(Title As String, Report As String)
On Error GoTo On_Error
Dim objNS As Outlook.NameSpace
Dim objItem As MailItem
Dim objFolder As MAPIFolder
Set objNS = Application.GetNamespace("MAPI") 'Application.Session
Set objItem = Application.CreateItem(olMailItem)
Set objFolder = objNS.GetDefaultFolder(olFolderInbox)
With objItem
.Subject = "This weeks appointments"
.Body = Report
.Display
End With
Exiting:
'Set Session = Nothing
Exit Sub
On_Error:
'MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Sub
答案 0 :(得分:0)
我没有查看您现有的代码,尽管我确实发现了:
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
我希望我已经包含了足够的评论,所以这一切都有道理。回来问题是必要的。