【问题标题】:Delete text before and after a certain string in email (up to a certain word)删除电子邮件中某个字符串前后的文本(最多为某个单词)
【发布时间】:2015-06-26 14:52:12
【问题描述】:

我希望创建一个 VBA 宏(来自 Excel),用于搜索正文中包含帐号的电子邮件,并删除该电子邮件中的所有其他表格元素,但我指定的元素所在的行除外。

例如,请参阅下面的附件。假设我搜索的号码是“222222222222”号码。我需要 VBA 代码来保留表格标题,删除所有不是“22222222222”的帐户(所以所有 1111 帐户),同时还保留持有量。是否有代码可以删除“2222222222”之后的所有文本但在“Term”一词处停止删除?在那个令牌上,它是否可以在“Deadline”一词之后开始删除,但在到达“222222...”帐户时停止删除?

如果有什么方法我可以专注于实现这一目标,请告诉我。

谢谢!

(P.S. 这些邮件的长度不一,每天都会收到很多。另外,我已经有了可以通过搜索文本来搜索和打开邮件的代码。我只是不知道如何删除这个我不是在寻找无关的东西。)

我已附上我的相关代码以搜索并打开下面的电子邮件:

Dim olApp As Outlook.Application
Dim olNs As Namespace
Dim Fldr As MAPIFolder
Dim olMail As Outlook.MailItem
Dim i As Integer
Dim olMsg As Outlook.MailItem
Dim r As Range
Dim strLocation As String
Dim o As Outlook.Application
Dim strbody As String
Dim objInspector As Object

Set r = ActiveSheet.Buttons(Application.Caller).TopLeftCell
Range(Cells(r.Row, r.Column), Cells(r.Row, r.Column)).Select

Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderInbox).Folders(" Notifications Macro")
i = 1


For Each olMail In Fldr.Items
If InStr(olMail.body, ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-3).Value) <> 0 Then
olMail.display

If InStr(olMail.body, "Mandatory Event: No Responses Required for this") Then
    strbody = "<BODY style=font-size:11pt;font-family:Calibri>Team,<br><br>" & _
              "Please see the notice below regarding " & _
              ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-2).Value & _
              ".<br><br> This is for informational purposes and no action is required.<br><br>" & _
                "Thank you!"

With olMail.Forward
.To = ActiveCell.Offset(ColumnOffset:=-1)
.display
SendKeys ("%")
SendKeys ("7")
 'Call Sleep
Application.Wait (Now + TimeValue("0:00:03"))
.HTMLBody = strbody & "<br>" & .HTMLBody
.HTMLBody = Replace(.HTMLBody, ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-3).Value, "<FONT style=" & Chr(34) & "BACKGROUND-COLOR: yellow" & Chr(34) & ">" & ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-3).Value & "</FONT>")


End With
End If

If InStr(olMail.body, "Warning: Response Required") Then
    strbody = "<BODY style=font-size:11pt;font-family:Calibri>Team,<br><br>" & _
              "Please see the notice below regarding " & _
              ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-2).Value & _
              ".<br><br> If the client wishes to make an election, they will need to call the corresponding team before the deadline indicated on the notice.<br><br>" & _
                "Thank you!"

With olMail.Forward
.To = ActiveCell.Offset(ColumnOffset:=-1)
.display
SendKeys ("%")
SendKeys ("7")
 'Call Sleep
Application.Wait (Now + TimeValue("0:00:03"))
.HTMLBody = strbody & "<br>" & .HTMLBody
.HTMLBody = Replace(.HTMLBody, ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-3).Value, "<FONT style=" & Chr(34) & "BACKGROUND-COLOR: yellow" & Chr(34) & ">" & ActiveCell.Offset(rowOffset:=0, ColumnOffset:=-3).Value & "</FONT>")


End With
End If

End If
Next

End Sub

代码可能看起来令人困惑,但它所做的只是在特定的 Outlook 文件夹中搜索包含特定值的邮件(在单元格 A1 中......在这种情况下...... 222222222222)然后打开电子邮件,转发电子邮件,并突出显示电子邮件中的帐号 (2222222222)。

理想情况下,除了可以删除“2222222”号码之后的文本直到碰到“学期”。问题是我还需要保持持有的数量,因为这个数字真的可以是任何东西,我很难想到如何做到这一点。 任何指导将不胜感激!

-- 编辑--

这里是“表格”的代码,尽管它实际上并没有显示表格标签。这是帐号出现的地方。我分别将它们更改为“111111”和“222222”。

</table>

<div class="normalHeader xsmall" style="color:'CE0000'; background-color: white;">

    Mandatory Event: No Responses Required for this event <br/>

</div>





        <table width="98%" border="0" cellspacing="0" cellpadding="4">

    <tr>

        <td>

            &nbsp;

        </td>

    </tr>

    <tr bgcolor="EEEEEE">

        <td class="normalHeader medium" align="left" colspan="7">

            Account Details

        </td>

    </tr>

    <tr bgcolor="EFEFEF">

        <td class="normalHeader xsmallAlternate" style="background-color: #EFEFEF;">

            Account

        </td>

        <td width="100">

            &nbsp;

        </td>

        <td align="center" class="normalHeader xsmallAlternate" width="20%" nowrap="true" style="background-color: #EFEFEF;" colspan="3">

            Holding Quantity

        </td>

        <td width="100">

            &nbsp;

        </td>

        <td class="normalHeader xsmallAlternate" nowrap="true" style="background-color: #EFEFEF;">

            Account Deadline

        </td>

    </tr>



        <tr class="xsmall">

        <td nowrap="true">

            11111111111

                    </td>

        <td>&nbsp;</td>

        <td width="100">

            &nbsp;

        </td>

        <td align="right" nowrap="true">

            25,000

        </td>

        <td width="100">

            &nbsp;

        </td>

        <td>&nbsp;</td>

        <td style="font-weight: bold;">



        </td>

    </tr>

        <tr class="xsmall">

        <td nowrap="true">

            11111111111

                    </td>

        <td>&nbsp;</td>

        <td width="100">

            &nbsp;

        </td>

        <td align="right" nowrap="true">

            50,000

        </td>

        <td width="100">

            &nbsp;

        </td>

        <td>&nbsp;</td>

        <td style="font-weight: bold;">



        </td>

    </tr>

        <tr class="xsmall">

        <td nowrap="true">

            222222222222

                    </td>

        <td>&nbsp;</td>

        <td width="100">

            &nbsp;

        </td>

        <td align="right" nowrap="true">

            50,000

        </td>

        <td width="100">

            &nbsp;

        </td>

        <td>&nbsp;</td>

        <td style="font-weight: bold;">



        </td>

    </tr>

        <tr class="xsmall">

        <td nowrap="true">

            111111111111

                    </td>

        <td>&nbsp;</td>
    <td width="100">

        &nbsp;

    </td>

【问题讨论】:

    标签: excel vba outlook


    【解决方案1】:

    这很糟糕,但并不令人惊讶,因为这里发生了很多事情。让我们尝试不同的方法。这是一个不涉及 Excel 或 Outlook 的示例。我这样做是为了清楚起见,因为 Excel 和 Outlook 的东西正在搞砸工作。我会让你决定如何将它插入到你现有的函数中。

    请删除我以前的任何代码并在 Excel 中创建一个新模块。 (假设您从代码的外观上使用 Excel)

    将以下函数粘贴到您的新模块中; 它只返回一个模拟 Outlook 邮件项的 html 正文的字符串。该表格与您提供的表格格式相同。

    Function GetTestHTML() As String
      'This respresents the e-mail's html body; use the e-mails html body for the real thing
      Dim strOut As String
      strOut = "<html><body>"
      strOut = strOut & "<div>Some Random Text in a div in made up html. Can be anything really.</div>"
    
      strOut = strOut & "<table>"
      strOut = strOut & "<tr><td>&nbsp;</td></tr>" 'first tr is just blank
      strOut = strOut & "<tr><td>Account Details</td></tr>" '2nd tr is 'Account Details'
      strOut = strOut & "<tr><td>Account</td><td>Holding Quantity</td><td>Account Deadline</td></tr>" '3rd tr is the column headers
      strOut = strOut & "<tr><td>11111111111</td><td>25,000</td><td>&nbsp</td></tr>" 'here's the first real data row
      strOut = strOut & "<tr><td>11111111111</td><td>50,000</td><td>&nbsp</td></tr>"
      strOut = strOut & "<tr><td>222222222222</td><td>50,000</td><td>&nbsp</td></tr>"
      strOut = strOut & "<tr><td>333333333333</td><td>75,000</td><td>&nbsp</td></tr>"
      strOut = strOut & "</table>"
      strOut = strOut & "</body></html>"
      GetTestHTML = strOut
    End Function
    

    现在,请在前一个函数的结束函数之后将以下内容粘贴到新模块中。 这包含将进入主函数的变量和功能,但您将需要使用它才能满足您的需求。 cmets 和 MsgBoxes 应该有助于确定正在发生的事情,以便您可以做到这一点。

    Function TestHtmlTableReplace()
      Dim nTableStart As Long, nTableEnd As Long
      Dim strTableOrg As String, strTableNew As String
    
      Dim strHTMLBody As String
      Dim strAccount As String
    
      strAccount = "222222222222" 'this value represents current account number; use the excel range account number for the real thing
      strHTMLBody = GetTestHTML 'This respresents the e-mail's html body; use the e-mails html body for the real thing
    
      '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> First we isolate the TABLE block >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    
      'As you already do, we are banking on the given account number being included somewhere in the body of the html
      'not only in the body, but within a TABLE object; if it's not, then we are SOL!
    
      'get the pos of your account number which is in the middle of a table object
      nTableStart = InStr(1, strHTMLBody, strAccount)
    
      'now get the pos of the start of the table object by going in reverse from the starting pos of the previous instr
      'checking using uppercase because the source case is unknown
      nTableStart = InStrRev(UCase(strHTMLBody), "<TABLE") 'leaving out the ending > incase there are other things in the tag
    
      'now get the end of the table object
      'checking using uppercase because the source case is unknown
      nTableEnd = InStr(nTableStart, UCase(strHTMLBody), "</TABLE>") + Len("</TABLE>")
    
      'save the original table in a string so you can replace it with the new table later
      strTableOrg = Mid(strHTMLBody, nTableStart, nTableEnd - nTableStart)
      MsgBox "This is our table isolated from the HTML." & vbCrLf & vbCrLf & "We are going to replace it with a modified version that only shows rows with the given account number" & vbCrLf & vbCrLf & strTableOrg
      '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< First we isolate the TABLE block <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
      '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now we modify the table block and replace the original HTML >>>>>>>>>>>>>>>>>>>>>>>>
      strTableNew = GetUpdatedTable(strTableOrg, strAccount)
      MsgBox "This is our modified table." & vbCrLf & vbCrLf & "Now all we have to do is replace the original table with this one in our HTML:" & vbCrLf & vbCrLf & strTableNew
    
      MsgBox "The Original HTML:" & vbCrLf & vbCrLf & strHTMLBody
      strHTMLBody = Replace(strHTMLBody, strTableOrg, strTableNew)
      MsgBox "This is the Modified HTML: " & vbCrLf & vbCrLf & strHTMLBody
    
    End Function
    

    现在,在前一个函数的结束函数之后将以下函数粘贴到新模块中。 这只是应该保持原样的表替换函数。除非“他们”更改电子邮件中 ​​html 的格式,否则它应该可以继续正常工作

    Function GetUpdatedTable(ByRef strTableOrg As String, ByRef strAccount As String) As String
      'now we have the table isolated and can play around until the desired results are acheived
     ' On Error GoTo ErrHandler
      Dim strTable As String
      Dim nStart As Long, nEnd As Long
      Dim strTRBlock As String
    
     'first tr is just blank
      nStart = InStr(1, strTableOrg, "<tr")
      If nStart < 1 Then Exit Function 'couldnt find it
      nStart = nStart + Len("<tr")
    
     '2nd tr is 'Account Details'
      nStart = InStr(nStart, strTableOrg, "<tr")
      If nStart < 1 Then Exit Function 'couldnt find it
      nStart = nStart + Len("<tr")
    
      '3rd tr is the column headers
      nStart = InStr(nStart, strTableOrg, "<tr")
      If nStart < 1 Then Exit Function 'couldnt find it
      nEnd = InStr(nStart, strTableOrg, "</tr>") + Len("</tr>")
    
      'we now have the first part of the table preserved
      strTable = Left(strTableOrg, nEnd - 1)
    
      'ditching that preserved part from what we do next.; all trs should have class="xsmall")
      strTableOrg = Trim(Replace(strTableOrg, strTable, ""))
    
      nStart = 1
      Do
    
        nStart = InStr(nStart, strTableOrg, "<tr")
        If nStart < 1 Then Exit Do
    
        nEnd = InStr(nStart, strTableOrg, "</tr>") + Len("</tr>")
        strTRBlock = Trim(Mid(strTableOrg, nStart, nEnd - nStart))
    
        'see if the account number is in this tr block
        If InStr(1, strTRBlock, strAccount) > 0 Then
    
          strTable = strTable & strTRBlock 'it was found so add this to the resulting table; we dont care about the block if it wasnt found
        End If
    
        nStart = nEnd
    
      Loop
    
      'add the </table> part since it wasnt accounted for
      strTable = strTable & "</table>"
    
      GetUpdatedTable = strTable
    ErrHandler:
      If Err.Number <> 0 Then
        MsgBox Err.Description, vbExclamation, "Error " & Err.Number
      End If
    
    End Function
    

    最后,单击 TestHtmlTableReplace() 函数主体中的某处并运行代码。愉快的编码和非常愉快的第四次!

    【讨论】:

    • 哇!谢谢你的深入回答。你显然在我的问题上花了很多时间,我真的很感激。我要到周三才能尝试这个(那将是我下次在办公室的时候),但我会及时通知你它是如何运作的。但是有一个问题,如果电子邮件中有多个 标签,这仍然可以正常工作吗?我认为电子邮件的标题可能包含一组表格标签,即使它实际上不包含任何数据。
    • 我尝试将此代码插入到我的模块中。我在最顶部插入了第一个 sn-p 代码,并在中间插入了函数,靠近我调用 .Forward 命令的位置。我立即收到有关“未定义对象”的错误
    • 嘿 JGoldz75,我刚刚发现了一个关于多个
    • 标签的好问题。隔离所需表的代码假定帐号在其中某处,因此它将选择第一个具有帐号的
      并忽略任何其他表。希望帐号非常独特,否则会有问题。 (例如,不太可能有多个“ZZZZ357363563”,但如果是“50”,那么可能会有问题。)我刚刚所做的编辑将允许您使用不同的 HTML 场景,以便您可以测试结果。跨度>
    • 天才。我很抱歉,但我将在 15 日之前休假,并且在那之前无法使用这个答案。我回来后会告诉你情况如何!对不起,您必须等待这么久才能得到答复。你的努力没有白费!此代码在新模块中运行良好,我了解 cmets 和 MsgBox 的工作方式以及您尝试发送的消息。周末愉快!
    • 我今天在工作中一直在搞砸这个。虽然我的代码的工作方式,我不确定这是否会完全按照我想要的方式工作。我使用 SendKeys 将原始消息转发给它需要去的任何人,我还使用 SendKeys 发送一条通用消息,上面写着“不需要任何操作”。我相信这段代码实际上是将原始电子邮件更改为仅包含一个帐户,但我需要 HTMLbody 仅在响应中进行更改。我认为最好的办法是以某种方式将整个原始电子邮件导出到一个 txt 文件中,使用代码来捕获所需的帐号
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签