Attribute VB_Name = "SummaPropisyu" Option Explicit ' Public function: =SUMMA_RU(A1). RUB only, rounds to two decimal places. ' Source: https://summa-propisyu-online.ru/summa-propisyu-v-excel/ ' No network, file access or workbook modifications. Public Function SUMMA_RU(ByVal amount As Variant) As Variant On Error GoTo InvalidInput If IsError(amount) Then GoTo InvalidInput If IsEmpty(amount) Then SUMMA_RU = "" Exit Function End If If VarType(amount) = vbString Then If Len(amount) = 0 Then SUMMA_RU = "" Exit Function End If GoTo InvalidInput End If If VarType(amount) = vbString Or VarType(amount) = vbBoolean Or Not IsNumeric(amount) Then GoTo InvalidInput If CDec(amount) < 0 Or CDec(amount) >= CDec(1000000000000#) Then GoTo InvalidInput Dim total As Variant, whole As Variant, remaining As Variant Dim cents As Long, chunk As Long, level As Long, output As String, words As String total = Fix(CDec(amount) * 100 + CDec(0.5)) If total >= CDec(100000000000000#) Then GoTo InvalidInput whole = Fix(total / 100) remaining = whole cents = CLng(total - whole * 100) Do While remaining > 0 chunk = CLng(remaining - Fix(remaining / 1000) * 1000) If chunk > 0 Then words = SP_Triplet(chunk, level = 1) Select Case level Case 1: words = words & " " & SP_Form(chunk, SP_Unicode("0442044b0441044f04470430007c0442044b0441044f04470438007c0442044b0441044f0447")) Case 2: words = words & " " & SP_Form(chunk, SP_Unicode("043c0438043b043b0438043e043d007c043c0438043b043b0438043e043d0430007c043c0438043b043b0438043e043d043e0432")) Case 3: words = words & " " & SP_Form(chunk, SP_Unicode("043c0438043b043b0438043004400434007c043c0438043b043b04380430044004340430007c043c0438043b043b0438043004400434043e0432")) End Select output = words & " " & output End If remaining = Fix(remaining / 1000) level = level + 1 Loop If whole = 0 Then output = SP_Unicode("043d043e043b044c") chunk = CLng(whole - Fix(whole / 100) * 100) output = Trim$(output) & " " & SP_Form(chunk, SP_Unicode("044004430431043b044c007c044004430431043b044f007c044004430431043b04350439")) & " " & Format$(cents, "00") & " " & SP_Form(cents, SP_Unicode("043a043e043f04350439043a0430007c043a043e043f04350439043a0438007c043a043e043f04350435043a")) SUMMA_RU = UCase$(Left$(output, 1)) & Mid$(output, 2) Exit Function InvalidInput: SUMMA_RU = CVErr(xlErrValue) End Function Private Function SP_Form(ByVal n As Long, ByVal variants As String) As String Dim items As Variant, ending As Long, lastTwo As Long items = Split(variants, "|") lastTwo = n Mod 100 ending = 2 If lastTwo < 11 Or lastTwo > 19 Then If n Mod 10 = 1 Then ending = 0 If n Mod 10 >= 2 And n Mod 10 <= 4 Then ending = 1 End If SP_Form = items(ending) End Function Private Function SP_Triplet(ByVal n As Long, ByVal female As Boolean) As String Dim ones As Variant, teens As Variant, tens As Variant, hundreds As Variant Dim result As String, remainder As Long If female Then ones = Split(SP_Unicode("007c043e0434043d0430007c043404320435007c044204400438007c044704350442044b04400435007c043f044f0442044c007c0448043504410442044c007c04410435043c044c007c0432043e0441" & _ "0435043c044c007c043404350432044f0442044c"), "|") Else ones = Split(SP_Unicode("007c043e04340438043d007c043404320430007c044204400438007c044704350442044b04400435007c043f044f0442044c007c0448043504410442044c007c04410435043c044c007c0432043e0441" & _ "0435043c044c007c043404350432044f0442044c"), "|") End If teens = Split(SP_Unicode("043404350441044f0442044c007c043e04340438043d043d04300434044604300442044c007c043404320435043d04300434044604300442044c007c044204400438043d04300434044604300442044c" & _ "007c044704350442044b0440043d04300434044604300442044c007c043f044f0442043d04300434044604300442044c007c0448043504410442043d04300434044604300442044c007c04410435043c" & _ "043d04300434044604300442044c007c0432043e04410435043c043d04300434044604300442044c007c043404350432044f0442043d04300434044604300442044c"), "|") tens = Split(SP_Unicode("007c007c0434043204300434044604300442044c007c0442044004380434044604300442044c007c0441043e0440043e043a007c043f044f0442044c043404350441044f0442007c0448043504410442" & _ "044c043404350441044f0442007c04410435043c044c043404350441044f0442007c0432043e04410435043c044c043404350441044f0442007c043404350432044f043d043e04410442043e"), "|") hundreds = Split(SP_Unicode("007c04410442043e007c043404320435044104420438007c044204400438044104420430007c044704350442044b04400435044104420430007c043f044f0442044c0441043e0442007c044804350441" & _ "0442044c0441043e0442007c04410435043c044c0441043e0442007c0432043e04410435043c044c0441043e0442007c043404350432044f0442044c0441043e0442"), "|") result = hundreds(n \ 100) remainder = n Mod 100 If remainder >= 10 And remainder <= 19 Then result = result & " " & teens(remainder - 10) Else result = result & " " & tens(remainder \ 10) & " " & ones(remainder Mod 10) End If SP_Triplet = Trim$(Replace(result, " ", " ")) End Function ' ASCII source avoids dependence on the VBA editor's Windows code page. Private Function SP_Unicode(ByVal hexText As String) As String Dim i As Long, result As String For i = 1 To Len(hexText) Step 4 result = result & ChrW$(CLng("&H" & Mid$(hexText, i, 4))) Next i SP_Unicode = result End Function