Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Word
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.03.2010, 13:37   #1
Simbad
Пользователь
 
Регистрация: 10.12.2009
Сообщений: 62
Сообщение Как подсчитать количество букв?

Приветствую всех участников форума.
Подскажите, пожалуйста, как подсчитать количество английских и русских букв в документе?
Заранее спасибо тем кто собирается помочь
Simbad вне форума Ответить с цитированием
Старый 10.03.2010, 00:44   #2
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию Самодельная статистика

Вот буквально за час-десять наваял
Код:
Sub RusLettersEngLetters() 'подсчёт букв в документе (кроме сносок, надписей, колонтитулов и рисунков)'
Dim rus As Long, eng As Long, oth As Long, i As Long

With ActiveDocument.Range.Characters
    For i = 1 To .Count
    If .Item(i) Like "[А-яЁё]" Then rus = rus + 1     'счётчик русских букв'
    If .Item(i) Like "[A-z]" Then eng = eng + 1         'счётчик нерусских букв'
    If .Item(i) Like "[!A-zА-яЁё]" Then oth = oth + 1 'счётчик прочих знаков текста документа'
    Next
End With

MsgBox "В документе «" & ActiveDocument & "»" & String(2, Chr(13)) & _
"русских букв:" & String(3, Chr(9)) & rus & Chr(13) & _
"английских букв:" & String(3, Chr(9)) & eng & Chr(13) & _
"всего русских и английских букв:" & Chr(9) & rus + eng & Chr(13) & _
"прочих символов:" & String(3, Chr(9)) & oth & Chr(13) & Chr(13) & _
"символов по статистике Word:" & Chr(9) & ActiveDocument.ComputeStatistics(wdStatisticCharactersWithSpaces)

End Sub
Вообще тема, для общего развития, что надо! Жаль, что непопулярна (как, скажем, массивы:-)).
Изображения
Тип файла: png Results.png (9.8 Кб, 197 просмотров)

Последний раз редактировалось Sasha_Smirnov; 10.03.2010 в 12:50.
Sasha_Smirnov вне форума Ответить с цитированием
Старый 10.03.2010, 02:09   #3
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

Вместо Like быстрее будет работать ASC() и Select Case с интервалами
кодов. Помимо надписей текст может быть на шейпах.
Отдельный вопрос - нужно ли считать WordArt ?
Aent вне форума Ответить с цитированием
Старый 10.03.2010, 12:38   #4
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

Цитата:
Сообщение от Aent Посмотреть сообщение
Вместо Like быстрее будет работать ASC() и Select Case с интервалами кодов.
Предлагаю померяться скоростями! Или хотя бы дать примерную статистику.

Цитата:
Сообщение от Aent Посмотреть сообщение
Помимо надписей текст может быть на шейпах.
Отдельный вопрос - нужно ли считать WordArt ?
Ну это ж не загадка Шамаханской царицы!
Так и сам документ можно рассмотреть как квадратную О (финскую).
Sasha_Smirnov вне форума Ответить с цитированием
Старый 11.03.2010, 00:44   #5
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Дело было вечером,
делать было нечего ...


Результаты независимой экспертизы
В тексте порядка 900 знаков( русских и английских приблизительно поровну + прочих символов около сотни)
Вариант Sasha_Smirnov -около 30 секунд

Вариант Aent - около 6-7 секунд
Анализ,обработка данных Недорого

Последний раз редактировалось doober; 11.03.2010 в 00:57.
doober вне форума Ответить с цитированием
Старый 13.03.2010, 19:48   #6
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

Цитата:
Сообщение от doober Посмотреть сообщение
Вариант Aent - около 6-7 секунд
Код:
Sub LettersSeekAndCountWithTimer()
Dim rus As Long, eng As Long
Dim swMilliseconds As New StopWatch: swMilliseconds.StartTimer 'вкл. таймера'
    Selection.HomeKey wdStory 'переход в начало документа'

    With Selection.Find
        .Wrap = wdFindAsk
        .MatchWildcards = True
        
        .Text = "[А-яЁё]" 'шаблон для поиска русских букв'
        .Execute
                Do While .Found
                rus = rus + 1
                .Execute
                Loop
        
     Selection.HomeKey wdStory
        .Text = "[A-z]" 'шаблон для поиска английских букв'
        .Execute
                Do While .Found
                eng = eng + 1
                .Execute
                Loop
    End With
    
    MsgBox "Подсчёт занял " & Format(swMilliseconds.EndTimer / 1000, "0.000 секунды."), vbInformation
    MsgBox "Русских букв: " & rus & "; английских букв: " & eng & ".", vbInformation
End Sub
работает на порядок* быстрее. Вот она мощь метода Find!

Используемый для хронометража класс StopWatch — в приложенном документе.
_________________________
* по основанию 10, разумеется
Изображения
Тип файла: jpg РусскиеБуквы.jpg (45.0 Кб, 138 просмотров)
Вложения
Тип файла: doc Собственно.doc (34.0 Кб, 34 просмотров)
Sasha_Smirnov вне форума Ответить с цитированием
Старый 12.05.2010, 12:51   #7
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

Цитата:
Сообщение от Sasha_Smirnov Посмотреть сообщение
работает на порядок быстрее. Вот она мощь метода Find!
Нет, мощь оказалась в стандартном линейном программировании:

Код:
Sub Letters2()
    Dim strTemp As String
    Dim ДлинаТекста As Long, i As Long
    Dim rus As Long, eng As Long
    Dim swMilliseconds As New StopWatch: swMilliseconds.StartTimer 'вкл. таймера'
    
    Selection.HomeKey Unit:=wdStory                     'Устанавливает курсор в начало текста'
    Selection.EndKey Unit:=wdStory, Extend:=wdExtend    'выделяет весь текст'
    
    strTemp = Selection.Text        'Загружает выделенный текст в переменную'
    ДлинаТекста = Len(strTemp)      'Длина текста'

    For i = 1 To ДлинаТекста
        a = Mid(strTemp, i, 1)
        If (a >= "а" And a <= "я") Or a = "ё" Or (a >= "А" And a <= "Я") Or a = "Ё" Then
            rus = rus + 1
        Else
            If (a >= "a" And a <= "z") Or (a >= "A" And a <= "Z") Then
                eng = eng + 1
            End If
        End If
    Next i

    MsgBox "Подсчёт занял " & Format(swMilliseconds.EndTimer / 1000, "0.000 секунды."), vbInformation
    MsgBox "Русских букв: " & rus & "; английских букв: " & eng & ".", vbInformation
End Sub
работает на 2 порядка быстрее. 0,015 сек против 0,402 сек
Оба варианта во вложенном файле
Вложения
Тип файла: doc Подсчёт числа знаков в тексте.doc (43.0 Кб, 40 просмотров)
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 12.05.2010, 16:56   #8
Sasha_Smirnov
Особый статус
Участник клуба
 
Аватар для Sasha_Smirnov
 
Регистрация: 24.11.2008
Сообщений: 1,535
По умолчанию

Супер! Нечего добавить. (Жаль, зачинатель темы не оценил!)
Sasha_Smirnov вне форума Ответить с цитированием
Старый 13.05.2010, 10:15   #9
Skif-F
Форумчанин
 
Регистрация: 24.03.2010
Сообщений: 349
По умолчанию

Цитата:
Сообщение от Sasha_Smirnov Посмотреть сообщение
(Жаль, зачинатель темы не оценил!)
Ничего, я не в обиде. Просто я поздно нашёл этот форум
Нет нерешаемых задач - есть недостаток времени и данных!
Skif-F вне форума Ответить с цитированием
Старый 13.05.2010, 12:57   #10
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

Ну раз начали выкусывать миллисекунды...:
Код:

Sub Letters2()
    Dim strTemp As String
    Dim ДлинаТекста As Long, i As Long
    Dim rus As Long, eng As Long
    Dim swMilliseconds As New StopWatch: swMilliseconds.StartTimer 'вкл. таймера'
    
    Selection.HomeKey Unit:=wdStory                     'Устанавливает курсор в начало текста
    Selection.EndKey Unit:=wdStory, Extend:=wdExtend    'выделяет весь текст
    
    strTemp = Selection.Text        'Загружает выделенный текст в переменную
    ДлинаТекста = Len(strTemp)      'Длина текста

    For i = 1 To ДлинаТекста
        a = Mid(strTemp, i, 1)
        If (a >= "а" And a <= "я") Or a = "ё" Or (a >= "А" And a <= "Я") Or a = "Ё" Then
            rus = rus + 1
        Else
            If (a >= "a" And a <= "z") Or (a >= "A" And a <= "Z") Then
                eng = eng + 1
            End If
        End If
    Next i

    Debug.Print "Letters2: Подсчёт занял " & Format(swMilliseconds.EndTimer / 1000, "0.000 секунды.") & vbCr & _
                "Русских букв: " & rus & "; английских букв: " & eng & "."
End Sub
Sub Letters3()
    Dim strTemp As String
    Dim ДлинаТекста As Long, i As Long
    Dim rus As Long, eng As Long
    Dim swMilliseconds As New StopWatch: swMilliseconds.StartTimer 'вкл. таймера'
        
    strTemp = ActiveDocument.Content.Text        'Загружает текст в переменную
    ДлинаТекста = Len(strTemp)      'Длина текста

    For i = 1 To ДлинаТекста
        a = Asc(Mid(strTemp, i, 1))
        Select Case a
            Case 192 To 255 'а-Я
                rus = rus + 1
            Case 184, 168   'ё,Ё
                rus = rus + 1
            Case 97 To 122, 65 To 90
                eng = eng + 1
        End Select
    Next i
    Debug.Print "Letters3: Подсчёт занял " & Format(swMilliseconds.EndTimer / 1000, "0.000 секунды.") & vbCr & _
                "Русских букв: " & rus & "; английских букв: " & eng & "."
End Sub
На приведённом выше файле:
Цитата:
Letters2: Подсчёт занял 0,002 секунды.
Русских букв: 726; английских букв: 34.
Letters3: Подсчёт занял 0,001 секунды.
Русских букв: 726; английских букв: 34.
В нескольких тестах результат Letters3 был меньше 1 мс
Выигрыш впрочем идёт не за счёт Select а из-за
Код:
strTemp = ActiveDocument.Content.Text

Последний раз редактировалось Aent; 13.05.2010 в 13:04.
Aent вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как подсчитать количество букв а в строке Оксана33 Общие вопросы по Java, Java SE, Kotlin 1 24.09.2015 15:59
C# Подсчитать количество согласных букв SmailikEKB Помощь студентам 1 17.05.2013 23:02
Подсчитать количество введенных букв WebbMan Паскаль, Turbo Pascal, PascalABC.NET 10 01.04.2011 17:20
Подсчитать количество букв "А" в предложении и общее количество букв.В тексте из файла несколько строк. kvas91 Общие вопросы C/C++ 3 14.11.2010 16:51
Подсчитать количество слов и количество букв MDSIQ Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 13.11.2010 16:57