엑셀 VBA 마지막 셀 찾기 (마지막 행·열 번호 구하기)
시트 전체는 UsedRange 로, 특정 행·열은 End(xlUp)·End(xlToLeft) 로 마지막 셀을 찾아 행·열 번호를 구합니다.
데이터가 어디까지 채워져 있는지 모른 채 매크로를 돌리면 빈 행까지 훑거나 자료를 놓칩니다. 마지막 셀의 행·열 번호를 먼저 구해 두면 범위를 정확히 잡을 수 있습니다.
바로 쓰는 코드
대부분의 상황에서는 UsedRange 로 충분합니다.
'// 시트에서 사용된 전체 범위의 마지막 셀
With ThisWorkbook.Worksheets("시트명")
Dim endRow As Long '// 마지막 행
Dim endCol As Long '// 마지막 열
endRow = .UsedRange.Rows.Count + .UsedRange.Row - 1
endCol = .UsedRange.Columns.Count + .UsedRange.Column - 1
End With
특정 열이나 행 하나만 볼 때는 End 속성을 씁니다.
'// A열의 마지막 행 / 1행의 마지막 열
With ThisWorkbook.Worksheets("시트명")
Dim endRow As Long
Dim endCol As Long
endRow = .Cells(.Rows.Count, 1).End(xlUp).Row
endCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
사용 예제
마지막 셀의 주소와 행·열 번호를 메시지 상자로 보여 주는 명령문입니다.
Sub Print_FinalCell()
Dim sShtName As String
sShtName = "시트1" '// 시트명을 입력합니다.
With ThisWorkbook.Worksheets(sShtName)
Dim endRow As Long
Dim endCol As Long
Dim endCell As String
endRow = .UsedRange.Rows.Count + .UsedRange.Row - 1
endCol = .UsedRange.Columns.Count + .UsedRange.Column - 1
endCell = .Cells(endRow, endCol).Address
End With
MsgBox sShtName & "의 마지막 셀은 " & endCell & "입니다." & vbNewLine & _
"행 번호는 " & endRow & ", 열 번호는 " & endCol & "입니다."
End Sub
동작 원리 1 — End 속성은 Ctrl + Shift + 방향키입니다
Range.End 는 시트에서 Ctrl + Shift + 방향키를 누른 것과 같습니다. 기준 셀에서 값이 이어진 마지막 셀까지 건너뜁니다.
| 값 | 이동 방향 |
|---|---|
xlUp |
위로 |
xlDown |
아래로 |
xlToLeft |
왼쪽으로 |
xlToRight |
오른쪽으로 |
맨 아래 행에서 xlUp 으로 거슬러 올라오는 이유는, 중간에 빈 셀이 있어도 진짜 마지막 값에 닿기 때문입니다.
동작 원리 2 — UsedRange 는 사용된 전체 범위입니다
시트1의 B2:C14 를 썼다면 이렇게 동작합니다.
Set rng = ThisWorkbook.Worksheets("시트1").UsedRange
'// B2:C14 범위를 돌려줍니다.
endRow = rng.Rows.Count '// 사용된 행의 개수 → 13
startRow = rng.Row '// 범위가 시작되는 행 번호 → 2
endRow + startRow - 1 '// 13 + 2 - 1 = 14 (마지막 행 번호)
행 개수와 시작 위치를 더한 뒤 1을 빼는 이유는, 개수는 1부터 세지만 번호는 시작 행부터 세기 때문입니다. 열도 같은 원리입니다.
동작 원리 3 — Rows.Count 로 시트 크기를 받아옵니다
시트가 가질 수 있는 행·열 개수는 버전마다 다릅니다.
| 엑셀 버전 | 최대 행 | 최대 열 |
|---|---|---|
| 2003 이전 | 65,536 | 256 |
| 2007 이후 | 1,048,576 | 16,384 |
오빠두Tip : 숫자를 직접 적어도 동작하지만
.Rows.Count·.Columns.Count 를 쓰는 편이 낫습니다. 옛 버전에서 열려도 깨지지 않고, 코드에서 1048576 같은 숫자를 읽어 내야 할 일이 없습니다.참고 문서
- Range.End 속성 — Microsoft Learn
- Worksheet.UsedRange 속성 — Microsoft Learn
관련 게시글
엑셀 VBA Application.ScreenUpdating 사용법 (매크로 속도 개선)
명령문 앞에서 ScreenUpdating 을 False 로 두면 실행 중 화면 갱신이 멈춰, 셀을 많이 건드리는 매크로일수록 속도가 크게 빨라집니다.
엑셀 개발 도구(매크로) 활성화 방법
[파일] - [옵션] - [리본 사용자 지정]에서 '개발 도구'에 체크하면 매크로와 VBA 편집기를 쓸 수 있는 탭이 리본에 나타납니다.
엑셀 데이터 통합 기능으로 여러 시트 합계 구하기
[데이터] - [통합]에서 각 시트의 범위를 머리글째 추가하고 '첫 행'·'왼쪽 열'을 체크하면, 시트가 흩어져 있어도 항목별 합계가 한 번에 계산됩니다.
근데 제걸로 만들려면 참 많은 노력이 필요하겠네요! ㅎㅎ
네 물론 입니다.
아래 명령문을 응용해보시겠어요?
Sheet1.Cells(Sheet1.Rows.Count ,1).End(xlUp).Column ' 열값을 반환합니다.
제시해드린 답변이 도움이 되셨길 바랍니다.
감사합니다.
지금 셀 값을 복사할때 셀에 값이 없으면 offset이랑 end 때문에 다음 행으로 넘어가서 복사를 하는데, 하나의 열이라도 비어있는 열이 있어도 포함해서 복사하는 방법은 없을까요?
Range("XFD1").End(xlToLeft).Column
실무에 응용해 보고자 하는데, 어떤 A열 마지막셀에 값을 넣어야 할 경우
가령 A열에 표가 A1:A10까지 있고 문자나 숫자가 A5까지 기록 되어 있다면(A6:A10까지는 공백), 매크로를 실행하면 문자를 건너띄고 공백을 지나 A10에 표시가 되는데,
저는 셀에 값이 있는 A6셀을 찾고자 할 때는어떻게 해야 되는지요?
(vba로 구현해야 할 때)
이 부분이 의미하는 바는 멀까요??
endRow = .UsedRange.Rows.Count 이렇게만 해도 구해지는거 아닌가요?
.UsedRange.Rows.Count
는 사용한 범위의 행 개수를 반환하므로
시트 범위가 1행이 아닌 중간부터 시작되면 잘못된 값을 반환해서
.UsedRange.Row - 1
를 사용하는 것이 좋습니다.^^