- 최초 작성일: 2001-10-31
- 최종 수정일: 2026-09-30
- 조회수: 10 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: 데이터 위치 바꾸기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
이생진 시인의 시집 <그리운 바다 성산포>에 실린 시 가운데 한 구절이 문득 떠올랐습니다. 바다 앞에서 술잔을 기울이는 사람과 바다의 모습을 그린 짧은 시입니다. (시의 전문은 저작권 문제로 싣지 않았습니다.)
왜 이 시 구절이 불현듯 생각나는 것일까요?(누구 이유를 아시는 분~~ ^^)
지난 시간에 잠깐 설명드린 토끼/거북이 자리 바꾸기(사실은 오래 전에 자세히 알려드렸습니다)의 원리를 잘 이해하셨지요? 마침 이런 질문을 해 오신 분이 있군요.
데이터 위치 바꾸기
핵심 요약: 두 영역의 데이터 교환
선택한 두 영역의 값을 각각 배열에 담아 둔 다음 서로 반대편 영역에 넣으면 데이터 위치가 바뀝니다.
- 1단계: Selection이 Range이며 영역이 2개이고 크기가 같은지 검사합니다.
- 2단계: 두 영역의 값을 배열 변수에 하나씩 저장합니다.
- 3단계: 반대편 영역에 저장한 값을 채워 넣습니다.
Step 1: 이번 시간의 질문
A열의 내용과 B열의 내용을 바꾸려면 어케해야 하나여??
질문 자체는 아주 간결하지만 해법은… 조금 복잡할 듯 합니다. Ctrl 키를 사용하여 아래의 두 범위를 선택하신 다음 버튼을 눌러 보세요.
예제 데이터 펼쳐 보기 (이름 / 값)
| 이름 | 값 |
|---|---|
| 갑동이 | 170 |
| 을동이 | 597 |
| 병동이 | 784 |
| 정동이 | 113 |
| 무동이 | 858 |
| 기동이 | 276 |
| 무동이 | 990 |
| 기동이 | 129 |
| 경동이 | 398 |
| 신동이 | 457 |
| 임동이 | 975 |
| 계동이 | 640 |
Step 2: ExchangeDataLocation 프로시저
Sub ExchangeDataLocation()
Dim varThis() As Variant, varThat() As Variant
Dim i As Integer, intNum As Integer
Dim strErrMsg As String
Application.ScreenUpdating = False
'''등장 인물에 대한 캐스팅 작업… 바로 변수와 맡을 역할을 정의해 주었습니다.
'''작업할 때마다 화면이 갱신되지 않도록 하기 위해 ScreenUpdating 속성을 False로…
strErrMsg = "범위 선택 오류//By Exceller"
On Error GoTo ET
If TypeName(Selection) <> "Range" Then
MsgBox "바꾸려는 범위를 먼저 선택하세요!", vbExclamation, strErrMsg
Exit Sub
End If
'''사용자가 Range 오브젝트, 그러니까 셀이 아닌 다른 것(예를 들면 도형같은 것)을 선택하고
'''버튼을 눌렀을 경우, 경고 메시지를 뿌리고 프로시저를 종료합니다.
With Selection
If .Areas.Count <> 2 Then
MsgBox "반드시 2개의 영역을 선택하셔야 합니다!", vbExclamation, strErrMsg
Exit Sub
End If
'''두 영역의 데이터를 바꾸려면 당연히 두 개의 범위를 지정해야 겠지요? 따라서 1개 또는
'''3개 이상의 영역을 선택하고 버튼을 누를 경우에도 에러 메시지를 보여줍니다.
If .Areas(1).Cells.Count <> .Areas(2).Cells.Count Then
MsgBox "바꾸려는 영역의 크기가 같아야 합니다", vbExclamation, strErrMsg
Exit Sub
End If
'''이 부분도 마찬가지로 에러 메시지를 보여주는 부분입니다. 이것은 무슨 뜻일까요?
'''두 집의 크기가 같아야 1:1로 바꾸어 줄 수 있을 것입니다. 따라서 두 집의 크기가 같은지를
'''비교하는 구문입니다.
intNum = Selection.Areas(1).Cells.Count
ReDim varThis(intNum)
ReDim varThat(intNum)
For i = 1 To intNum
varThis(i) = .Areas(1).Cells(i)
varThat(i) = .Areas(2).Cells(i)
Next i
'''바로 이 부분이 오늘의 하일라이트입니다.
'''그런데 별로 설명드릴 만한 사항은 없을 듯 합니다. 왜냐구요? 넘 쉬우니까…
'''장난치지 말라구요? 알겠습니다! 하지만 정말로 설명드릴 것이 없습니다.
'''Areas(1) 영역 내에 몇 개의 셀이 있는 지 카운팅 한 다음 varThis와 varThat라는 동적
'''배열 변수의 크기를 결정합니다. 그런 다음에 순환문을 돌면서 각 셀의 값을 하나씩
'''담아두는 것이지요.
End With
For i = 1 To intNum
Selection.Areas(1).Cells(i).Value = varThat(i)
Selection.Areas(2).Cells(i).Value = varThis(i)
'''다시 한번 순환문을 돌면서 두 영역의 데이터 값의 위치를
'''서로 바꾸어 줍니다.
Next i
ET:
Application.ScreenUpdating = True
End Sub
마무리
방법은 조금 다릅니다만, 토끼/거북이 자리 옮기기만 잘 생각하시면 충분히 해결가능한 문제가 아닌가 생각됩니다. 쉬운 것을 어렵게 생각하고 어려운 것을 쉽게 생각하는 습관을 기르시기 바랍니다. 예측 가능한 모든 사항을 다 감안하려면 머리털 또 다 빠집니다.
다음 시간에…
정리 — 데이터 위치 교환 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 선택 검사 | TypeName(Selection) <> "Range" | Range가 아니면 종료 |
| 영역 개수 | .Areas.Count <> 2 | 두 영역만 허용 |
| 크기 비교 | .Areas(1).Cells.Count <> .Areas(2).Cells.Count | 같은 크기만 허용 |
| 값 저장 | varThis(i) = .Areas(1).Cells(i) | 임시 배열에 저장 |
| 값 교환 | Areas(1).Cells(i).Value = varThat(i) | 반대편 값 입력 |
자주 묻는 질문 (FAQ)
Q1. 떨어져 있는 두 영역의 데이터를 서로 바꾸려면 어떻게 하나요?
Ctrl 키로 두 영역을 선택하고 Areas 컬렉션으로 접근해 값을 배열에 담아 둔 뒤 서로 반대편에 넣습니다.
Q2. Areas 컬렉션은 무엇인가요?
여러 영역을 선택했을 때 각 영역에 순서대로 접근할 수 있게 해 주는 컬렉션입니다.
Q3. 두 영역의 크기가 다르면 어떻게 되나요?
1:1로 바꿀 수 없으므로 크기를 비교해 다르면 오류 메시지를 표시하고 종료합니다.
마치며
임시 저장 공간을 활용한 자리 바꾸기 원리만 알면 두 영역의 데이터 교환도 쉽게 구현할 수 있습니다.