Статьи из блога

Макрос преобразования числа в текст

На форуме Microsoft был задан вопрос:

Необходимо в тексте Word введенное число преобразовать в текст на русском.

Для того, чтобы преобразовать некое число в текстовый формат, вы можете воспользоваться специальными программами, о которых я писал в заметке Число или сумма прописью.

 

Но если вам нужно преобразовать уже введенное число, то здесь может помочь следующий макрос (ниже).

В коде макроса используется формула с ключом CardText. Но у этого ключа есть ограничение - максимальное число не может быть больше 999.999 (см. заметку Ключ CardText и его ограничения). Поэтому автор макроса идет на хитрость и объединяет поля.

Но в английском языке нет склонений и результат для преобразованного числа получается правильным для чисел свыше 1.000.000 - используется слово "million". В русском языке итоговый результат будет выглядеть не очень красиво. Поэтому я чуть-чуть подредактировал макрос, заменив слово "million" на "миллион(а/ов)". Тоже не совсем нормально но, по крайней мере, не так режет глаз грамматической неправильностью.

Sub BigCardText()
'преобразование целого числа в текстовый эквивалент
'источник - http://wordtips.vitalnews.com/
Dim sDigits As String
Dim sBigStuff As String
sBigStuff = ""
' Select the full number in which the insertion point is located
Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdMove
Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
' Store the digits in a variable
sDigits = Trim(Selection.Text)
If Val(sDigits) > 999999 Then
    If Val(sDigits) <= 999999999 Then
        sBigStuff = CStr(Val(sDigits) \ 1000000)
        ' Create a field containing the big digits and
        ' the cardtext format flag
        Selection.Fields.Add Range:=Selection.Range, _
          Type:=wdFieldEmpty, Text:="= " + sBigStuff + " \* CardText", _
          PreserveFormatting:=True
        ' Select the field and copy it
        Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
        sBigStuff = Selection.Text & " миллион(а/ов) "
        sDigits = Right(sDigits, 6)
    End If
End If
If Val(sDigits) <= 999999 Then
    ' Create a field containing the digits and the cardtext format flag
    Selection.Fields.Add Range:=Selection.Range, _
      Type:=wdFieldEmpty, Text:="= " + sDigits + " \* CardText", _
      PreserveFormatting:=True
    ' Select the field and copy it
    Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
    sDigits = sBigStuff & Selection.Text
    ' Now put the words in the document
    Selection.TypeText Text:=sDigits
    Selection.TypeText Text:=" "
Else
    MsgBox "Число слишком большое для преобразования", vbOKOnly
End If
End Sub

Если вы не знаете, как подключить к документу и применить этот макрос, изучите следующие заметки с сайта:

Создание макроса из готового кода

Автоматическая запись макроса

twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru rutvit.ru myspace.com technorati.com digg.com friendfeed.com pikabu.ru blogger.com liveinternet.ru livejournal.ru memori.ru google.com bobrdobr.ru mister-wong.ru yahoo.com yandex.ru del.icio.us

Еще записи по вопросам использования Microsoft Word:

Комментариев: 15

  1. 08.09.2008 в 15:35 | #1

    Посмотрим макрос дома, придумаем, чтобы было полностью грамматически правильно

  2. 08.09.2008 в 15:55 | #2

    Александр, приветствую.

    Придумать можно и есть решения для этого (перед публикацией заметки я анализировал страницы, найденные в сети по этой теме). Но решения слишком громоздкие и используют функции. Я просто не люблю больших макросов.

    Но в любом случае буду благодарен, если скините в комментарий подходящий код.

  3. 08.09.2008 в 22:34 | #3

    Ну вот, Антон, я попытался. Вроде бы работает. По крайней мере я не сумел подобрать «плохое» число. Пришлось писать функцию, но без нее получилось бы еще хуже, менее читабельно. А так, я надеюсь, все понятно.

    Sub BigCardText()
    'преобразование целого числа в текстовый эквивалент
    'источник - http://wordtips.vitalnews.com/Pages/T000203_Converting_Numbers_to_Text.html
    Dim sDigits As String
    Dim sBigStuff As String
    sDigits = ""
    sBigStuff = ""
    ' Select the full number in which the insertion point is located
    Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdMove
    Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
    ' Store the digits in a variable
    sDigits = Trim(Selection.Text)
    If Val(sDigits) > 999999 Then
        If Val(sDigits) <= 999999999 Then
            sBigStuff = CStr(Val(sDigits) \ 1000000)
            ' Create a field containing the big digits and
            ' the cardtext format flag
            Selection.Fields.Add Range:=Selection.Range, _
              Type:=wdFieldEmpty, Text:="= " + sBigStuff + " \* CardText", _
              PreserveFormatting:=True
            ' Select the field and copy it
            Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
            sBigStuff = Selection.Text & EndOfWord(Val(sBigStuff))
            sDigits = Right(sDigits, 6)
        End If
    End If
    If Val(sDigits) <= 999999 Then
        ' Create a field containing the digits and the cardtext format flag
        Selection.Fields.Add Range:=Selection.Range, _
          Type:=wdFieldEmpty, Text:="= " + sDigits + " \* CardText", _
          PreserveFormatting:=True
     
        ' Select the field and copy it
        Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
        sDigits = sBigStuff & Selection.Text
     
        ' Now put the words in the document
        Selection.TypeText Text:=sDigits
        Selection.TypeText Text:=" "
    Else
        MsgBox "Число слишком большое для преобразования", vbOKOnly
    End If
    End Sub
    'Вот эта функция. Берет аргумент в виде числа, чтобы 
    'быть более универсальной. Возвращает слово с нужным окончанием
    Private Function EndOfWord(nmbr As Integer) As String
    'число единиц находится в промежутке от 5 до 19
    If (Val(Right(CStr(nmbr), 2)) = 5) _
        Or Val(Right(CStr(nmbr), 1)) = 0 _
        Or (Val(Right(CStr(nmbr), 1)) >= 5 And Val(Right(CStr(nmbr), 1)) <= 9) Then
        EndOfWord = " миллионов "
        'число единиц равно единице
    ElseIf Val(Right(CStr(nmbr), 1)) = 1 Then
        EndOfWord = " миллион "
        'число единиц не больше четырех и больше единицы
        ElseIf Val(Right(CStr(nmbr), 1)) > 1 Then
            EndOfWord = " миллиона "
    End If
    End Function

  4. 09.09.2008 в 11:51 | #4

    Александр, спасибо - работает. Там была опечатка в коде - не хватало знака "больше" в строке

    ElseIf Val(Right(CStr(nmbr), 1)) 1 Then

    Поправил.

  5. Luna
    09.09.2008 в 12:15 | #5

    Немаловажный момент - чтобы результат преобразования гарантированно был на русском языке, необходимо заранее убедиться, что выделяемое число воспринимается Word'ом как русский текст:

    Сервис - Язык - Выбрать язык - Пометить выделенный текст как: "Русский"

    Если результат преобразования должен быть всегда по-русски, то эту процедуру лучше ввести в сам макрос

  6. Сергей
    25.09.2008 в 10:22 | #6

    Самой полезной оказалась макрос-прога Untaco (http://orlovs.pp.ru/soft.php).

    1. Удобно (установил и забыл в видел панели в Word).

    2. Работоспосбно

    3. Имеется расчет НДС

    4. Кое-что ещё настраивается.

    Рекомендую!

  7. Маша
    03.12.2009 в 21:02 | #7

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

    но все это надо сделать не применяя VBA

  8. 03.12.2009 в 21:58 | #8

    Пишем число. Помещаем его в закладку, скажем с именем MyNumber. После этого вставляем поле с таким содержимым:

    {= MyNumber \*CardText}

    Теперь при изменении содержимого закладки будет и изменяться содержимое поля

  9. Маша
    06.12.2009 в 12:52 | #9

    Делала все как вы написали, но не оплучилось(

    Вместо числа 100 код полей выдает ноль.

    Что же делать?

  10. 06.12.2009 в 22:14 | #10

    Число точно находится в закладке?

  11. FvR
    30.05.2010 в 11:18 | #11

    добавив проверку "на число" и подкорректировав вышеизложенную функцию получилось:

    Private Sub BigCardText(control As IRibbonControl)   'преобразование целого числа в текст
        Dim sDigits As String
        Dim sBigStuff As String
        sBigStuff = ""
        Selection.LanguageID = wdRussian
        Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdMove
        Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
        sDigits = Trim(Selection.Text)
        If IsNumeric(sDigits) = False Then MsgBox "Не является числом!", vbCritical, "": Exit Sub
        If Val(sDigits) > 999999 Then
            If Val(sDigits)

  12. 03.08.2010 в 20:09 | #12

    Есть макрос по преобразованию сумм в текст, с дополнительными данными (рубли, доллары, евро). Есть проблема, ноль не пишет.

    Word(1, 1) = "од": Word(2, 1) = "десять": Word(3, 1) = "сто"

    Word(1, 2) = "дв": Word(2, 2) = "двадцать": Word(3, 2) = "двести"

    Word(1, 3) = "три": Word(2, 3) = "òðèäöàòü": Word(3, 3) = "òðèñòà"

    Word(1, 4) = "÷åòûðå": Word(2, 4) = "ñîðîê": Word(3, 4) = "÷åòûðåñòà"

    Word(1, 5) = "ïÿòü": Word(2, 5) = "ïÿòüäåñÿò": Word(3, 5) = "ïÿòüñîò"

    Word(1, 6) = "øåñòü": Word(2, 6) = "øåñòüäåñÿò": Word(3, 6) = "øåñòüñîò"

    Word(1, 7) = "ñåìü": Word(2, 7) = "ñåìüäåñÿò": Word(3, 7) = "ñåìüñîò"

    Word(1, 8) = "âîñåìü": Word(2, 8) = "âîñåìüäåñÿò": Word(3, 8) = "âîñåìüñîò"

    Word(1, 9) = "äåâÿòü": Word(2, 9) = "äåâÿíîñòî": Word(3, 9) = "äåâÿòüñîò"

    в результате не пишет "ноль рублей (долларов)00 копеек (центов)", а по нормам заполнения это необходимо.

    В итоге добавил:

    Word(1, 0) = "ноль"

    на цифру 0,00 пишет "ноль рублей (долларов)00 копеек (центов)", а на цыфру 1780 пишет "одна тысяча восемьдесят ноль рублей (долларов)00 копеек (центов)"

    ХЭЛП

  13. Ложка
    08.11.2010 в 19:28 | #13

    Василий, проблема - это ведь неразрешимое(пока) противоречие. В поисках "0" вы прибегли к логической хитрости, поставив под сомнение и "правду и лож" (1, 0 = "ноль"). У вас возникла проблема несоответствия. Это, что-то вроде замка и ключа: ситуация - это замок, а ваше состояние - ключ от этого замка. А у вас получилось "Есть одно, а пишется совсем другое".

  14. Егор
    07.07.2011 в 17:30 | #14

    А не подскажите как автоматизировать Word так, чтобы он сам при обновлении полей, выводил число, помеченное в тексте закладкой - прописью. В принципе CardText меня устраивало, пока числа большие не пошли.

  15. Lazutchik71
    11.08.2018 в 09:06 | #15

    Всё замечательно.

    А можно ли в Worde сделать так же как в Exel, т.е. есть форма с ячейками например Расходный кассовый ордер в одной ячейке вбиваем цифрами в другой ячейке сразу преобразовывается в текст?

Оставьте комментарий!

(обязательно)

^ Наверх