Примітивний контент-аналіз (продовження).

початок теми

Отож. Вдосконалимо розроблений інструмент до рівня розв’язання поставленої задачі. Якщо ви вже встигли протестувати наш макрос на різних текстах, то мали звернути увагу, що в категорію “слово” він може зараховувати числа, розділові знаки, що стоять окремо від текстую Навіть останнє слово речення вписується в таблицю з крапкою, і, очевидно, відрізнятиметь при підрахунку від того ж слова, записаного всередині речення. Перед тим як програмувати процедуру підрахунку кількостей слід позбавити результуючу таблицю від цього “сміття”. Можна було б здійснити перегляд наших слів уже в посортованій таблиці, але це вимагає додаткового перебору елементів списку з певною кількстю порівнянь. Оптимальним вирішенням цієї проблеми є перевірка на наявність зайвих розділових знаків у слові до запису його у таблицю. Опишемо на початку коду макроса ще дві змінні:

Dim S As String
Dim S0 As String

для тимчасового зберігання чергового слова та його частин і скористаємося функціями для обробки даних типу String.

Насампереред запишемо чергове слово з курсора в змінну S, заодно позбавивши його зайвих пробілів на початку і в кінці функцією Trim(). Зайві розділові знаки трапляються лише в кінці слів, тому запишемо останній символ слова S:

S0 = Right(S, 1)

і будемо первіряти чи він є буквою. Ідеальним вирішенням цієї задачі могла б бути перевірка належності Unicode-коду симовла до діапазону кодів, якими задаються літери. Для цього слід використовувати функції Asc(), яка, на жаль, не може впоратися з ситуцією, коли в тексті є порожні абзаци і числа. Щоб не заплутатися, накладаючи на символи та вміст курсора цілий ряд додаткових обмежень, ми задовольнимося простою перевіркою рівності символа S0 тому чи іншому розділовому знаку. Ось так буде вилядати цикл, який позбавлє слово S від зайвих знаків пунктуації у кінці:

S0 = Right(S, 1)
While (S0 = “.” Or S0 = “,” Or S0 = “;” Or S0 = “:” Or S0 = “!” _
Or S0 = “?” Or S0 = “)” Or S0 = “(“ Or S0 = Chr(10) Or _
S0 = Chr(13) Or S0 = Chr(34)) And Len(S)>0
S = Left(S, Len(S) – 1)
S0 = Right(S, 1)
Wend

Chr(10) – недрукований символ закінчення рядка, Chr(13) – символ переходу на новий рядок, Chr(34) – символ подвійної лапки, яку задати в подвійних лапках, очевидно не вдасться. Скласти “чорний список” “небажаних” в умові циклу, очевидно, можна на свій смак, але зловживати не варта, бо кожне порівняня – це додатковий час роботи макроса.

Нарешті можна перейти до підрахунку частоти, попередньо посортувавши список слів в таблиці. Для цього можна було б скористатися зведеною таблицею, або проміжними підсумками, але ми зупинимося на простому переборі комірок. Алгоритм буде полягати в наступному:

  • беремо чергову комірку і обнулюємо лічильник,
  • порівнюємо слово в комірці зі словом у наступній комірці,
  • якщо слова співпадають, то збільшуємо лічильник і видаляємо рядок, що містить наступну комірку з таблиці і продовжуємо порівняння
  • якщо слова відрізняються, то записуємо значення лічильника, беремо наступну комірку і повторюємо процедуру спочатку.

Код відповідних цьому алгоритму інструкцій макроса виглядатиме ось так:


n = 1
Do
S = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n)).getString()
k = 1
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).getString()
While S = S0
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).removeByIndex(0, 1)
k = k + 1
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).getString()
Wend
StatTable.Sheets(0).getCellRangeByName(“B” & CStr(n)).getString(k)
n = n + 1
Loop Until S0 = “”

Залишається ще раз посортувати список, на цей раз за другим стовпцем і за спаданням, тому доведеться дещо модифікувати нашу прцедуру сортування, додавши їй ще два аргументи – порядок сортування, та номер стовпця. Попердній її виклик також слід переписати з додаванням цих аргументів.

Остаточно отримаємо приблизно такий код:

Sub WordsParser()
Dim Cursor As Object
Dim StatTable As Object
Dim noArgs()
Dim n As Integer
Dim k As Integer
Dim S As String
Dim S0 As String

StatTable = StarDesktop.LoadComponentFromUrl(“private:factory/scalc”, _
“_blank”, 0, noArgs())

Cursor = ThisComponent.Text.createTextCursor
Cursor.gotoStart(False)
n = 1
Do While Cursor.gotoNextWord(True)
S = Trim(Cursor.getString())
S0 = Right(S, 1)
While (S0 = “.” Or S0 = “,” Or S0 = “;” Or S0 = “:” Or S0 = “!” _
Or S0 = “?” Or S0 = “)” Or S0 = “(“ Or S0 = Chr(10) Or _
S0 = Chr(13) Or S0 = Chr(34)) And Len(S)>0
S = Left(S, Len(S) – 1)
S0 = Right(S, 1)
Wend
If Len(S)>0 Then
StatTable.Sheets(0).getCellByPosition(0,n).setString(S)
End If
n = n + 1
Cursor.gotoStartOfWord(False)
Loop

SortList StatTable.Sheets(0).getCellRangeByName(“A1:A” & CStr(n), 0, TRUE

n = 1
Do
S = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n)).getString()
k = 1
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).getString()
While S = S0
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).removeByIndex(0, 1)
k = k + 1
S0 = StatTable.Sheets(0).getCellRangeByName(“A” & CStr(n + 1)).getString()
Wend
StatTable.Sheets(0).getCellRangeByName(“B” & CStr(n)).setString(k)
n = n + 1
Loop Until S0 = “”

SortList StatTable.Sheets(0).getCellRangeByName(“A1:A” & CStr(n), 1, FALSE

End Sub

Залишити відповідь