배움터  
  HOME > 배움터 > 무료강좌
무료강좌
 
엑셀, 곽승주님의 오튜공구함 제작으로 배워보는 VBA 이야기, Excel
  

12. 금액을 한글/한자/영어로 변환

자료다운로드 : 오튜공구함012.xls 

안녕하세요 오튜가족 여러분!

지난 시간에는 기존의 영문변환소스를 가지고 작업을 했는데 이번 시간에는 숫자로 표시된 금액을 한글 또는 한자영어로 변경하는 기능을 완성해보려고 합니다. 한글과 한자로 변환하는 기능은 영문일때와는 약간 다릅니다. 영문에서는 소수점 이하는 센트(Cent)로 처리하였지만 한글과 한자변환에서는 소수점 이하를 반올림하여 변환합니다. 그리고 한글과 한자는 표시하는 글자만 다르지 논리적인 방법은 동일합니다. 그러나 소스를 간편하게 보이게 하기 위해 한글변환루틴과 한자변환루틴을 각각 만들었습니다.

먼저 한글변환루틴과 한자변환루틴을 보여드리겠습니다.

'전역상수
Const ERR_TOOBIG = 6
Const ERR_NOTNUMBER = 13
Const NUM_HANGUL = "일이삼사오육칠팔구"
Const NUM_HANJA = "壹貳參四五六七八九"

'한글변환루틴
Function ConvertCurrencyToHangul(NumberText As String) As String
     Dim curAmount As Currency
     Dim StringReturn As String
     Dim strAmount As String
     Dim TmpString As String
     Dim AmountLength As Integer
     Dim I As Integer

     On Error GoTo ErrHandler

     curAmount = Format(NumberText, "#")
     AmountLength = Len(CStr(curAmount))
     strAmount = ""

     For i = AmountLength To 1 Step -1
          strAmount = strAmount & Mid(CStr(curAmount), i, 1)
     Next I

     For i = 1 To AmountLength
           If Mid(strAmount, i, 1) = "0" Then
               TmpString = ""
           Else
                TmpString = Mid(NUM_HANGUL, Mid(strAmount, i, 1), 1)
            Select Case I
            Case 4, 8, 12
                 TmpString = TmpString & "천"
            Case 3, 7, 11, 15
                 TmpString = TmpString & "백"
            Case 2, 6, 10, 14
                 TmpString = TmpString & "십"
            End Select
        End If
        Select Case I
        Case 13
             TmpString = TmpString & "조"
        Case 9
             TmpString = TmpString & "억"
        Case 5
             TmpString = TmpString & "만"
        End Select
          StringReturn = TmpString & StringReturn
     Next I
     ConvertCurrencyToHangul = "일금 " & StringReturn & "원정"

ErrHandler:
     Select Case Err
     Case ERR_TOOBIG
          MsgBox "입력한 숫자가 너무 큽니다.", vbExclamation
     Case ERR_NOTNUMBER
          If txtNumber = "" Then Resume Next
          MsgBo   x "입력한 내용이 숫자가 아닙니다.", vbExclamation
     End Select

End Function
'한자변환루틴
Function ConvertCurrencyToHanja(NumberText As String) As String
     Dim curAmount As Currency
     Dim StringReturn As String
     Dim strAmount As String
     Dim TmpString As String
     Dim AmountLength As Integer
     Dim i As Integer

     On Error GoTo ErrHandler

     curAmount = Format(NumberText, "#")
     AmountLength = Len(CStr(curAmount))
     strAmount = ""

     For i = AmountLength To 1 Step -1
          strAmount = strAmount & Mid(CStr(curAmount), i, 1)
     Next I

     For i = 1 To AmountLength
          If Mid(strAmount, i, 1) = "0" Then
              TmpString = ""
          Else
              TmpString = Mid(NUM_HANJA, Mid(strAmount, i, 1), 1)
              Select Case i
          Case 4, 8, 12
               TmpString = TmpString & "阡"
          Case 3, 7, 11, 15
               TmpString = TmpString & "百"
          Case 2, 6, 10, 14
               TmpString = TmpString & "拾"
          End Select
       End If
       Select Case I
       Case 13
            TmpString = TmpString & "兆"
       Case 9
            TmpString = TmpString & "億"
       Case 5
            TmpString = TmpString & "萬"
        End Select
          StringReturn = TmpString & StringReturn
     Next I
     ConvertCurrencyToHanja = "一金 " & StringReturn & "원 整"

ErrHandler:
     Select Case Err
     Case ERR_TOOBIG
           MsgBox "입력한 숫자가 너무 큽니다.", vbExclamation
     Case ERR_NOTNUMBER
           If txtNumber = "" Then Resume Next
           MsgBox "입력한 내용이 숫자가 아닙니다.", vbExclamation
      End Select

End Function

전역상수에 대해 말씀 드리자면 이것은 모듈의 선두 선언하여 현재의 모듈 내에서 모든 프로시져와 함수가 이용 가능한 상수입니다. 여기에서 사용하는 전역상수에는 에러를 처리하기 위한 상수 ERR_TOOBIG과 ERR_NOTNUMBER이 있습니다. 이것은 그 이름에서도 알 수 있듯이 사용자가 입력하는 내용이 처리하기 곤란한 지나치게 큰 숫자이거나 숫자가 아닌 경우를 대비한 것입니다.

Const ERR_TOOBIG = 6
Const ERR_NOTNUMBER = 13

또한 변환할 한글과 한자를 상수로 정의해 두었습니다.
Const NUM_HANGUL = "일이삼사오육칠팔구"
Const NUM_HANJA = "壹貳參四五六七八九"

Function ConvertCurrencyToHangul(NumberText As String)와 Function ConvertCurrencyToHanja(NumberText As String) 함수는 거의 동일한 것이므로 Function ConvertCurrencyToHangul(NumberText As String)만 설명해보겠습니다. 

Function ConvertCurrencyToHangul(NumberText As String) As String
함수는 매개변수로 NumberText라는 스트링형 데이터를 받습니다. 그렇지만 내용은 숫자이죠. 초보로서는 문자열자료를 받는데, 내용은 숫자라는 말이 이해가 안 갈지도 모릅니다. "9"는 숫자로서는 아홉 개, 아홉 번째를 의미합니다. 숫자로서 곱하기,빼기,더하기,나누기 등등의 연산의 대상이 됩니다. 그러나 이는 남과 다르다는 것을 표시하는 문자로 사용되기도 합니다. "9"가 시내버스의 번호라든가, 자신이 사는 아파트동의 숫자를 의미할 수 도 있습니다. 이것은 연산의 대상이 아니죠. 전화번호도 숫자로 이루어졌지만 이것으로 무슨 더하거나 빼는 일을 하진 않습니다. 즉 숫자는 연산의 대상이기도 하지만 문자로서는 표시의 수단이기도 합니다. 

     Dim curAmount    As Currency
curAmount는 NumberText과 같은 내용을 가지지만 문자가 아닌 숫자로 가집니다. 그런데 데이터형이 Currency형이군요. 처음 VBA를 배울 때 슬쩍 지나쳐버린 데이터 형입니다. 이것은 말 그대로 화폐를 표시하기 위한 데이터 형입니다. 도움말에 따르면, { 정수 유형의 64 비트(8 바이트) 숫자로 저장됩니다. 정수 부분 15자리와 소수점 이하 4자리의 고정 소수점을 주기 위하여, 10,000 단위로 잘라서 이 값은 922,337,203,685,477.5808부터 922,337,203,685,477.5807까지 표현이 가능합니다} 라고 되어 있습니다. 

     Dim StringReturn As String
     Dim strAmount As String
     Dim TmpString As String
     Dim AmountLength As Integer
     Dim I As Integer

     On Error GoTo ErrHandler

     curAmount = Format(NumberText, "#")
입력받은 문자열을 숫자로 변환합니다.

     AmountLength = Len(CStr(curAmount))
각 자리수의 숫자를 문자로 변환하기 위해 몇 개의 자리수인가를 헤아립니다. 이때AmountLength = Len(NumberText)로 하지 않고 굳이 숫자로 변환 한 것을 다시 문자로 변환하여 자리수를 세는 이유는 ","(쉼표) 때문입니다. 혹시 사용자가 천단위마다 ","표시를 해 두어NumberText에 "123,456"이 있다면 이를 Len()함수를 사용하여 세어보면 6자리가 아니라 7자리가 됩니다. 그러나 이를 curAmount = Format(NumberText, "#") 과 같이 숫자로 변환한 후 다시 문자로 변환하면 "123456"이 되므로 정확하게 6자리수가 나옵니다.

     strAmount = ""

     For i = AmountLength To 1 Step -1
          strAmount = strAmount & Mid(CStr(curAmount), i, 1)
     Next I
변환을 아랫자리 수부터 하기 위해 "123456"을 "654321"처럼 뒤집습니다. 여러분도 "일, 십, 백, 천, 만, …"을 중얼거리며 숫자를 세어나가는 것처럼 여기에서도 낮은 단위부터 문자로 변환하는 것이 편리하여 문자를 뒤집습니다.

     For i = 1 To AmountLength
여기서부터는 뒤집어놓은 문자열을 하나 하나 꺼내어 문자로 변환합니다. 
           If Mid(strAmount, i, 1) = "0" Then
               TmpString = ""
만일 "0"이라면 세어볼 필요가 없으므로 아무 변환없이 넘어갑니다.
           Else
                TmpString = Mid(NUM_HANGUL, Mid(strAmount, i, 1), 1)
해당문자와 위의 문자열 상수내의 위치를 맞추어 하나만 골라냅니다. 가령 Mid(strAmount, i, 1) 값이 7이라면 NUM_HANGUL의 7번째 문자인 "칠"을 뽑아 돌려줍니다. 

            Select Case I
            Case 4, 8, 12
                 TmpString = TmpString & "천"
            Case 3, 7, 11, 15
                 TmpString = TmpString & "백"
            Case 2, 6, 10, 14
                 TmpString = TmpString & "십"
            End Select
        End If
        Select Case I
        Case 13
             TmpString = TmpString & "조"
        Case 9
             TmpString = TmpString & "억"
        Case 5
             TmpString = TmpString & "만"
        End Select

위의 Select~End Select문은 단위에 맞추어 자리수를 넣어줍니다. "칠"이라고 하면 이것이 십단위인지, 천단위인지를 다음에 넣어주어야 겠죠.

          End If

          StringReturn = TmpString & StringReturn
문자열을 계속 쌓아갑니다.

     Next i
     ConvertCurrencyToHangul = "일금 " & StringReturn & "원정"
모두 변환되었으면 문자열로 변환된 값을 돌려줍니다. 이때 금액이므로 "일금~ 원정"이라는 접두어와 접미어를 붙여줍니다.

ErrHandler:
     Select Case Err
     Case ERR_TOOBIG
          MsgBox "입력한 숫자가 너무 큽니다.", vbExclamation
     Case ERR_NOTNUMBER
          If txtNumber = "" Then Resume Next
          MsgBo   x "입력한 내용이 숫자가 아닙니다.", vbExclamation
     End Select

에러에 대한 처리루틴입니다. 
End Function

지난 번과 비교해 변경된 프로시져에 대해 설명하겠습니다. 
Const KEY_DOT = 46
소수점을 입력하는 경우 "."(쩜)을 처리하기 위한 상수입니다. "."의 아스키코드값은 46입니다.

Private Sub txtNumber_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
txtNumber라는 텍스트상자에 뭔가를 입력하는 경우 발생하는 이벤트프로시져입니다. 매개변수로는 아스키코드값을 받습니다. 

     Select Case KeyAscii
     Case vbKey0 To vbKey9
받은 아스키코드값이 0~9까지의 숫자라면 그대로 통과시켜줍니다.
     Case KEY_DOT
          KeyAscii = IIf(InStr(1, txtNumber.Text, "."), 0, 46)
"."이라면 한번만 통과시켜줍니다. 숫자에서는 여러 개의 "."이 있을 수 없으므로 이미 "."이 있다면 0값을 강제로 넣어주어 입력을 무효화시킵니다.
     Case Else
기타의 경우인데 문자를 입력하는 경우 역시 키 값을 0으로 설정해 무효화합니다.

     End Select
End Sub

오늘은 여기까지입니다. 그럼 이만…

목차 | 이전 | 다음