Sub CountWordsSorted()
Dim doc As Document
Dim s As Shape
Dim allText As String
Dim words() As String
Dim wordCount As Object
Dim w As Variant
Dim trimmedWord As String
Dim cleanedText As String
Dim result As String
Dim keyArray As Variant
Dim i As Long
Set doc = ActiveDocument
Set wordCount = CreateObject("Scripting.Dictionary")
' Проходим по всем текстовым объектам на странице
For Each s In doc.ActivePage.Shapes
If s.Type = cdrTextShape Then
cleanedText = s.Text.Story.Text
cleanedText = RemoveSpecialChars(cleanedText) ' Удаляем спецсимволы 1-31
cleanedText = RemovePunctuation(cleanedText) ' Удаляем знаки препинания
cleanedText = Trim(cleanedText) ' Убираем пробелы в начале и конце
allText = allText & " " & cleanedText
End If
Next s
' Разбиваем весь текст на слова
words = Split(LCase(allText))
' Считаем количество каждого слова в словаре
For Each w In words
trimmedWord = Trim(w)
If Len(trimmedWord) > 0 Then
If wordCount.Exists(trimmedWord) Then
wordCount(trimmedWord) = wordCount(trimmedWord) + 1
Else
wordCount.Add trimmedWord, 1
End If
End If
Next w
' Получаем массив ключей (слов) из словаря
keyArray = wordCount.Keys
' Сортируем массив по алфавиту
Call QuickSortStrings(keyArray, LBound(keyArray), UBound(keyArray))
' Формируем строку результата для вывода
result = "Количество одинаковых слов:" & vbCrLf & "(в алфавитном порядке) " & vbCrLf & vbCrLf
For i = LBound(keyArray) To UBound(keyArray)
result = result & keyArray(i) & ": " & wordCount(keyArray(i)) & vbCrLf
Next i
' Выводим сообщение
MsgBox result, vbInformation, "Результат подсчёта"
End Sub
' Удаление спецсимволов с кодами от 1 до 31 включительно, заменяем на пробел
Function RemoveSpecialChars(str As String) As String
Dim i As Integer
Dim ch As String
Dim resultStr As String
resultStr = ""
For i = 1 To Len(str)
ch = Mid(str, i, 1)
If Asc(ch) >= 32 Then
resultStr = resultStr & ch
Else
resultStr = resultStr & " "
End If
Next i
RemoveSpecialChars = resultStr
End Function
' Удаление всех знаков препинания, сохранение кириллицы, латиницы, цифр и пробелов
Function RemovePunctuation(text As String) As String
Dim i As Long
Dim ch As String
Dim code As Integer
Dim resultStr As String
resultStr = ""
For i = 1 To Len(text)
ch = Mid(text, i, 1)
code = AscW(ch)
' Латиница A-Z a-z
If (code >= 65 And code <= 90) Or (code >= 97 And code <= 122) Then
resultStr = resultStr & ch
' Кириллица А-Я, а-я, Ё, ё
ElseIf (code >= 1040 And code <= 1103) Or code = 1025 Or code = 1105 Then
resultStr = resultStr & ch
' Цифры 0-9
ElseIf (code >= 48 And code <= 57) Then
resultStr = resultStr & ch
' Пробел
ElseIf ch = " " Then
resultStr = resultStr & ch
Else
' Удаляем остальные символы (знаки препинания)
resultStr = resultStr & " "
End If
Next i
RemovePunctuation = resultStr
End Function
' Быстрая сортировка массива строк (алфавитно, без учёта регистра)
Sub QuickSortStrings(arr As Variant, first As Long, last As Long)
Dim pivot As String
Dim i As Long, j As Long
Dim temp As String
If first >= last Then Exit Sub
pivot = arr((first + last) \ 2)
i = first
j = last
Do While i <= j
Do While StrComp(arr(i), pivot, vbTextCompare) < 0
i = i + 1
Loop
Do While StrComp(arr(j), pivot, vbTextCompare) > 0
j = j - 1
Loop
If i <= j Then
temp = arr(i)
arr(i) = arr(j)
arr(j) = temp
i = i + 1
j = j - 1
End If
Loop
If first < j Then QuickSortStrings arr, first, j
If i < last Then QuickSortStrings arr, i, last
End Sub