시트 위에 ActiveX 컨트롤(텍스트 상자, 콤보 상자 등)을 올려놓고 VBA로 셀을 다루다 보면 Selection 에서 갑자기 오류가 나는 경우가 있습니다. 컨트롤에 포커스가 가 있는 동안에는 Selection 이 셀 범위가 아니라 그 컨트롤 객체를 가리키기 때문입니다. Selection.Row 나 Selection.Value 를 셀이라고 생각하고 쓰면 그 순간 형식이 맞지 않아 멈춥니다.
이럴 때 쓰는 게 ActiveWindow.ActiveCell 입니다. 포커스가 컨트롤에 있어도 창에서 현재 활성 셀이 어디인지는 그대로 돌려주기 때문에, 컨트롤과 셀을 오가는 코드에서 안전하게 셀 위치를 얻을 수 있습니다.
ActiveWindow.ActiveCell
활용 예 - 칸마다 한 글자씩
원고지나 답안지처럼 칸 하나에 글자 하나씩 들어가는 양식을 엑셀로 만들면, 셀마다 클릭하고 입력하고 Tab 누르기를 반복해야 해서 금방 지칩니다. 아래 예제는 B3:I20 영역의 셀을 클릭하면 텍스트 상자로 포커스를 옮겨 두고, 텍스트 상자에 입력된 글자를 한 글자씩 꺼내 현재 칸에 넣고 다음 칸으로 넘어가게 만든 것입니다.

시트에 ActiveX 텍스트 상자(TextBox1)를 하나 놓고, 아래 코드를 그 시트의 코드 창에 넣습니다.
Private Sub TextBox1_Change()
Dim T As String, C As Range
T = Mid(TextBox1, 1, 1)
Set C = ActiveWindow.ActiveCell
If Application.Intersect(Range("B3:I20"), C) Is Nothing Then Exit Sub
If Len(C) Then C.Next.Activate: Set C = ActiveWindow.ActiveCell
If Application.Intersect(Range("B3:I20"), C) Is Nothing Then Cells(C.Row + 1, 2).Activate
ActiveWindow.ActiveCell = T
TextBox1.Activate
TextBox1 = Mid(TextBox1, 2)
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub
If Not Application.Intersect(Range("B3:I20"), Target) Is Nothing Then TextBox1.Activate
End Sub
흐름
Worksheet_SelectionChange 는 셀 하나를 클릭했을 때 그 셀이 B3:I20 안이면 텍스트 상자를 활성화합니다. 여러 셀을 드래그한 경우는 건너뜁니다. 이제 키보드 입력은 텍스트 상자로 들어갑니다.
TextBox1_Change 가 핵심입니다. 텍스트 상자 내용 중 첫 글자를 T 에 꺼내 두고, 현재 활성 셀을 ActiveWindow.ActiveCell 로 얻습니다. 여기서 Selection 을 썼다면 텍스트 상자가 잡혀서 오류가 났을 자리입니다. 현재 칸에 이미 글자가 있으면 C.Next 로 오른쪽 칸으로 옮기고, 옮긴 칸이 영역(I열)을 벗어났으면 다음 행의 B열로 줄을 바꿉니다. 그 칸에 글자를 넣고 텍스트 상자에서 첫 글자를 잘라 냅니다.
마지막 줄에서 텍스트 상자 내용이 바뀌니 Change 이벤트가 다시 일어나고, 남은 글자가 있으면 같은 과정을 반복합니다. 그래서 문장을 통째로 붙여 넣어도 글자가 칸마다 하나씩 흩어져 들어갑니다. 내용이 빈 문자열이 되면 T 도 빈 값이라 마지막 호출은 빈 칸을 하나 쓰고 끝나는 구조입니다.
바꿔 쓸 때
영역은 코드 세 군데의 "B3:I20" 과 줄바꿈할 때 돌아가는 열 번호 2(B열)를 같이 고쳐야 합니다. 범위만 바꾸고 열 번호를 그대로 두면 줄바꿈 뒤 엉뚱한 열로 갑니다. 그리고 Range.Next 는 Tab 키처럼 오른쪽 셀을 돌려주는데, 시트 보호가 걸려 있으면 잠기지 않은 다음 셀로 이동하는 식으로 동작이 달라집니다. 양식을 보호해서 쓸 계획이라면 보호 상태에서 한 번 시험해 보세요.