- 최초 작성일: 2000-12-27
- 최종 수정일: 2026-09-30
- 조회수: 15 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 사용자 정의 변수 활용예제 하나
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
지난 강좌시간에 사용자 정의 변수에 대해 설명을 드렸는데 많이들 응용해 보셨는지 모르겠군요. 아직 이해도 제대로 못하셨다구요? ^^ 그렇다면 어떤 곳에 활용가능한지 활용 예제 한가지를 알려드릴테니 확실하게 이해하시기 바랍니다(참 친절하기도 하다! ^^)
사용자 정의 변수 활용예제 하나
핵심 요약: 행열 방향 바꾸기
자료를 동적 배열에 담아두고 셀을 비운 다음, 방향을 바꿔 다시 배치하며, 여러 필드가 있으면 사용자 정의 변수 배열로 처리합니다.
- 1단계: 한 칸 아래(또는 옆)가 비었는지로 현재 배치 방향을 판별합니다.
- 2단계: ReDim Preserve로 배열을 늘려가며 값을 담고 원래 셀을 비웁니다.
- 3단계: 배열을 순환하며 Offset으로 반대 방향에 값을 배치합니다.
Step 1: 행과 열 방향을 바꾸는 예제
먼저 아래와 같은 리스트가 있습니다. 버튼을 눌러 보세요.
시트에는 지점명이 세로로 나열되어 있습니다(맨 위 제목 아래로 강동지점부터 제주지점까지 20개 지점).
- 강동지점
- 강서지점
- 강남지점
- 강북지점
- 수원지점
- … (이하 제주지점까지 총 20개 지점)
제목 셀에 "Start"라는 이름을 미리 정의해 두었고, 버튼을 누를 때마다 자료가 행↔열 방향으로 번갈아가며 표시됩니다. 물론 이것은 "선택하여 붙여넣기-행/열 바꿈" 기능을 사용해서 해결할 수도 있습니다. 하지만 어떤 논리적 접근을 통해 이것이 가능하게 되는 것인지, 그리고 사용자 정의 변수를 어떤 경우에 사용하면 좋은지를 알 수 있는 좋은 예제이니까 잘 이해하시도록…
Sub ChangeRowToCol()
Dim strTemp() As String
Dim i As Integer
'//변수를 지정해 주었습니다. strTemp()라는 동적 배열변수를 사용합니다.
With Range("Start")
If Not IsEmpty(.Offset(1, 0)) Then
'//Start 셀을 기준으로 해서 한 라인 아래의 셀이 빈 셀이 아니면 아래의 구문을 실행.
Do Until .Offset(i, 0) = ""
ReDim Preserve strTemp(i)
strTemp(i) = .Offset(i, 0)
.Offset(i, 0) = ""
i = i + 1
'//한 라인씩 아래로 내려가면서 셀의 값을 동적 배열변수에 차곡차곡 담습니다.
'//여기서 Preserve라는 명령은 동적 배열변수의 크기를 보존하는 것입니다.
'//다른 랭귀지와는 다른 아주 독특한 것이기도 한데 보통 다른 프로그래밍 언어도
'//배열을 재선언(ReDimension) 할 수는 있으나 그렇게 되면 기존에 보관하고 있던
'//데이터는 지워지게 마련인데 VB에서는 위와 같이 해주면 배열의 크기가
'//변하더라도 기존의 데이터들은 그대로 보존됩니다.
Loop
For i = LBound(strTemp) To UBound(strTemp)
.Offset(0, i) = strTemp(i)
'//순환문을 돌면서 지정한 배열의 사용가능한 아래 첨자에서 위첨자까지의 값을
'//Start 셀을 기준으로 옆의 셀에 차례로 옮깁니다.
Next i
Else
'//아래의 것은 윗부분과 반대되는 것으로 가로 방향으로 배치 되어있는 자료를 세로
'//방향으로 옮기도록 하는 것입니다. 내용은 위의 것과 대동소이하므로 설명 생략…
Do Until .Offset(0, i) = ""
ReDim Preserve strTemp(i)
strTemp(i) = .Offset(0, i)
.Offset(0, i) = ""
i = i + 1
Loop
For i = LBound(strTemp) To UBound(strTemp)
.Offset(i, 0) = strTemp(i)
Next i
End If
End With
End Sub
Step 2: 사용자 정의 변수를 활용하는 예제
위의 예제에서는 아직 사용자 정의 변수를 활용하지 않았습니다. 동적 배열만을 사용하였습니다. 이제 사용자 정의 변수를 사용한 또다른 예제 하나를 보도록 할까요? 버튼을 누르세요!
이번에는 지점명, 판매수량, 판매금액의 세 필드로 이루어진 표를 대상으로 합니다. 위에서와 마찬가지로 표의 첫 셀에 이름을 미리 정의하였는데, 이번에는 Start2라고 지정했습니다.
코드를 살펴보도록 하지요.
Type MyCustInfo
strBranch As String * 10
varNum As Variant
varSales As Variant
End Type
'//프로시저의 도입부분에 위와 같이 MyCustInfo라는 코펠(사용자 정의 변수)를
'//선언합니다. 프로시저의 외부에 선언해 준 점에 유의!
Sub ChangeRowToCol2()
Dim typTemp() As MyCustInfo
Dim i As Integer
'//사용자 정의 변수를 불러와서 사용할 때에는 "Dim 변수명 As 사용자정의 변수명"과
'//같은 형태로 사용합니다.
With Range("Start2")
If Not IsEmpty(.Offset(3, 0)) Then
'//Start2 셀을 기준으로 가로 방향의 데이터를 세로 방향으로 복사를 하는 것인지,
'//아니면 그 반대의 경우인지를 먼저 구분해야 겠지요?
'//그렇다면 어떻게 하면 그것을 구분할 수 있을까요? 사람 같으면야 그냥 눈으로 보면
'//되지만 컴퓨터야 눈이 없으니… 그래서 위와 같은 방법을 생각해 본 것입니다.
'//즉 지점명, 판매수량, 판매금액 이렇게 세 개의 필드로 이루어진 테이블이니까
'//Start2 셀을 기준으로 아래로 3간 내려간 곳에 어떤 자료가 있다면 세로 방향으로
'//자료가 배열되어 있다고 할 수 있겠지요?
Do Until .Offset(i, 0) = ""
ReDim Preserve typTemp(i)
typTemp(i).strBranch = .Offset(i, 0)
typTemp(i).varNum = .Offset(i, 1)
typTemp(i).varSales = .Offset(i, 2)
'//따라서 세로 방향으로 배치되어 있는 자료를 동적 배열변수에 하나씩 담습니다.
'//이 때 사용자 정의 변수를 어떻게 사용하였는지를 눈여겨 보시기 바랍니다.
.Offset(i, 0) = ""
.Offset(i, 1) = ""
.Offset(i, 2) = ""
i = i + 1
Loop
For i = LBound(typTemp) To UBound(typTemp)
.Offset(0, i) = typTemp(i).strBranch
.Offset(1, i) = typTemp(i).varNum
.Offset(2, i) = typTemp(i).varSales
'//순환문을 돌면서 동적 배열 변수에 들어있는 값을 가로 방향으로 옮깁니다.
Next i
Else
'//아래 부분은 위와 반대로 가로 방향으로 배치되어 있는 자료를 세로 방향으로
'//옮기는 것입니다. 역시 코드는 위의 것과 거의 같으므로 설명은 생략합니다.
Do Until .Offset(0, i) = ""
ReDim Preserve typTemp(i)
typTemp(i).strBranch = .Offset(0, i)
typTemp(i).varNum = .Offset(1, i)
typTemp(i).varSales = .Offset(2, i)
.Offset(0, i) = ""
.Offset(1, i) = ""
.Offset(2, i) = ""
i = i + 1
Loop
For i = LBound(typTemp) To UBound(typTemp)
.Offset(i, 0) = typTemp(i).strBranch
.Offset(i, 1) = typTemp(i).varNum
.Offset(i, 2) = typTemp(i).varSales
Next i
End If
End With
End Sub
요즘 버전의 엑셀에서는 Range.Copy와 PasteSpecial Transpose:=True 또는 WorksheetFunction.Transpose로 행과 열을 한 줄에 바꿀 수 있습니다. 이 강좌의 코드는 배열과 사용자 정의 변수를 익히기 위한 예제입니다.
마무리
많이 응용해 보시기 바랍니다.
다음 시간에…
정리 — 행열 바꾸기 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 방향 판별 | If Not IsEmpty(.Offset(1, 0)) | 세로 배치인지 확인 |
| 배열 확장 | ReDim Preserve strTemp(i) | 기존 값을 보존하며 크기 확장 |
| 값 담기 | strTemp(i) = .Offset(i, 0) | 셀 값을 배열에 저장 |
| 형식 정의 | Type MyCustInfo ... End Type | 세 필드를 묶은 형식 |
| 다시 배치 | .Offset(0, i) = strTemp(i) | 반대 방향으로 값 입력 |
자주 묻는 질문 (FAQ)
Q1. ReDim Preserve는 무엇인가요?
동적 배열의 크기를 다시 정하면서 기존에 담겨 있던 값을 그대로 보존하는 구문입니다.
Q2. 사용자 정의 변수는 언제 쓰면 좋은가요?
지점명, 판매수량, 판매금액처럼 여러 필드로 이루어진 하나의 레코드를 다룰 때 하나로 묶어 배열로 처리하면 편리합니다.
Q3. 행과 열 방향은 어떻게 구분하나요?
기준 셀에서 한 칸(또는 필드 수만큼) 아래의 셀이 비어 있는지 확인해 세로 배치인지 가로 배치인지 판별합니다.
마치며
동적 배열과 사용자 정의 변수를 함께 쓰면 여러 필드로 된 자료도 방향을 자유롭게 바꿀 수 있습니다.