Народ, тут понадобилось договора писать, а там сумма прописью... Можно было бы, конечно, и имеющимися наработками для Excel'я воспользоваться, но я у себя в копилке нашёл, что числа до 999999 можно в текст прямо Вордом перегонять (например, здесь, здесь, здесь, ...). Решил попробовать. Вот что примерно получилось:
И всё бы, наверное, и ничего, да вот только триады цифр в документе для читабельности обычно разбиваются пробелом. А с пробелами не пашет. Попытался тупо заменить пробел на "пустышку" Replace'ом в Selection.Range.Text - не вышло - макрос стал давать ошибку в формуле... Я объектную модель Ворда практически не знаю. Тыкаю почти наугад по аналогии с Excel'ем Конечно, идеалом было бы допилить макрос так, чтобы он ПОСЛЕ (а не ВМЕСТО) выделенного числа выдавал его же прописью, но это уже не так важно.
Народ, тут понадобилось договора писать, а там сумма прописью... Можно было бы, конечно, и имеющимися наработками для Excel'я воспользоваться, но я у себя в копилке нашёл, что числа до 999999 можно в текст прямо Вордом перегонять (например, здесь, здесь, здесь, ...). Решил попробовать. Вот что примерно получилось:
И всё бы, наверное, и ничего, да вот только триады цифр в документе для читабельности обычно разбиваются пробелом. А с пробелами не пашет. Попытался тупо заменить пробел на "пустышку" Replace'ом в Selection.Range.Text - не вышло - макрос стал давать ошибку в формуле... Я объектную модель Ворда практически не знаю. Тыкаю почти наугад по аналогии с Excel'ем Конечно, идеалом было бы допилить макрос так, чтобы он ПОСЛЕ (а не ВМЕСТО) выделенного числа выдавал его же прописью, но это уже не так важно.Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Понедельник, 28.10.2013, 16:33
Poltava, спасибо за совет и попытку помочь. А со вставкой после подождём, может быть кто-нибудь из более продвинутых в Ворде чем мы откликнется. А то, глядишь, и сумму прописью от МСН прикрутим чтобы снять ограничения
Poltava, спасибо за совет и попытку помочь. А со вставкой после подождём, может быть кто-нибудь из более продвинутых в Ворде чем мы откликнется. А то, глядишь, и сумму прописью от МСН прикрутим чтобы снять ограниченияAlex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Вторник, 29.10.2013, 14:40
Народ, спасибо за отзывы. К сожалению, уже опять меня настиг завал на работе и разбираться совершенно некогда. А внутренние средства Ворда я для того применил, т.к. была задумка чтобы сумма прописью вводилась макросом как поле, вычисляемое по сумме цифрами, которую можно было бы потом спокойно изменять в ручную (ну как у нас, нормальных в Excel'e формула, использующая UDF).
Хотя всё-таки не удержался и проверил вариант от RAN Андрей! Спасибо большое. Отлично работает!
Народ, спасибо за отзывы. К сожалению, уже опять меня настиг завал на работе и разбираться совершенно некогда. А внутренние средства Ворда я для того применил, т.к. была задумка чтобы сумма прописью вводилась макросом как поле, вычисляемое по сумме цифрами, которую можно было бы потом спокойно изменять в ручную (ну как у нас, нормальных в Excel'e формула, использующая UDF).
Хотя всё-таки не удержался и проверил вариант от RAN Андрей! Спасибо большое. Отлично работает!Alex_ST
даёт инвалид-аргумент при выделенном 123456 на листе
Оффтоп: А объектную модель-то Ворда, оказывается кто-то всё-таки знает... Столько абсолютно ничего не говорящих мне свойств, методов и параметров в коде!
даёт инвалид-аргумент при выделенном 123456 на листе [offtop]А объектную модель-то Ворда, оказывается кто-то всё-таки знает... Столько абсолютно ничего не говорящих мне свойств, методов и параметров в коде![/offtop]Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Вторник, 29.10.2013, 13:36
Выдалась минутка поковыряться с вариантом, предложенным RAN Решил, что число прописью лучше вставлять в буфер обмена, а уж пользователь сам потом будет решать, рубли там или юани и куда их вставлять. Вот что получилось:
Sub Прописью() Dim NNN OnErrorResumeNext WithCreateObject("VBScript.RegExp"): .Global = True: .Pattern = "\D": NNN = CDbl(.Replace(Selection.Range.Text, "")): EndWith
NNN = IIf(Err, Err.Description, СУМ_ПРОП(NNN)) WithGetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .SetText NNN: .PutInClipBoard: EndWith EndSub Function СУМ_ПРОП$(ByVal ЧИСЛО#) ' http://www.excelworld.ru/forum/3-3521-1 Author MCH (Михаил Ч.), май 2012 Dim rub$, kop$, ed, des, sot, nadc, RAZR, i&, m$ If ЧИСЛО >= 1E+15Or ЧИСЛО < 0ThenExitFunction
sot = Array("", "сто ", "двести ", "триста ", "четыреста ", "пятьсот ", "шестьсот ", "семьсот ", "восемьсот ", "девятьсот ")
des = Array("", "", "двадцать ", "тридцать ", "сорок ", "пятьдесят ", "шестьдесят ", "семьдесят ", "восемьдесят ", "девяносто ")
nadc = Array("десять ", "одиннадцать ", "двенадцать ", "тринадцать ", "четырнадцать ", "пятнадцать ", "шестнадцать ", "семнадцать ", "восемнадцать ", "девятнадцать ")
ed = Array("", "один ", "два ", "три ", "четыре ", "пять ", "шесть ", "семь ", "восемь ", "девять ", "", "одна ", "две ")
RAZR = Array("триллион ", "триллиона ", "триллионов ", "миллиард ", "миллиарда ", "миллиардов ", "миллион ", "миллиона ", "миллионов ", "тысяча ", "тысячи ", "тысяч ", "", "", "")
rub = Left(Format(ЧИСЛО, "000000000000000.00"), 15)
kop = Right(Format(ЧИСЛО, "0.00"), 2) IfCDbl(rub) = 0Then m = "ноль " For i = 1ToLen(rub) Step3 IfMid(rub, i, 3) <> "000"Or i = Len(rub) - 2Then
m = m & sot(CInt(Mid(rub, i, 1))) & IIf(Mid(rub, i + 1, 1) = "1", nadc(CInt(Mid(rub, i + 2, 1))), _
des(CInt(Mid(rub, i + 1, 1))) & ed(CInt(Mid(rub, i + 2, 1)) + IIf(i = Len(rub) - 5AndCInt(Mid(rub, i + 2, 1)) < 3, 10, 0))) & _ IIf(Mid(rub, i + 1, 1) = "1"Or (Mid(rub, i + 2, 1) + 9) Mod10 >= 4, RAZR(i + 1), IIf(Mid(rub, i + 2, 1) = "1", RAZR(i - 1), RAZR(i))) EndIf Next i
СУМ_ПРОП = UCase(Left(m, 1)) & Mid(m, 2) EndFunction
Выдалась минутка поковыряться с вариантом, предложенным RAN Решил, что число прописью лучше вставлять в буфер обмена, а уж пользователь сам потом будет решать, рубли там или юани и куда их вставлять. Вот что получилось:
Sub Прописью() Dim NNN OnErrorResumeNext WithCreateObject("VBScript.RegExp"): .Global = True: .Pattern = "\D": NNN = CDbl(.Replace(Selection.Range.Text, "")): EndWith
NNN = IIf(Err, Err.Description, СУМ_ПРОП(NNN)) WithGetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .SetText NNN: .PutInClipBoard: EndWith EndSub Function СУМ_ПРОП$(ByVal ЧИСЛО#) ' http://www.excelworld.ru/forum/3-3521-1 Author MCH (Михаил Ч.), май 2012 Dim rub$, kop$, ed, des, sot, nadc, RAZR, i&, m$ If ЧИСЛО >= 1E+15Or ЧИСЛО < 0ThenExitFunction
sot = Array("", "сто ", "двести ", "триста ", "четыреста ", "пятьсот ", "шестьсот ", "семьсот ", "восемьсот ", "девятьсот ")
des = Array("", "", "двадцать ", "тридцать ", "сорок ", "пятьдесят ", "шестьдесят ", "семьдесят ", "восемьдесят ", "девяносто ")
nadc = Array("десять ", "одиннадцать ", "двенадцать ", "тринадцать ", "четырнадцать ", "пятнадцать ", "шестнадцать ", "семнадцать ", "восемнадцать ", "девятнадцать ")
ed = Array("", "один ", "два ", "три ", "четыре ", "пять ", "шесть ", "семь ", "восемь ", "девять ", "", "одна ", "две ")
RAZR = Array("триллион ", "триллиона ", "триллионов ", "миллиард ", "миллиарда ", "миллиардов ", "миллион ", "миллиона ", "миллионов ", "тысяча ", "тысячи ", "тысяч ", "", "", "")
rub = Left(Format(ЧИСЛО, "000000000000000.00"), 15)
kop = Right(Format(ЧИСЛО, "0.00"), 2) IfCDbl(rub) = 0Then m = "ноль " For i = 1ToLen(rub) Step3 IfMid(rub, i, 3) <> "000"Or i = Len(rub) - 2Then
m = m & sot(CInt(Mid(rub, i, 1))) & IIf(Mid(rub, i + 1, 1) = "1", nadc(CInt(Mid(rub, i + 2, 1))), _
des(CInt(Mid(rub, i + 1, 1))) & ed(CInt(Mid(rub, i + 2, 1)) + IIf(i = Len(rub) - 5AndCInt(Mid(rub, i + 2, 1)) < 3, 10, 0))) & _ IIf(Mid(rub, i + 1, 1) = "1"Or (Mid(rub, i + 2, 1) + 9) Mod10 >= 4, RAZR(i + 1), IIf(Mid(rub, i + 2, 1) = "1", RAZR(i - 1), RAZR(i))) EndIf Next i
СУМ_ПРОП = UCase(Left(m, 1)) & Mid(m, 2) EndFunction
А если не выделять ничего? Просто курсор поставить "посреди" числа? Я больше ориентировался на то, чтобы не заставлять пользователя выделять число (и ещё обычно при ручном выделении дефолтный Expand срабатывает, расширяя область выделения по своему разумению).
По ошибке - это Word VBA, гад, всё равно считает в Left(,-1) в IIF() ... можно сделать
Что касается "сумма вводилась как поле" - она и так вводится в поле. Поэтому, кстати, исходный вариант и предполагал замену текста полем, чтобы число оставалось единственным. А чтобы можно было "менять сумму", не заходя в поле - надо либо текст преобразовать в поле с меткой (закладкой), на которую потом будет ссылаться сумма прописью, либо отслеживать изменение текста и перезаписывать/пересоздавать поле с прописью. Ещё хочу заметить - .MoveRight Unit:=wdWord сдвинет точку ввода хоть и на конец цифр - но там может стоять разделитель Например, сумма записана (как это любят бухи) "123456=00" - тогда что? Да и число может быть "Ноль" (например, остаток суммы оплаты)...
А если не выделять ничего? Просто курсор поставить "посреди" числа? Я больше ориентировался на то, чтобы не заставлять пользователя выделять число (и ещё обычно при ручном выделении дефолтный Expand срабатывает, расширяя область выделения по своему разумению).
По ошибке - это Word VBA, гад, всё равно считает в Left(,-1) в IIF() ... можно сделать
Что касается "сумма вводилась как поле" - она и так вводится в поле. Поэтому, кстати, исходный вариант и предполагал замену текста полем, чтобы число оставалось единственным. А чтобы можно было "менять сумму", не заходя в поле - надо либо текст преобразовать в поле с меткой (закладкой), на которую потом будет ссылаться сумма прописью, либо отслеживать изменение текста и перезаписывать/пересоздавать поле с прописью. Ещё хочу заметить - .MoveRight Unit:=wdWord сдвинет точку ввода хоть и на конец цифр - но там может стоять разделитель Например, сумма записана (как это любят бухи) "123456=00" - тогда что? Да и число может быть "Ноль" (например, остаток суммы оплаты)...AndreTM
Skype: andre.tm.007 Donate: Qiwi: 9517375010
Сообщение отредактировал AndreTM - Вторник, 29.10.2013, 22:24
А если не выделять ничего? Просто курсор поставить "посреди" числа? Я больше ориентировался на то, чтобы не заставлять пользователя выделять число
Андрей, как раз этот вариант скорее всего не прокатит, т.к. бухгалтеры чаще всего цифры разделяют пробелами на триады. Тогда в Вашем варианте при курсоре, стоящем между двоек в числе, например, 111 222 333, в пропись будет преобразовано только 222. Так что как раз пользователь и должен напрячь чуть-чуть извилины и выделить именно всё то, что он хочет преобразовать. В моём крайнем примере регулярка как раз это и делает - из выделенного фрагмента удаляет все символы кроме цифр.
А если не выделять ничего? Просто курсор поставить "посреди" числа? Я больше ориентировался на то, чтобы не заставлять пользователя выделять число
Андрей, как раз этот вариант скорее всего не прокатит, т.к. бухгалтеры чаще всего цифры разделяют пробелами на триады. Тогда в Вашем варианте при курсоре, стоящем между двоек в числе, например, 111 222 333, в пропись будет преобразовано только 222. Так что как раз пользователь и должен напрячь чуть-чуть извилины и выделить именно всё то, что он хочет преобразовать. В моём крайнем примере регулярка как раз это и делает - из выделенного фрагмента удаляет все символы кроме цифр.
Не пробовал, т.к. выяснилось, что 999 999 всё равно мало. А должно было получиться? Ну ты бы хоть полный текст процедуры выложил тогда, а не фрагмент чтобы его можно было просто не заморачиваясь началом и концом процедуры проверить.
??? Это что, у вас в бюстгалтерии так принято: вместо запятой в качестве разделителя рублей и копеек = использовать? Уж сколько разных договоров из разных мест видел, а такого - нет!
Не пробовал, т.к. выяснилось, что 999 999 всё равно мало. А должно было получиться? Ну ты бы хоть полный текст процедуры выложил тогда, а не фрагмент чтобы его можно было просто не заморачиваясь началом и концом процедуры проверить.
??? Это что, у вас в бюстгалтерии так принято: вместо запятой в качестве разделителя рублей и копеек = использовать? Уж сколько разных договоров из разных мест видел, а такого - нет!Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Среда, 30.10.2013, 19:23