• 최초 작성일: 2000-08-10
  • 최종 수정일: 2026-09-30
  • 조회수: 8 회
  • 작성자: 권현욱 (엑셀러)
  • 강의 제목: 시트 정렬하기

들어가기 전에

오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.

Excel에서 작업을 하다보면 경우에 따라서는 작업 시트가 10개, 20개, 마구 불어나고 나중에는 이 시트들을 사전순으로 정렬을 해 주어야 하는 경우가 생길 것입니다. 예를 들어 시트가 30개 정도 된다면 이들 중에서 자기가 원하는 시트로 이동하려면 어떻게 할까요?

물론 시트이동 탭을 오른쪽 마우스 버튼으로 눌러서 (그나마) 좀 쉽게 이동하는 방법도 있지만 그것도 시트 가 많다면 시트 이름이 한번에 다 나타나지 않아 불편할 것입니다. 먼저, 이 워크북에 있는 여러 시트들의 위 치를 무작위로 흩어놓은 다음, 아래의 버튼을 누르세요.

잘 되지요? 이번 강좌에서는 이렇게 시트를 이름순으로 정렬하는 방법에 대해 설명을 드리겠습니다. 코드를 보시기 전 에 '어떻게 하면 이런 것이 가능할 것인가?' 머리속에서 한번 생각해 보시는 것이 좋을 것입니다.

시트를 정렬하는 것도 아마 여러 가지 방법이 있을 것으로 생각이 됩니다만 제가 주로 사용하는 두 가지 방 법에 대해 소개해 드리지요. 혹시라도 다른 기발한 방법이 있는 분은 알려주시기 바랍니다.

권현욱(엑셀러)
저자: 권현욱(엑셀러), 아이엑셀러 대표

필자는 Excel 컨설턴트, 작가, 그리고 크리에이터입니다. 현재 Microsoft Excel MVP이며, 『챗GPT+엑셀 업무자동화 정석』을 비롯한 10여 권의 도서를 집필했습니다. Excel 자동화 및 생산성 향상 분야에서 25년 넘는 경력을 보유하고 있습니다.

권현욱(엑셀러) 님의 최신 포스트:
  • 최신 글을 불러오는 중...


26년 경력 Microsoft MVP 권현욱(엑셀러) 대표 직강 1강 무료

🎁 파워툴스 마스터클래스 · 엑셀 바이브 코딩

AI에게 말로 지시해서 '나만의 엑셀 도구'를 만들고 리본에 장착합니다.

  • 코딩 지식 없이 시작 · 코드는 AI가 작성
  • 엑셀 리본에 내 탭과 버튼을 만들고 XLAM으로 공유
  • 1강 무료 수강 가능
수강 신청하기 강의 소개 보기

시트 정렬하기

핵심 요약: 시트를 이름순으로 정렬하기

시트 이름을 정렬한 결과대로 Move 메서드로 시트 위치를 바꾸면 이름순 정렬이 됩니다.

  • 방법 1: Temp 시트의 A열에 시트 이름을 적고 Sort한 뒤 순서대로 Move합니다.
  • 방법 2: 배열에 이름을 담고 버블 소트로 인접한 이름을 교환합니다.
  • 핵심: 두 값을 바꿀 때는 임시 저장공간을 사용합니다.

방법 1: 시트 이름을 셀에 적고 정렬하기

(방법 1) 각 시트의 이름을 워크시트에 표시한 다음 Sorting을 활용하는 방법

Sub SheetSortByName2()
    Dim sht As Worksheet
    Dim rngCell As Range
    Dim intNum As Integer
    Dim intCount As Integer
    Dim strTemp As String
    '//먼저 등장인물(변수)을 설정해 줍니다.

    Application.DisplayAlerts = False
    Worksheets.Add.Name = "Temp"
    '//보통 시트를 삭제하려고 하면 "시트를 정말로 삭제할까요 말까요?…"하고 물어오는데 "Application.
    '//DisplayAlerts=False"라고 지정을 하면 묻지 않고 바로 지웁니다.
    '//그리고 나서 워크시트를 한 장 삽입한 다음, 시트이름을 "Temp"라고 정해줍니다.

    For Each sht In Worksheets
        intCount = intCount + 1
        Cells(intCount, 1) = sht.Name
    Next sht
    '//각 워크시트를 돌면서 시트의 이름을 좀전에 삽입한 워크시트의 A1셀부터 아래로 가면서 차례로 적어
    '//둔 다음,
    Columns(1).Sort key1:=Range("A1"), order1:=xlAscending, Header:=xlNo
    '//첫번째 열을 기준으로 오름차순 정렬을 합니다. 그러면 시트의 이름들이 사전순으로 나열되겠지요?

    For Each rngCell In Range("a1").CurrentRegion.Columns(1).Cells
        intNum = intNum + 1
        strTemp = rngCell.Value
        Sheets(strTemp).Move before:=Sheets(intNum)
    Next rngCell
    '//For~Next 순환문을 돌면서 Temp 시트의 A열에 있는 각 셀들의 값을 strTemp라는 변수에 저장을
    '//하고 시트의 위치를 바꾸어 줍니다. 이 과정을 시트 수만큼 반복해 주면 사전순 배열이 될 것입니다.
    '//왜 그렇게 되냐고요? 종이에다가 intNum값을 하나씩 증가시켜 가면서 위의 순환문을 한바퀴씩 돌려
    '//보세요. 그러면 금방 답이 나옵니다 ^^.

    Sheets("Temp").Delete
    '//이렇게 해서 정렬이 끝난 다음에는 Temp라는 임시 작업공간 시트는 삭제를 해 주어야 겠지요?
    '//만약 이것을 삭제하지 않을 경우, 다음 번에 이 프로시저를 다시 실행하게 되면 에러가 나겠지요?
    '//왜냐하면 프로시저 초반부에 Worksheets.Add.Name="Temp"라는 구문 때문이지요.
End Sub

방법 2: 버블 소트 알고리즘 사용하기

버블소트 알고리즘 이라고 하니까 겁부터 나시지요? ^^;

아래와 같이 한 셀에는 "토끼"라는 값이 입력되어 있고, 다른 셀에는 "거북이"라는 값이 들어 있습니다. 그렇다면 이 두 값을 서로 바꾸어 주려면 어떻게 해야 할까요? 즉 토끼가 든 셀은 거북이로, 거북이가 든 셀은 토끼로 바꾸어 주려면 말입니다.

먼 말인지 이해가 안 가시지요? ^^ 아래의 "토끼/거북이 바꾸기" 버튼을 눌러 보세요.

어떻습니까? 버튼을 한번 누를 때마다 두 셀의 값이 서로 바뀌지요? 어떻게 하면 이렇게 될까요? 알고보면 간단합니다.

  1. (1) 먼저 "토끼"라는 값을 임시 저장공간에다가 담아둡니다.
  2. (2) "거북이"라는 값을 가져와서 "토끼"위에 엎어씁니다.
  3. (3) 원래 "거북이"가 들어있든 셀을 (1)에서 임시 저장공간에 담아두었던 토끼로 대치합니다.

이렇게 3단계 작업을 하면 되겠지요? 논리적으로는 아주 간단합니다. 코끼리를 냉장고에 넣는 3단계와 흡사한 것도 같지요? 하하하!! 농담입니다.

Sub SwapCells()
    Dim varTemp
    varTemp = Range("B77").Value
    Range("B77").Value = Range("D77").Value
    Range("D77").Value = varTemp
End Sub

이것은 버블소트 라고는 할 수는 없겠지만 이 아이디어를 약간 응용한 것이 버블소트 알고리즘입니다. 코드를 살펴 볼까요?

Sub SortByBubbleSort()
    Dim i As Integer
    Dim j As Integer
    Dim varTemp
    Dim strName() As String
    '//변수를 선언하는 것은 보통 때와 똑같은데… strName()이라고 하는 배열변수를 하나 선언한 것이
    '//조금 다르군요. 배열변수에 대해서는 설명을 드렸던가요? 드렸군요. 예전에 셀을 병합하는 방법에
    '//대해 설명을 드릴 때 (동적) 배열변수를 사용해서 해결을 했었지요? 기억이 안나는 분들은 다시
    '//살펴보시기 바랍니다. 어짜피 반복학습이 중요한 것이니까…

    i = Sheets.Count
    ReDim strName(1 To i)
    '//현재 시트의 수를 카운팅 한 다음, 다시 strName() 배열변수의 크기(정확히 말하자면 차원의 크기)
    '//를 다시 지정해 주었습니다.

    '//ReDim문은 Dim문에 의해 이미 선언된 동적 배열의 크기를 지정(또는 재확정)할 때 사용합니다.
    '//배열의 요소나 차원의 개수를 바꾸고자 할 경우, ReDim문을 여러 번 반복해서 사용할 수도 있으나
    '//배열변수의 타입이 Variant가 아니라면 데이터 타입 자체를 바꿀 수는 없습니다. 보다 자세한 사항은
    '//도움말을 참고하시도록…

    For i = LBound(strName()) To UBound(strName())
        strName(i) = Sheets(i).Name
    Next i
    '//배열과 관련하여 새로운 것이 하나 나왔군요. Ubound()는 배열에서 지정된 차원의 최대범위를  돌려
    '//줍니다.(누구 기죽일려고 작정을 했나? 지정된 차원의 최대범위를 어쩐다구?!@#$) ^^;)
    '//쉽게 말해서 strName(1 to 10, 1 to 5)라고 하게 되면 이것은 2차원 배열이 됩니다. 가로/세로 방향으
    '//로 있으니까 2차원인 것이지요. 그리고 차원의 최대범위라는 것은 그냥 해당 차원이 갖는 제일 큰 값
    '//이라고만 생각해 두세요. (Lbound()는 Ubound()와는 반대의 특징을 갖는 것이겠지요?)

    '//즉 For LBound(strName())=1 To Ubound(strName())에서 최대범위는 얼마일까요? ReDim strName(I)
    '//에 의해서 현재 워크북의 워크시트 수만큼이 되겠지요? 지금 보시는 파일에서 시트수가 몇 개 입니까?
    '//7개 이지요. 따라서 Ubound()는 7인 것이지요.

    For i = UBound(strName()) - 1 To LBound(strName()) Step -1
    '//여기서 Ubound(strName())-1을 해 준 이유는 아시겠지요? 현재 시트를 다른 시트들과 비교를 해야
    '//하므로 당연히 현재 시트와 현재 시트를 비교할 필요는 없겠지요? 그래서 -1을 해 준 것입니다.

        For j = 1 To i
            If strName(j) > strName(j + 1) Then
                varTemp = strName(j)
                strName(j) = strName(j + 1)
                strName(j + 1) = varTemp
                Sheets(varTemp).Move after:=Sheets(strName(j))
                '//이 단계에서 버블소트를 사용하였지요? 현재 시트의 이름을 그 다음 시트 이름과 비교를
                '//해서 현재 시트 이름이 크면(크다는 말은 사전순으로 따졌을 때 뒷부분이라는 얘기이지요!)
                '//(1) 현재 시트 이름을 임시 저장공간에 담아두고, (2) 다음 시트의 이름을 현재 시트 이름으로
                '//바꾸어 주고, (3) 다음 시트의 이름을 임시 저장공간에 있는 이름으로 바꾸어 주는 것입니다.

                '//말이 좀 엉킨 것 같은데, 위에서 설명드린 토끼/거북이를 서로 바꾸는 방법과 비교를 해 보시
                '//기 바랍니다. 똑같은 논리적 구조이니까요.

                '//그 다음에는 현재 시트를 다음 시트의 위치로 이동 시켜주면 되는 것이지요.
            End If
        Next j
    Next i
End Sub

마무리

코끼리를 냉장고에 넣는 방법과 비슷합니까?(하나도 안 비슷하다고요?!@#$) 논리적인 개념을 잘 정리해 두시기 바랍니다. 아마 여러 분야에서 응용이 가능할 것입니다.

그럼…

정리 — 시트 정렬 핵심

구분 사용한 코드 역할
임시 시트 Worksheets.Add.Name = "Temp" 정렬용 작업 공간
정렬 Columns(1).Sort key1:=Range("A1") 이름 오름차순
시트 이동 Sheets(strTemp).Move before:=Sheets(intNum) 순서대로 배치
배열 크기 ReDim strName(1 To i) 시트 수만큼 확보
교환 varTemp = strName(j) 임시 저장 후 교환

자주 묻는 질문 (FAQ)

Q1. 임시 시트를 마지막에 삭제하는 이유는 무엇인가요?

삭제하지 않으면 다음에 프로시저를 실행할 때 같은 이름의 Temp 시트를 추가하려다 오류가 발생합니다.

Q2. Application.DisplayAlerts = False는 무슨 역할을 하나요?

시트를 삭제할 때 나타나는 확인 메시지를 표시하지 않고 바로 삭제하도록 합니다.

Q3. UBound와 LBound는 무엇인가요?

배열의 지정한 차원에서 가장 큰 첨자와 가장 작은 첨자를 돌려줍니다.

마치며

논리적인 개념을 잘 정리해 두면 여러 분야에 응용할 수 있습니다.