- 최초 작성일: 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라는 부서에서도 하고 있다면 이것은 제대로 된 회사가 아니지요. 마찬가지입니다! 프로그래밍을 하실 때에도 "중복되는 부분은 없는가?", " 이 구문이 꼭 필요한 것인가?" 하는 점을 항상 염두에 두어야 합니다.
효율이라는 것은 다른 게 아닙니다. "중복"의 배제가 바로 효율이지요.
현금 관리장부 만들기
핵심 요약: 클릭으로 수금 기록하기
셀마다 텍스트 박스를 만들어 하나의 매크로를 연결하고, 호출한 텍스트 박스의 날짜를 읽어 기준일을 넘으면 막고 기록합니다.
- 1단계: 셀 크기의 텍스트 박스를 만들어 Caption에 날짜를 넣고 OnAction으로 매크로를 연결합니다.
- 2단계: Application.Caller로 클릭한 텍스트 박스의 날짜를 읽어 오늘 기준으로 제한합니다.
- 3단계: OK를 표시하고 일일입력장 시트 마지막 행에 날짜, 채무자, 금액을 기록합니다.
Step 1: 질문하신 분의 장부 살펴보기
일단 질문하신 분이 작성한 장부를 보도록 하지요. 아래의 버튼을 눌러 장부로 이동한 다음 날짜가 들어 있는 아무 셀이나 클릭해 보세요. 그리고 클릭한 내용이 "일일입력장" 시트에 어떻게 기록이 되어져 있는지 확인해 보신 다음 돌아오시기 바랍니다.
다 보셨지요? 그렇다면 질문하신 분이 어떤 것을 질문하셨는지, 다시 말해서 이 프로그램에서 어떠한 문제가 있는지 아시겠습니까?
우선, "이순신-일수장부" 시트에서 특정일을 클릭하면 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로 클릭형 장부를 만들 수 있습니다.