• 최초 작성일: 2000-11-28
  • 최종 수정일: 2026-09-30
  • 조회수: 13 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: 현금 관리장부 만들기

들어가기 전에

오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.

이번 시간에는 메일로 받은 질문 하나를 살펴봅니다.

안녕하세요 엑셀러님
제 전직업이 사채업자였어요 지금은 아니지요
그 때에는 손으로 일수수금을 했는데 이걸 자동화 해보려고요

이순신 장부에서요
오늘을 기준으로 2-3일까지만 클릭이 되어야지 아무 날짜에나 OK표시가 되면
장부정리가 곤란해지잖아요. 이순신 시트에서요 텍스트박스안에 날짜가 들어
있고요 그 위에 큰 사각형이 있어서 이것을 클릭하면 OK 표시가 되잖아요.
근데 오늘날짜를 기준으로 2-3일 뒤의 날짜를 클릭하면 "수금 안된 곳을 아무데나
누르면 안되지"라는 메시지를 띄우고 싶은데 텍스트 박스 안에 있는 날짜를
불러낼 수가 있어야지요

사채업자를 했다고 흉보시지 마시고
전국민의 생활 자동화를위해 힘쓰시는 엑셀러님의 노고에 감사 드리면서
한수 부탁드릴께요
이번 파일은 꼭좀 답장을 부탁드립니다
일수장부 시트는 계속 만들어지지요
60일 80일 100일 장부도 계속 만들어볼려고요
사채동료들을 위해 파일을 나눠 줄려고요

Excel은 단순한 수치계산용 프로그램이 아닙니다. 얼마나 창의성을 가미하느냐에 따라 못만들 것이 없습니다. 외국에는 Spreadsheet Developer 또는 Solution Provider라는 직업도 있다는군요.

그러고 보니 참으로 다양한 계층의 분들이 Exceller의 강좌를 보시는군요. 이 질문을 주신 분은 VBA를 아주 열심히 하시는 분인데 아주 다양한 질문으로 Exceller를 괴롭히는(?) 분 중 한분 이십니다.

우리가 다니는 회사에서 어떤 일을 하는데 A라는 부서에서도 하고 B라는 부서에서도 하고 있다면 이것은 제대로 된 회사가 아니지요. 마찬가지입니다! 프로그래밍을 하실 때에도 "중복되는 부분은 없는가?", " 이 구문이 꼭 필요한 것인가?" 하는 점을 항상 염두에 두어야 합니다.

효율이라는 것은 다른 게 아닙니다. "중복"의 배제가 바로 효율이지요.

권현욱(엑셀러)
저자: 권현욱(엑셀러), 아이엑셀러 대표

필자는 Excel 컨설턴트, 작가, 그리고 크리에이터입니다. 현재 Microsoft Excel MVP이며, 『챗GPT+엑셀 업무자동화 정석』을 비롯한 10여 권의 도서를 집필했습니다. Excel 자동화 및 생산성 향상 분야에서 25년 넘는 경력을 보유하고 있습니다.

권현욱(엑셀러) 님의 최신 포스트:
  • 최신 글을 불러오는 중...


26년 경력 Microsoft MVP 권현욱(엑셀러) 대표 직강 1강 무료

🎁 파워툴스 마스터클래스 · 엑셀 바이브 코딩

AI에게 말로 지시해서 '나만의 엑셀 도구'를 만들고 리본에 장착합니다.

  • 코딩 지식 없이 시작 · 코드는 AI가 작성
  • 엑셀 리본에 내 탭과 버튼을 만들고 XLAM으로 공유
  • 1강 무료 수강 가능
수강 신청하기 강의 소개 보기

현금 관리장부 만들기

핵심 요약: 클릭으로 수금 기록하기

셀마다 텍스트 박스를 만들어 하나의 매크로를 연결하고, 호출한 텍스트 박스의 날짜를 읽어 기준일을 넘으면 막고 기록합니다.

  • 1단계: 셀 크기의 텍스트 박스를 만들어 Caption에 날짜를 넣고 OnAction으로 매크로를 연결합니다.
  • 2단계: Application.Caller로 클릭한 텍스트 박스의 날짜를 읽어 오늘 기준으로 제한합니다.
  • 3단계: OK를 표시하고 일일입력장 시트 마지막 행에 날짜, 채무자, 금액을 기록합니다.

Step 1: 질문하신 분의 장부 살펴보기

일단 질문하신 분이 작성한 장부를 보도록 하지요. 아래의 버튼을 눌러 장부로 이동한 다음 날짜가 들어 있는 아무 셀이나 클릭해 보세요. 그리고 클릭한 내용이 "일일입력장" 시트에 어떻게 기록이 되어져 있는지 확인해 보신 다음 돌아오시기 바랍니다.

다 보셨지요? 그렇다면 질문하신 분이 어떤 것을 질문하셨는지, 다시 말해서 이 프로그램에서 어떠한 문제가 있는지 아시겠습니까?

우선, "이순신-일수장부" 시트에서 특정일을 클릭하면 OK 표시가 되기는 하는데 "일일입력장" 시트에 가서 내용을 보면 무조건 날짜가 오늘 날짜로 입력이 됩니다.

날짜가 적힌 칸을 클릭하면 OK가 표시되는 일수장부 시트
아이엑셀러
일일입력장 시트에 기록된 날짜, 채무자, 금액
아이엑셀러

그리고 어떤 이유인지 모르겠으나 사각형(Rectangle) 오브젝트를 그릴 때, 가로 방향으로는 한 셀 크기만큼 그리셨으나 세로 방향으로는 세 개의 셀 크기만큼 그리셨군요.

마지막으로, 오늘 날짜를 기준으로 해서 특정일 이후의 날짜를 클릭하면 입금이 되지 않도록 설정이 안되는 문제점이 있습니다.

Step 2: 수정한 프로그램 실행해 보기

Exceller가 수정한 프로그램을 실행해 보고 오시기 바랍니다.

바로 이렇게 되도록 해 달라는 요청이시지요? 코드를 보도록 하지요. 질문하신 분의 코드는 모듈 시트에 따로 저장을 해 두었으니 살펴보도록 하세요. 질문자의 코드 중 필요한 부분을 조금 수정하였습니다.

Step 3: 장부 시트를 만드는 MakeGameBoardByExceller

Sub MakeGameBoardByExceller()
    Dim rngCell As Range
    Dim shtSheet As Worksheet
    Dim rngStage As Range
    Dim txtText As TextBox
    Dim intNum
    Dim btnButton As Button
    Dim dan As String
    Dim dan1 As String
    '//필요한 변수를 선언합니다.

    dan = InputBox("채무자 이름을 넣으세요", Format(Date, "yyyy/m/d(aaaa)입니다"))
    If dan = "" Then
        MsgBox " 이름은 반드시 입력해야 합니다", vbQuestion, ":::OO산업:::"
        Exit Sub
    End If
    '//채무자 이름을 입력받습니다. 아무 이름도 입력하지 않으면 메시지를 띄우고 종료합니다.

    dan1 = InputBox("차용금액을 넣으세요", Format(Date, "yyyy년 m월 d일(aaaa)"), "1000000")
    If Len(dan1) > 7 Or Len(dan1) <= 5 Then
        MsgBox "5자리이상 6자리까지 입력합니다", vbQuestion, ":::OO산업:::"
        Exit Sub
    End If

    If MsgBox("입력한 성명과금액이 맞습니까?" & Chr(13) & "채무자:" & dan & "님" _
        & Chr(13) & "일  금:" & Format(dan1, "#,##0""원"""), vbYesNo, ":::OO산업:::") = vbYes Then
    Else
        Exit Sub
    End If
    Set shtSheet = Worksheets.Add
    '//채무자와 채무금액에 이상이 있다고 응답하면 프로그램을 종료하고 이상이 없다고
    '//응답을 하였으면 새로운 워크시트를 한장 삽입합니다.

    With shtSheet
        .Columns(1).ColumnWidth = 3
        .Columns("b:F").ColumnWidth = 10
        .Rows(1).RowHeight = 6
        .Rows("2:13").RowHeight = 28
        .Cells.Interior.ColorIndex = 1
        .Name = dan & "-일수장부"
    End With
    '//새로운 워크시트의 이름과 기본적인 셀 크기, 색상 등을 지정해 줍니다.

    '//이제부터는 셀에 몇 가지의 기본정보를 입력하고 서식을 설정하는 과정입니다.
    With ActiveSheet.Range("H3")
        .Value = "채무자:"
        .Font.ColorIndex = 2
        .Font.Size = 10
        .HorizontalAlignment = xlDistributed
    End With
    With ActiveSheet.Range("i3")
        .Value = dan
        .Font.ColorIndex = 2
        .Font.Size = 12
        .HorizontalAlignment = xlRight
    End With
    With ActiveSheet.Range("h13")
        .Value = "작성자:" & Application.UserName & Format(Now(), "     yy년mm월dd일(aaaa)")
        .Font.ColorIndex = 2
        .Font.Size = 12
    End With

    With ActiveSheet.Range("h4")
        .Value = "차용금액:"
        .Font.ColorIndex = 2
        .Font.Size = 10
        .HorizontalAlignment = xlDistributed
    End With
    With ActiveSheet.Range("i4")
        .Value = dan1
        .Font.ColorIndex = 2
        .Font.Size = 12
        .NumberFormatLocal = "#,##0""원"""
    End With
    With ActiveSheet.Range("H5")
        .Value = "하루입금액:"
        .Font.ColorIndex = 2
        .Font.Size = 10
        .HorizontalAlignment = xlDistributed
    End With
    With ActiveSheet.Range("i5")
        .FormulaR1C1 = "=일수6(R[-1]C)"
        '//"일수6" 이라는 사용자 정의 함수를 실행시켜서 그 결과값을 i5 셀에 표시합니다.

        .Font.ColorIndex = 2
        .Font.Size = 12
        .NumberFormatLocal = "#,##0""원"""
    End With

    Set rngStage = Range("b2:f13")
    With rngStage
        With .Font
            .ColorIndex = 3
            .Size = 15
            .Bold = True
            .Name = "arial"
        End With
        .HorizontalAlignment = xlRight
        .VerticalAlignment = xlBottom
        With .Borders(xlEdgeBottom)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        With .Borders(xlEdgeRight)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        With .Borders(xlEdgeTop)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        With .Borders(xlInsideHorizontal)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        With .Borders(xlInsideVertical)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        With .Borders(xlEdgeLeft)
            .Weight = xlThin
            .ColorIndex = 2
        End With
        .BorderAround , xlThick, 2
        .Locked = False
        .FormulaHidden = False
    End With

    intNum = Date - 1
    For Each rngCell In rngStage
        intNum = intNum + 1
        Set txtText = ActiveSheet.TextBoxes.Add(rngCell.Left, rngCell.Top, _
            rngCell.Width, rngCell.Height)
        '//이 부분에서 질문하신 분이 작성하신 것과 좀 차이가 있습니다. 질문자는 각 셀에
        '//TextBox를 셀 크기의 1/2만큼 그리고 Rectanble 오브젝트도 세 개의 셀 크기만큼
        '//작성을 하셨으나 그렇게 할 별다른 이유가 없는 것 같아 사각형(Rectangle) 오브젝트를
        '//제거하고 텍스트 박스를 하나 그려넣고 여기에 매크로를 연결합니다.

        With txtText
            .OnAction = "ClickMeByExceller"
            With txtText.Characters
                .Text = CStr(intNum)
                With .Font
                    .Name = "바탕체"
                    .Size = 9
                    .ColorIndex = 6
                End With
            End With
            .ShapeRange.Fill.Visible = msoFalse
            .ShapeRange.Line.Visible = msoFalse
            '//텍스트 박스를 그린 다음에 내부 공간과 테두리 선 색상을 msoFalse 속성, 즉
            '//아무 색상도 지정하지 않으면 마치 아무 것도 없는 것처럼 보이겠지요.

        End With
    Next rngCell

    Set btnButton = ActiveSheet.Buttons.Add(Range("h11").Left, Range("h11").Top, _
        Range("h11").Width * 2, Range("h11").Height)
    With btnButton
        .Caption = "Main으로가기"
        .Characters.Font.Name = "arial"
        .OnAction = "maingoto"
    End With

    Set btnButton = ActiveSheet.Buttons.Add(Range("h10").Left, Range("h10").Top, _
        Range("h10").Width * 2, Range("h10").Height)
    With btnButton
        .Caption = "일일입력장으로가기"
        .Characters.Font.Name = "arial"
        .OnAction = "입력goto"
    End With

    Set btnButton = ActiveSheet.Buttons.Add(Range("h9").Left, Range("h10").Top, _
        Range("h10").Width * 2, Range("h10").Height)
    With btnButton
        .Caption = "<<되돌아가기"
        .Characters.Font.Name = "arial"
        .OnAction = "GoBack"
    End With
    ActiveSheet.Protect
    ActiveSheet.ScrollArea = rngStage.Address
    '//작업이 끝났으면 시트에 Protect를 걸어 보호하고, ScrollArea 즉, 화면 상에서 스크롤
    '//되는 영역을 설정해 주었습니다.
End Sub

이 예제에서 사용한 TextBoxes와 Buttons는 옛 버전의 그리기 개체 모델이며, 지금도 동작하지만 요즘 코드에서는 Shapes.AddTextbox, Shapes.AddFormControl 등을 주로 사용합니다.

Step 4: 셀을 클릭했을 때 실행되는 ClickMeByExceller

이번에는 각 셀에 연결되어 있는 ClickMeByExceller 프로시저의 내용을 볼까요?

Sub ClickMeByExceller()
    Dim rngCell As Range
    Dim rngUsed As Range
    Dim intNum As Integer
    Dim intCount As Integer
    Dim i As Integer
    Dim datDate() As Date
    Dim Msg As String
    Set rngCell = ActiveSheet.TextBoxes(Application.Caller).TopLeftCell

    If CDate(ActiveSheet.TextBoxes(Application.Caller).Caption) > Date + 4 Then
    '//질문하신 분께서 "텍스트 박스 안의 날짜를 불러낼 수 가 없다"고 하셨는데 이렇게
    '//하면 이제 가능하겠지요?
    '//텍스트 박스 중에서 Application.Caller, 즉 이 프로시저를 호출한 녀석의 Caption 속성이
    '//오늘 날짜보다 4일 이후의 것이면 에러 메시지를 띄우고 프로시저를 종료합니다.

        Msg = "오늘 날짜를 기준으로 5일 이내의 자료만" & vbCr
        Msg = Msg & "수금가능합니다" & vbCr & vbCr
        Msg = Msg & "날짜를 다시 확인하세요"
        MsgBox Msg, , "날짜 확인//Exceller"
        Exit Sub
    End If
    If rngCell = "OK" Then
        MsgBox " 수금한 곳을 지우면 안되지", , "수금 완료//Exceller"
        Exit Sub
    Else
        rngCell = "OK"
        Call SearchWordByExceller
        '//클릭한 셀에 OK 표시가 없을 경우 OK라고 표시를 하고 SearchWordByExceller
        '//프로시저를 실행합니다.
    End If
End Sub

Step 5: 수금 내역을 일일입력장에 옮기는 SearchWordByExceller

마지막으로, 수금한 날짜의 금액을 "일일입력장"으로 옮겨적기 위한 프로시저를 수행합니다. 코드는 그다지 어려운 것이 없으므로 해설은 생략합니다.

Sub SearchWordByExceller()
    Dim shtSheet As Worksheet
    Dim rngstart As Range
    Dim txtSeat As TextBox
    Dim rngSale As Range
    Dim strTemp As String

    Set txtSeat = ActiveSheet.TextBoxes(Application.Caller)
    Set rngSale = txtSeat.TopLeftCell
    Set shtSheet = Worksheets("Modified일일입력장")
    Set rngstart = shtSheet.Cells(Application.CountA(shtSheet.Columns(1)) + 1, 1)
    With rngstart
        .Offset(0, 0) = txtSeat.Caption
        .Offset(0, 1) = Range("i3")
        .Offset(0, 2) = Range("i5")
    End With
End Sub

Step 6: 보조 프로시저

장부 시트의 버튼과 하루 입금액 계산에 사용된 보조 프로시저는 아래와 같습니다(하루 입금액은 차용금액을 60일로 나눈 값으로 가정한 예시입니다).

Function 일수6(차용금액 As Double) As Double
    일수6 = 차용금액 / 60
End Function

Sub maingoto()
    Worksheets(1).Select
End Sub

Sub 입력goto()
    Sheets("Modified일일입력장").Select
End Sub

Sub GoBack()
    Worksheets(1).Select
End Sub

마무리

문제잘 정리된 문제점은 80% 이상은 해결된 것입니다. 막연한 문제는 막연한 해결책을 낳을 뿐이지요. 무슨 문제에 직면하든 간에 항상 문제를 구체화시키도록 노력하시기 바랍니다.

오늘은 여기까지 하지요.

정리 — 관리장부 핵심

구분 사용한 코드 역할
텍스트 박스 만들기 ActiveSheet.TextBoxes.Add(Left, Top, Width, Height) 셀마다 클릭 영역 생성
매크로 연결 .OnAction = "ClickMeByExceller" 클릭 시 실행
호출한 개체 확인 ActiveSheet.TextBoxes(Application.Caller) 클릭한 텍스트 박스
날짜 제한 CDate(...Caption) > Date + 4 기준일 이후 차단
기록 위치 Application.CountA(shtSheet.Columns(1)) + 1 마지막 다음 행

자주 묻는 질문 (FAQ)

Q1. 텍스트 박스 안의 날짜를 읽어 오려면?

Application.Caller로 호출한 텍스트 박스를 지정한 뒤 Caption 속성을 읽으면 됩니다.

Q2. 오늘 날짜 이후는 클릭하지 못하게 하려면?

Caption의 날짜를 CDate로 바꿔 Date와 비교하고 기준을 넘으면 메시지를 띄운 뒤 프로시저를 종료합니다.

Q3. 프로그래밍에서 효율이란 무엇인가요?

중복되는 부분을 없애는 것이며, 같은 일을 하는 구문이 없는지 항상 확인하는 습관이 필요합니다.

마치며

문제를 구체화하면 80% 이상 해결된 것이며, 텍스트 박스와 Application.Caller로 클릭형 장부를 만들 수 있습니다.