Итак, вам нужен «конечный автомат», который отслеживает то, что анализируется в текстовом файле в любой момент времени для любой данной строки. По большей части ваш текстовый файл выглядит так, как будто у него есть два основных ключевых слова: Page
и Author
. Кроме того, вы либо ожидаете обнаружения следующего ключевого слова, либо собираете (многострочный) комментарий. В простейшей форме конечный автомат часто выражается с помощью оператора Select Case
:
Select Case
Case "Page"
'--- do something with the page number
Case "Author"
'--- do something with the author line
Case Else
'--- either wait for a keyword or collect the comment
End Select
В дополнение к конечному автомату в моем примере ниже, вы также заметите, что я разбил вашкодировать логику в отдельные блоки, чтобы упростить сложность всей длинной цепочки логики. Разделяя функции таким образом, легче сосредоточиться на том, что именно делает этот метод, не беспокоясь о его влиянии на остальную часть метода.
Option Explicit
Sub main()
Dim forumPostFile As String
forumPostFile = "C:\Temp\ForumPostExample.txt"
ExtractComments forumPostFile, Sheet1
End Sub
Sub ExtractComments(ByVal fullPathFilename As String, _
ByRef destWS As Worksheet)
InitializeOutput destWS
Dim commentNumber As Long
commentNumber = 1
Dim fso As FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")
Dim forumFile As Object
Set forumFile = fso.OpenTextFile(fullPathFilename, ForReading)
Dim oneLine As String
Dim state As String
state = "LookForPage"
Dim keywords() As String
Dim page As Long
Dim author As String
Dim subject As String
Dim timestamp As Date
Dim comment As String
Do Until forumFile.AtEndOfStream
oneLine = forumFile.ReadLine
If Len(oneLine) > 0 Then
keywords = Split(oneLine, ":")
Select Case keywords(0)
Case "Page"
If state = "BuildComment" Then
CommentToSheet destWS, (commentNumber + 1), _
commentNumber, author, subject, page, comment, timestamp
commentNumber = commentNumber + 1
comment = vbNullString
End If
page = keywords(1)
state = "LookForAuthor"
Case "Author"
If state = "BuildComment" Then
CommentToSheet destWS, (commentNumber + 1), _
commentNumber, author, subject, page, comment, timestamp
commentNumber = commentNumber + 1
comment = vbNullString
End If
author = Trim$(Left(keywords(1), Len(keywords(1)) - Len("Subject")))
subject = Trim$(Left(keywords(2), Len(keywords(2)) - Len("Date")))
timestamp = CDate(Right$(oneLine, Len(oneLine) - InStr(1, oneLine, "Date:") - Len("Date:")))
state = "BuildComment"
Case Else
If state = "BuildComment" Then
comment = comment & oneLine
End If
End Select
End If
Loop
forumFile.Close
End Sub
Private Sub InitializeOutput(ByRef destWS As Worksheet)
Dim header As Range
Set header = destWS.Range("A1:F1")
destWS.Cells.Clear
With header
.Cells(1, 1) = "Comment No."
.Cells(1, 2) = "Reviewer Name"
.Cells(1, 3) = "Type"
.Cells(1, 4) = "Page Number"
.Cells(1, 5) = "Comment"
.Cells(1, 6) = "Date Submitted"
.WrapText = True
.Interior.Color = RGB(191, 191, 191)
.Columns(1).EntireColumn.HorizontalAlignment = xlHAlignCenter
.Columns(2).EntireColumn.HorizontalAlignment = xlHAlignCenter
.Columns(3).EntireColumn.HorizontalAlignment = xlHAlignCenter
.Columns(4).EntireColumn.HorizontalAlignment = xlHAlignCenter
.Columns(5).EntireColumn.HorizontalAlignment = xlHAlignLeft
.Columns(5).EntireColumn.WrapText = True
.Columns(6).EntireColumn.HorizontalAlignment = xlHAlignLeft
End With
End Sub
Private Sub CommentToSheet(ByRef destWS As Worksheet, _
ByVal row As Long, _
ByVal number As Long, _
ByVal author As String, _
ByVal subject As String, _
ByVal pageNumber As Long, _
ByVal comment As String, _
ByVal timestamp As Date)
With destWS.Rows(row)
.Cells(1, 1) = number
.Cells(1, 2) = author
.Cells(1, 3) = subject
.Cells(1, 4) = pageNumber
.Cells(1, 5) = comment
.Cells(1, 6) = timestamp
End With
End Sub