提问人:sickboy 提问时间:7/6/2023 最后编辑:sickboy 更新时间:7/7/2023 访问量:132
VB.NET Outlook 项目中的 HTML 不正确。HTMLBody
VB.NET Incorrect HTML from Outlook Item .HTMLBody
问:
我正在尝试将我制作的 VBA 函数复制到 VB.NET 中。 它基本上得到一个邮件,然后它从它的HTMLBody中提取它的TABLE标签。 我的问题是函数给出了不同的输出。 VBA 返回标准 HTML 格式,包括所有标记,包括 TABLE。 VB中。NET的输出如下。
<!-- Converted from text/rtf format -->
<P><FONT SIZE=2>TEXT0,<BR>
<BR>
<BR>
INTRO:<BR>
<BR>
A. TEXT1<BR>
<BR>
B TEXT2<BR>
<BR>
C. TEXT3<BR>
<BR>
D. TEXT4<BR>
<BR>
E. TEXT5 & TEXT6<BR>
<BR>
<BR>
相反,这是我想要的
<body lang=EN-US link=blue vlink=purple style='word-wrap:break-word'><div class=WordSection1><p><span style='font-family:Arial'>TEXT0<o:p></o:p></span></p>
<p><span style='font-family:Arial'><br>INTRO <o:p></o:p></span></p>
<p><span style='font-family:Arial'>A. TEXT1 <o:p></o:p></span></p>
<p><span style='font-family:Arial'>B. TEXT2 <o:p></o:p></span></p>
<p><span style='font-family:Arial'>C. TEXT3 <o:p></o:p></span></p>
<p><span style='font-family:Arial'>D. TEXT4 <o:p></o:p></span></p>
<p style='margin-bottom:12.0pt'><span style='font-family:Arial'>E. TEXT5
我已经尝试了所有的 BodyFormats,结果几乎相同,没有标准的 HTML。 两者中使用的引用是相同的。 在代码下方。
Function GetMailTable(Subject As String, daysAgo As Integer, ParamArray Keywords() As Object)
Dim myOlApp As New Outlook.Application
Dim objNamespace As Outlook.NameSpace = myOlApp.GetNamespace("MAPI")
Dim objFolder As Outlook.MAPIFolder = objNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
Dim itm As Outlook.MailItem
Dim Found As Boolean
Dim strFilter As String
Dim Subj As String = Subject
Dim arrList As ArrayList = New ArrayList
daysAgo = myDate.Subtract(previousBusinessDay(myDate, daysAgo)).TotalDays
strFilter = "@SQL=" & Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " like '%" & Subj & "%'"
Dim filtereditemssubj As Object = objFolder.Items.Restrict(strFilter)
Dim filteredItems As Object = filtereditemssubj.Restrict("[ReceivedTime]>'" & Format(myDate.AddDays(-daysAgo), "dd/MM/yyyy") + " 00:00" & "'")
filteredItems = filteredItems.Restrict("[ReceivedTime]<'" & Format(myDate.AddDays(-daysAgo).AddDays(1), "dd/MM/yyyy") + " 00:00" & "'")
Dim htmlDoc As New mshtml.HTMLDocument
Dim tables As mshtml.DispHTMLElementCollection
Dim Table As mshtml.HTMLTable
If filteredItems.Count = 0 Then
Found = False
Else
Found = True
For Each itm In filteredItems
htmlDoc.HTMLBody = itm.HTMLBody
tables = htmlDoc.getElementsByTagName("table")
For Each Table In tables
arrList.Add(Table)
Next Table
Next itm
End If
myOlApp = Nothing
Return arrList
End Function
您可以尝试复制它,在邮件正文中包含表示例。 有人有什么建议吗?
谢谢大家
编辑:我试图在Outlook中查看源代码,正确的输出是在VBA中获得的输出,我真的不明白为什么我在 VB.NET 中没有得到相同的结果。 谁能帮忙?
答:
社区维基,因为这可能无法完全解决问题(可能会给出相同的结果),但它也太长了,无法发表评论。下面的代码为现代 VB.Net 重写了一些东西。如果这仍然只是一个 Office 加载项,您可能无法使用所有这些语言功能,但某些更改(例如不使用 ArrayList 或匈牙利变量前缀)已成为超过 15 年的标准做法,并且从不需要或根本没有帮助 .Net 将项目设置为方法的末尾。Nothing
Function GetMailTable(Subject As String, daysAgo As Integer, ParamArray Keywords() As Object) As IEnumerable(Of mshtml.HTMLTable)
Dim App As New Outlook.Application()
Dim Mapi As Outlook.NameSpace = App.GetNamespace("MAPI")
Dim Inbox As Outlook.MAPIFolder = Mapi.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
Dim searchDate As DateTime = DateTime.Today.AddDays(-daysAgo)
Dim quote As String = Chr(34)
' Below line assumes "Option Infer On"
Dim filteredItems = Inbox.Items.
Restrict($"@SQL={quote}urn:schemas:httpmail:subject{quote} like '%{Subject}%'").
Restrict($"[ReceivedTime]>'{searchDate:dd/MM/yyyy HH:mm}'")
' Needs "Imports System.Linq" at the top
Return filteredItems.
Select(Function(itm) New mshtml.HTMLDocument With {.HTMLBody = itm.HTMLBody}).
SelectMany(Function(doc) doc.getElementsByTagName("table")).
Cast(Of mshtml.HTMLTable)()
End Function
此外,该参数从未被使用过。我只保留它,以防万一某处有代码调用该方法,如果未定义参数,该方法可能会中断。Keywords
当然,调用代码也必须针对新的返回类型进行调整。新结果可以与循环、Linq 运算符方法一起使用,也可以通过追加到函数调用作为列表使用。尽量避免最后一个。For Each
.ToList()
最后,如果我看不到的类型没有正式实现正确的接口,您可能需要包含此方法(在单独的类或模块中):filteredItems
' Requires Option Strict Off, so the compiler will make the implied GetEnumerator() call :(
<Extension()>
Public Shared Iterator Function AsEnumerable(Of T)(input As Object) As IEnumerable(Of T)
For Each item As T In input.GetEnumerator()
Yield item
Next
End Function
然后语句的第一行如下所示:Return
Return filteredItems.AsEnumerable(Of Outlook.MailItem)().
我们知道将具有所需的方法,否则它将无法与原始代码中的循环一起使用。显式键入初始变量声明也可以避免这种情况,但如果您遇到这个问题,我认为这无济于事。filteredItems
GetEnumerator()
For Each
filteredItems
评论
HTML 指示消息是纯文本或 RTF,而不是 HTML。很可能您的脚本正在访问与 VBA 访问的邮件不同的邮件。
尝试找到正确的消息,选择它,并使用集合而不是受限制的集合作为测试。Application.ActiveExplorer.Selection
Items
评论
HTMLBody
Application.ActiveExplorer.Selection
Items.Restrict
评论
<o:p></o:p>