Как извлечь конкретный текст из писем? - PullRequest
0 голосов
/ 04 ноября 2018

Я борюсь с извлечением имени и адреса электронной почты из стандартной электронной почты.

Я ожидаю более 300 электронных писем с тем же форматом / макетом, как показано ниже.

От: webfeedback@XXXXX.com Отправлено: четверг, 1 ноября 2018 г., 10:20. Кому: Джо Тема: 2018 сертификат КОМАНДЫ

Четверг, 1 ноября 2018 года - 10: 20

Как бы вы хотели, чтобы ваше имя отображалось в СЕРТИФИКАТЕ УЧАСТИЯ? Джо Фамилия Адрес электронной почты Обязательно ojoelastname@XXXXXXXXX.com

Я хотел бы извлечь имя «Джо Фамилия», адрес электронной почты ojoelastname@xxxxxxxxxx.com и дату, отправленную в Excel.

В настоящее время код извлекается в Excel: «Как бы вы хотели, чтобы ваше имя отображалось в СЕРТИФИКАТЕ УЧАСТИЯ? OJoe Xaskasdad » и адрес электронной почты «ojoeXaskasdaa@XXXXXXxXxX.org

Я изо всех сил пытаюсь выяснить, как получить только Имя " oJoe Xaskasdad " и адрес электронной почты ojoeXaskasdaa@XXXXXXxXxX.org> address (минус ">») .

Я новичок в VBA, но мне нравится учиться. Я нахожусь в тупике, и хотя я продолжаю читать и исследовать ошибку, я надеюсь, что кто-то будет достаточно любезен, чтобы помочь, так как время истекает, и мне, возможно, скоро придется много копировать и вставлять.

Ваши предложения, рекомендации (исправления) будут с благодарностью. СПАСИБО за любую помощь!

ТЕКУЩИЙ КОД

Sub CopyToExcel13()

    Dim xlApp As Excel.Application
    Dim xlWB As Excel.Workbook
    Dim xlSheet As Excel.Worksheet
    Dim olItem As Outlook.MailItem
    Dim vText As Variant
    Dim sText As String
    Dim vItem As Variant
    Dim i As Long
    Dim RowCount As Long
    Dim sLink As String
    Dim bXStarted As Boolean
    Dim FilePath As String
    Dim sReplace As String

    FilePath = "D:\My Documents\Book1.xlsx" 'the path of the xl workbook'


    If Application.ActiveExplorer.Selection.Count = 0 Then
        MsgBox "No Items selected!", vbCritical, "Error"
    End If

    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application")

    If Err <> 0 Then
        Application.StatusBar = "Please wait while Excel source is opened ... "
        Set xlApp = CreateObject("Excel.Application")
        bXStarted = True
    End If

    On Error GoTo 0
    '// Open the workbook to input the data
    Set xlWB = xlApp.Workbooks.Open(FilePath) ' Open xlFile
    Set xlSheet = xlWB.Sheets("Sheet1") ' use Sheet1 or Sheet name

    '// Process each selected Mail Item
    For Each olItem In Application.ActiveExplorer.Selection
        sText = olItem.Body ' Email Body
        vText = Split(sText, Chr(13)) ' Chr(13) = Carriage return
'        vPara = Split(sText, Chr(13))

        '// Find the next empty line of the worksheet
        RowCount = xlSheet.Range("A" & xlSheet.Rows.Count).End(xlUp).Row
        RowCount = RowCount + 1

        '// Check each line of text in the message body down loop
        For i = UBound(vText) To 0 Step -1

            '// InStr([start,]mainString, SearchedString[, compare])
            If InStr(1, vText(i), "name to appear") > 0 Then
                '// Split vItem : & :
                vItem = Split(vText(i), Chr(58)) ' Chr(58) = :
                '// Trim = String whose both side spaces needs to be trimmed
                xlSheet.Range("A" & RowCount) = Trim(vItem(0)) ' (0) = Position
            End If

            '// Email Address Required
            If InStr(1, vText(i), "Email Address Required ") > 0 Then
                vItem = Split(vText(i), Chr(58))
                xlSheet.Range("B" & RowCount) = Trim(vItem(1))
            End If

        Next i

        xlWB.Save

    Next olItem

    '// Save & close workbook
    xlWB.Close SaveChanges:=True
    If bXStarted Then
        xlApp.Quit
    End If

    '// Cleanup
    Set xlApp = Nothing
    Set xlWB = Nothing
    Set xlSheet = Nothing
    Set olItem = Nothing

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Дано письмо в этом формате:

От: webfeedback@XXXXX.com
Отправлено: четверг, 1 ноября 2018 г., 10:20
Кому: Джо
Тема: 2018 сертификат КОМАНДЫ

Четверг, 1 ноября 2018 года - 10: 20

Как бы вы хотели, чтобы ваше имя отображалось в СЕРТИФИКАТЕ УЧАСТИЯ? Джо Фамилия
Адрес электронной почты Обязательно ojoelastname@XXXXXXXXX.com

Вы можете настроить код, предназначенный для структурированных строк, с разделителем ":".

Option Explicit

Sub CopyToExcel13()

' With a reference to Excel Object Library

Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlSheet As Excel.Worksheet

Dim olItem As MailItem

Dim vText As Variant
Dim sText As String
Dim vItem As Variant

Dim i As Long
Dim RowCount As Long

Dim bXStarted As Boolean

Dim FilePath As String

FilePath = "D:\My Documents\Book1.xlsx" 'the path of the xl workbook'

If ActiveExplorer.Selection.count = 0 Then
    MsgBox "No Items selected!", vbCritical, "Error"

    Exit Sub    ' <--

End If

On Error Resume Next
Set xlApp = getObject(, "Excel.Application")
' Discontinue error bypass as soon as possible
On Error GoTo 0

If xlApp Is Nothing Then    ' <--
    Set xlApp = CreateObject("Excel.Application")
    bXStarted = True
End If

' Comment out as applicable
xlApp.Visible = True
xlApp.ScreenUpdating = True

'// Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(FilePath) ' Open xlFile
Set xlSheet = xlWB.Sheets("Sheet1") ' use Sheet1 or Sheet name

'// Process each selected Mail Item
For Each olItem In ActiveExplorer.Selection

    sText = olItem.body ' Email Body
    vText = Split(sText, Chr(13)) ' Chr(13) = Carriage return

    '// Find the next empty line of the worksheet
    RowCount = xlSheet.Range("A" & xlSheet.Rows.count).End(xlUp).Row
    RowCount = RowCount + 1

    '// Check each line of text in the message body down loop
    For i = UBound(vText) To LBound(vText) Step -1

        Debug.Print i & ": " & vText(i)

        '// InStr([start,]mainString, SearchedString[, compare])
        If InStr(1, vText(i), "CERTIFICATE OF PARTICIPATION?") > 1 Then
            vItem = Split(vText(i), "CERTIFICATE OF PARTICIPATION?")
            '// Trim = String whose both side spaces needs to be trimmed
            xlSheet.Range("A" & RowCount) = Trim(vItem(1))
        End If

        '// Email Address Required
        If InStr(1, vText(i), "Email Address Required") > 0 Then
            vItem = Split(vText(i), "Email Address Required")
            xlSheet.Range("B" & RowCount) = Trim(vItem(1))
        End If

        'Sent date
        If InStr(1, vText(i), "Sent:") > 0 Then
            vItem = Split(vText(i), Chr(58)) ' Chr(58) = :
            xlSheet.Range("C" & RowCount) = Trim(vItem(1))
        End If

    Next i

    xlWB.Save

Next olItem

'// Save & close workbook
'xlWB.Close SaveChanges:=True
'If bXStarted Then
'    xlApp.Quit
'End If

'// Cleanup
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing

End Sub
0 голосов
/ 05 ноября 2018

Знаете ли вы точный формат этих писем? Например, текстовое тело каждого электронного письма, которое я изучал, использует CR LF в качестве разрыва строки, и обычно их больше, чем вы ожидаете. Если я правильно интерпретировал ваш код, каждая обрабатываемая вами строка будет начинаться с перевода строки.

Ниже приведен код модуля, который я использую для изучения электронных писем, которые я хочу обработать.

Я предлагаю вам скопировать код в новый модуль с именем что-то вроде «ModInvestigate». Вам понадобятся ссылки на «Microsoft Scripting Runtime» и «Microsoft ActiveX Data Objects n.n Library».

Выберите несколько таких писем и запустите макрос «InvestigateEmails». На рабочем столе вы найдете новый файл с именем «InvestigateEmails.txt».

Непосредственным для вас имуществом является текстовое тело. Возврат каретки, перевод строки и табуляция были заменены на «{cr}», «{lf}» и «{tb}», поэтому вы можете точно видеть, что будет видеть макрос VBA.

Это может быть вся необходимая вам помощь. Если нет, я предлагаю вам включить вывод из текстового тела, отформатированного как код, в ваш вопрос.

Option Explicit
Public Sub InvestigateEmails()

  ' Outputs properties of selected emails to a file.

  ' ???????  No record of when originally coded
  ' 22Oct16  Output to desktop file rather than Immediate Window.

  ' Technique for locating desktop from answer by Kyle:
  ' http://stackoverflow.com/a/17551579/973283
  ' Needs reference to "Microsoft Scripting Runtime"

  Dim Exp As Explorer
  Dim FileBody As String
  Dim Fso As FileSystemObject
  Dim ItemCrnt As MailItem
  Dim Path As String

  Path = CreateObject("WScript.Shell").specialfolders("Desktop")

  Set Exp = Outlook.Application.ActiveExplorer

  If Exp.Selection.Count = 0 Then
    Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
    Exit Sub
  Else
    FileBody = ""
    For Each ItemCrnt In Exp.Selection
      With ItemCrnt
        FileBody = FileBody & "From (Sender): " & .Sender & vbLf
        FileBody = FileBody & "From (Sender name): " & .SenderName & vbLf
        FileBody = FileBody & "From (Sender email address): " & _
                              .SenderEmailAddress & vbLf
        FileBody = FileBody & "Subject: " & CStr(.Subject) & vbLf
        Call OutLongText(FileBody, "Text: ", Replace(Replace(Replace(.Body, vbLf, _
                         "{lf}" & vbLf), vbCr, "{cr}"), vbTab, "{tb}"))
        Call OutLongText(FileBody, "Html: ", Replace(Replace(Replace(.HtmlBody, vbLf, _
                         "{lf}" & vbLf), vbCr, "{cr}"), vbTab, "{tb}"))
        FileBody = FileBody & "--------------------------" & vbLf
      End With
    Next
  End If

  Call PutTextFileUtf8NoBOM(Path & "\InvestigateEmails.txt", FileBody)

End Sub
Public Sub OutLongText(ByRef TextOut As String, ByVal Head As String, _
                       ByVal TextIn As String)

  ' Break TextIn into lines of not more than 100 characters
  ' and append to TextOut

  Dim PosEnd As Long
  Dim LenOut As Long
  Dim PosStart As Long

  If TextIn <> "" Then
    PosStart = 1
    Do While PosStart <= Len(TextIn)
      PosEnd = InStr(PosStart, TextIn, vbLf)
      If PosEnd = 0 Or PosEnd > PosStart + 100 Then
        ' No LF in remainder of TextIn or next 100 characters
        PosEnd = PosStart + 99
        LenOut = 100
      Else
        ' Output upto LF.  Restart output after LF
        LenOut = PosEnd - PosStart
        PosEnd = PosEnd
      End If
      If PosStart = 1 Then
        TextOut = TextOut & Head
      Else
        TextOut = TextOut & Space(Len(Head))
      End If
      TextOut = TextOut & Mid$(TextIn, PosStart, LenOut) & vbLf
      PosStart = PosEnd + 1
    Loop
  End If

End Sub
Public Sub PutTextFileUtf8NoBOM(ByVal PathFileName As String, ByVal FileBody As String)

  ' Outputs FileBody as a text file named PathFileName using
  ' UTF-8 encoding without leading BOM

  ' Needs reference to "Microsoft ActiveX Data Objects n.n Library"
  ' Addition to original code says version 2.5. Tested with version 6.1.

  '  1Nov16  Copied from http://stackoverflow.com/a/4461250/973283
  '          but replaced literals with parameters.
  ' 15Aug17  Discovered routine was adding an LF to the end of the file.
  '          Added code to discard that LF.
  ' 11Oct17  Posted to StackOverflow
  '  9Aug18  Comment from rellampec suggested removal of adWriteLine from
  '          WriteTest statement would avoid adding LF.
  ' 30Sep18  Amended routine to remove adWriteLine from WriteTest statement
  '          and code to remove LF from file. Successfully tested new version.

  ' References: http://stackoverflow.com/a/4461250/973283
  '             https://www.w3schools.com/asp/ado_ref_stream.asp

  Dim BinaryStream As Object
  Dim UTFStream As Object

  Set UTFStream = CreateObject("adodb.stream")

  UTFStream.Type = adTypeText
  UTFStream.Mode = adModeReadWrite
  UTFStream.Charset = "UTF-8"
  UTFStream.Open
  UTFStream.WriteText FileBody

  UTFStream.Position = 3 'skip BOM

  Set BinaryStream = CreateObject("adodb.stream")
  BinaryStream.Type = adTypeBinary
  BinaryStream.Mode = adModeReadWrite
  BinaryStream.Open

  UTFStream.CopyTo BinaryStream

  UTFStream.Flush
  UTFStream.Close
  Set UTFStream = Nothing

  BinaryStream.SaveToFile PathFileName, adSaveCreateOverWrite
  BinaryStream.Flush
  BinaryStream.Close
  Set BinaryStream = Nothing

End Sub
...