- 최초 작성일: 2007-11-04
- 최종 수정일: 2026-09-30
- 조회수: 17 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 무작위로 입력한 자료를 품목별로 나누기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
지난 번에 친구 녀석 사이트에 놀러 갔다가 퍼온 글입니다.
죽을만큼 힘이 들때
북극 근처에 사는 사람들은 살아가다가 죽을만큼 힘이 드는 일이 생기면 말뚝과 망치 하나를 들고 집을 나선다고 합니다.
가야 할 한 방향을 정하고는 영하 수십도가 넘는 빙판 위를 걷고 또 걷고 걸어가다가 도저히 더는 못 갈 것 같으면 가지고 온 말뚝을 빙판위에 박아 놓고 집으로 되돌아 간답니다.
그러다가 또 죽을 만큼 힘든 일이 생기면 이번엔 망치 하나만 들고 다시 같은 방향으로 걸어간답니다.
걷고 걷고 또 걷다가 지난 번에 박아 놓은 말뚝이 보이면 이렇게 생각 한답니다.
'아... 저번에 그렇게 죽을만큼 힘들었는데도 겨우 여기까지 밖에 안왔었구나... 이번 일은 그 때보다 힘든일도 아니었는데... 이제 그만 집으로 돌아가자...'
그러면서 집으로 돌아 온답니다.. 만약 그때보다 지금이 더 힘들다면 그 말뚝을 뽑아서 더 먼곳에까지 가서 말뚝을 박아 놓고 돌아오겠죠..
오늘 죽을만큼 힘들다고 생각이 든다면 잘 생각 해보시기 바랍니다. 아마 살아오면서 오늘보다 더 힘들고 고통스러웠던 기억이 있었을 겁니다. 그런데도 여태껏 잘 견디며 살아 왔었지요?
살아간다는 일은 그런 겁니다. 그렇게 견디는 일이지요
저도 어디선가 이 글을 읽은 기억이 나는데 어디서였는지는 가물가물 하군요. 어제도 원문을 찾다 책을 뒤적였지만 찾지 못했습니다. 누구 출전을 아시는 분은 알려주세요.
무작위로 입력한 자료를 품목별로 나누기
핵심 요약: 뒤섞인 매출 자료를 품목별로 한 줄씩 정리하기
담당자별로 자유롭게 기록한 매출 데이터를 품목별로 묶어 판매수량을 가로로 나열해 줍니다. 고급 필터와 자동 필터를 VBA로 조합하는 것이 핵심입니다.
- 1단계: 고급 필터로 중복 없는 상품명을 새 시트에 추출하고 정렬합니다.
- 2단계: 상품명을 하나씩 자동 필터 조건으로 지정해 해당 판매수량만 남깁니다.
- 3단계: 보이는 셀만 복사해 행/열을 바꿔 붙여넣습니다.
Step 1: 어떤 질문이었을까요?
질문 하나
조그마한 가게를 하나 운영하고 있습니다. POS가 설치되어 있기는 하지만 수기로 관리하고 있습니다. 저를 포함하여 세 명이 매출장부에 기록한 내용을 일마감 후 수작업 정리합니다. Exceller님 덕택에 수준이 한단계 상승하여 엑셀로 정리를 하고는 있는데… 각자가 작성한 양식을 품목별로 보기 좋게 정리하는 방법이 없을까요?...
비밀 메일로 보내신 것으로 보아… 예제 파일을 하나 만들고 이것으로 설명을 하는 것이 좋을 듯 합니다. 아래 버튼을 클릭하면 요런 모양의 데이터가 이렇게 정리됩니다.
위의 두 그림을 보면 무엇을 어떻게 처리해 달라는 것인지 이해가 되시지요?
왼쪽 그림과 같이 담당자별로 매출 실적이 발생할 때마다 자유롭게(?) 매출장부에 기록을 합니다. 그런 다음 하루 마감을 할 때, 각자가 기록한 것을 펼쳐 놓고 품목별로 뭐가 얼마나 팔렸는지 결산을 하는데 이것을 자동화 할 방법이 없느냐는 것입니다.
버튼을 눌러서 보셨듯이 가능합니다.
Step 2: 코드 살펴보기
Option Base 1
'배열의 아래 첨자(Lbound) 하한값을 1로 설정합니다.
Sub DivideDataByItem()
Dim shtSheet As Worksheet
Dim shtAdd As Worksheet
Dim rngSource As Range
Dim rngItem As Range
Dim rngAmount As Range
Dim rngUnique As Range
Dim varUnique As Variant
Dim lngRow As Long
Dim i As Integer
'Workplace 시트에서 사용된 영역(UsedRange)을 rngSource 변수에 할당하고 행수를 카운팅하여
'lngRow 변수에 담아 둡니다.
Set shtSheet = Worksheets("Workplace")
Set rngSource = shtSheet.UsedRange
lngRow = rngSource.Rows.Count
Set rngItem = rngSource.Columns(1).SpecialCells(xlTextValues)
Set rngAmount = rngItem.Offset(1, 1)
Set shtAdd = Worksheets.Add
With shtAdd
'새로운 시트를 한 장 삽입합니다. 고급 필터를 이용하여 상품명 중에서 중복되지 않는 항목들을
' 걸러 냅니다.
rngItem.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=.Range("A1"), Unique:=True
Set rngUnique = .Range(.Range("A2"), .Range("A2").End(xlDown))
End With
With rngUnique
.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, OrderCustom:=1
varUnique = .Value
'중복되지 않는 값들을 varUnique 변수에 저장합니다.
End With
For i = LBound(varUnique) To UBound(varUnique)
'varUnique 변수, 즉 상품명별로 판매수량 데이터를 필터 기능을 이용하여 하나씩 가져옵니다.
'잘 이해가 안되는 분은 연필과 종이를 이용하여 순환문을 3바퀴 정도만 돌려보면 로직을 이해
'할 수 있으리라 생각합니다.
rngSource.AutoFilter Field:=1, Criteria1:=varUnique(i, 1)
rngAmount.SpecialCells(xlCellTypeVisible).Copy
rngUnique(i, 1).Offset(0, 1).PasteSpecial Transpose:=True
Next i
rngSource.AutoFilter
Range("A1").Select
End Sub
참고 - 코드의 핵심 흐름: ① 고급 필터의 '고유 레코드만' 옵션으로 중복 없는 상품명을 새 시트에 뽑아내고 정렬합니다. ② 상품명을 하나씩 자동 필터의 조건으로 지정하면 화면에 보이는 판매수량만 남습니다. ③ 보이는 셀만 복사해서 '행/열 바꿈' 옵션으로 붙여 넣으면 가로로 나열됩니다. 첫 줄의 Option Base 1은 모듈 맨 위(프로시저 바깥)에 적어야 합니다.
다음 시간에…
정리 — 품목별 나누기 코드 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 배열 하한값 | Option Base 1 | 배열 첨자의 시작을 1로 지정 |
| 중복 없는 품목 추출 | AdvancedFilter Action:=xlFilterCopy, Unique:=True | 상품명의 고유값만 새 시트에 복사 |
| 품목별 필터 | AutoFilter Field:=1, Criteria1:=varUnique(i, 1) | 상품명을 하나씩 조건으로 지정 |
| 보이는 셀 복사 | SpecialCells(xlCellTypeVisible).Copy | 필터링된 판매수량만 복사 |
| 가로로 붙여넣기 | PasteSpecial Transpose:=True | 행/열을 바꿔서 나열 |
자주 묻는 질문 (FAQ)
Q1. Option Base 1은 꼭 필요한가요?
이 코드에서 varUnique 변수는 Range의 Value를 받은 2차원 배열이라 원래 첨자가 1부터 시작하므로 Option Base 1이 없어도 동작합니다. 다만 배열을 다루는 코드의 일관성을 위해 넣어 두었습니다. 사용하려면 모듈 맨 위(프로시저 바깥)에 적어야 합니다.
Q2. 품목 수가 많아지면 느려지지 않나요?
품목 수만큼 자동 필터를 적용하고 복사하는 방식이라 데이터가 많으면 시간이 걸릴 수 있습니다. 이럴 때는 Application.ScreenUpdating = False로 화면 갱신을 끄고 실행하면 훨씬 빨라집니다.
Q3. 결과를 새 시트가 아니라 기존 시트에 만들 수 있나요?
코드에서 Worksheets.Add로 새 시트를 만드는 부분을 원하는 시트를 지정하는 구문으로 바꾸면 됩니다. 이 경우 이전에 남아 있는 결과를 먼저 지우도록 처리해 주세요.
마치며
필터 기능 두 가지와 붙여넣기 옵션만 조합해도 수작업 결산을 자동으로 바꿀 수 있습니다. 순환문이 잘 이해되지 않으면 연필과 종이로 세 바퀴만 돌려 보세요!