반응형

안녕하세요.

 

행 방향으로 같은 내용인 셀을 하나로 병합하는 방법을 소개했습니다.

 

2022.08.03 - 같은 내용인 근처 셀들을 하나로 병합하기

 

같은 내용인 근처 셀들을 하나로 병합하기

안녕하세요. 실습 파일 다운로드 VBA 다운로드 데이터 분석 기능을 이용해서 결과를 나타냈습니다. 그대로 사용해도 되지만 A, B열처럼 보통 같은 내용인 셀들을 하나로 묶어 셀을 병합해서 사용

hantip.net

 

이미 만들어진 VBA 코드를 엑셀 파일에 삽입해서 사용하는 방법을 소개했는데, 이 강좌에서는 VBA 코드를 하나씩 만들면서 코드의 의미를 알아 보겠습니다.

 

실습 파일 다운로드

같은 내용인 근처 셀들을 하나로 병합하기_실습.xlsx
0.03MB

VBA 다운로드

CellMerge.txt
0.00MB

 

완성된 코드입니다.

Public Sub 셀합치기()
    Temp = ActiveCell
    TempR = ActiveCell.Row
    
    Application.DisplayAlerts = False
    
    Do While ActiveCell <> ""
        If ActiveCell.Offset(1, 0) <> Temp Then
            Range(Cells(TempR, ActiveCell.Column).Address, ActiveCell.Address).Merge
            
            Temp = ActiveCell.Offset(1, 0)
            TempR = ActiveCell.Offset(1, 0).Row
        End If
        
        ActiveCell.Offset(1, 0).Select
        
        DoEvents
    Loop
    
    Application.DisplayAlerts = True
End Sub

 

이제 만들어 보겠습니다.

 

제일 먼저 실습 파일을 열어 엑셀을 실행합니다.

그리고 <Alt + F11>를 눌러 VBE를 실행합니다.

[삽입]-[모듈]을 선택합니다.

다시 [삽입]-[프로시저]를 선택하고 [프로시저 추가] 대화상자에서 '이름''셀합치기'를 입력하고 [확인]을 클릭합니다.

완성된 코드 15줄2줄이 벌써 만들어 졌습니다.

Sub ~ End Sub이 하나의 작업 단위입니다. 프로시저라고 하고, 매크로이기도 합니다.

 

Sub 앞의 Public은 일단 넘어갑니다.

 

Sub 아래 빈 줄에 커서를 두고 <Tab>을 한 번 눌러 안으로 들여 씁니다.

코드의 포함 관계를 나타내기 위해 들여쓰기를 해야 하고, <SpaceBar>를 여러 번 누르는 것보다 <Tab>을 이용하는 것이 편리합니다.

 

Temp=activecell을 입력하고 <Enter>를 누릅니다.

그러면 자동으로 Temp =  ActiveCell 로 바뀝니다.

=(이퀄) 앞 뒤로 빈 칸을 넣고 알려진 개체인 ActiveCell의 단어 첫 글자를 대문자로 표시합니다.

사용자가 입력할 때는 소문자로 다 입력하고 <Enter>를 누르면 자동으로 첫 글자가 대문자로 바뀌는 것을 확인해서 개체나 속성, 메소드를 제대로 입력했는지 확인할 수 있습니다.

개체나 속성, 메서드를 입력했는데, 자동으로 대문자로 바뀌지 않는다면 이름을 잘못 적었을 가능성이 있습니다.

 

앞의 Temp는 변수이고, 직접 대문자 T를 써야 합니다.

변수는 알려진 이름이 아니기 때문에 사용자가 입력한 형식 그대로 보여집니다.

다른 이름들과 같은 형식을 나타내기 위해 첫 글자를 대문자로 나타냈습니다.

 

변수는 ab처럼 간단히 적어도 되지만 입력된 내용이 무엇인지 유추할 수 있는 이름을 써야 코드를 한 눈에 볼 수 있습니다.

Temp는 전통적으로 임시 값을 저장할 때 사용하는 변수 이름입니다.

 

Temp 변수에 입력하는 ActiveCellActiveCell.Value를 생략한 것입니다.

ActiveCell은 현재 선택된 셀을 의미하는데, 그냥 ActiveCell이라고 쓰면 ActiveCell 개체의 대표 속성인 Value를 의미하는 것입니다.

코드의 의미를 정확하게 하기위해 ActiveCell.Value라고 쓸 수도 있었지만, 이렇게 쓰면 코드가 더 길어 보여 복잡하게 느낄 수 있기 때문에 줄여 적었습니다.

 

ActiveCell의 내용을 변수 Temp에 저장하는 이유는 코드를 좀 더 써 보면 알 수 있습니다.

코드를 작성하는 사람은 어떤 식으로 동작할 것인지 대략의 흐름을 머리속에서 계산하고 있습니다.

변수에 첫번째 값을 기억해 두었다가 다른 값과 비교해서 사용하는 이 방법은 아주 전형적인 코드입니다.

위에서부터 아래로 한 행씩 다음 행과 값을 비교해서 뭔가 처리를 하는 작업, 개수를 헤아릴 수도 있고, 합계를 구할 수도 있는, 프로그램을 만들 때 다양하게 쓰이는 알고리즘입니다.

 

다음 줄에 TempR=activecell.row를 입력합니다.

끝부분의 점(.)만 입력하면 자동으로 [구성원 자동 목록]이 표시됩니다.

[구성원 자동 목록]이 나타났을 때 r을 입력하면 r로 시작하는 목록을 선택합니다.

속성이나 메서드를 모두 입력하거나 나타난 목록에서 선택하고 <SpaceBar><Enter>를 누르면 입력됩니다.

변수 TempR을 입력할 때는 직접 대소문자를 구분해서 넣어야 합니다.

변수 TempR에는 ActiveCell의 행번호를 저장합니다.

TempRow라고 이름을 정할 수도 있었는데, 이름이 길면 복잡해 보일 수 있어 짧게 TempR로 정했습니다.

 

빈 줄을 넣어 띄우고, do를 입력한 뒤 <Enter>를 두 번 눌러 빈 줄을 넣고 loop를 입력합니다.

완성된 코드에는 있는 내용을 적지 않고 넘겼습니다.

빠진 내용은 나중에 넣을 겁니다.

꼭 필요한 코드이긴 하지만 현재 작업을 수행하는 흐름에 필요한 코드는 아닙니다.

 

완성된 코드를 보면 위에서 아래로 순서대로 쓴 것처럼 보이지만, 코드를 작성하다 보면 필요에 따라 위 아래로 왔다 갔다 하며 만듭니다.

기능을 구현하는데 꼭 필요한 코드를 만들고 나서 꾸미거나 오류 처리를 하는 코드를 적게 됩니다.

앞으로 코드를 볼 때 이런 걸 감안해서 코드를 보면 의미를 이해하는데 도움이 됩니다.

 

Do ~ Loop 명령문은 반복문입니다.

조건을 지정해서 반복 처리할 때 사용하고, 이 코드에서는 데이터 첫 행부터 마지막 행까지 차례대로 한 행씩 바꿔가면서 필요한 작업을 할 것입니다.

그냥 Do ~ Loop를 쓰면 무한반복하게 됩니다.

그래서 꼭 종료할 조건을 입력해야 합니다.

조건은 Do 옆에 쓸 수도 있고, Loop 옆에 쓸 수도 있습니다.

 

우리가 작성할 코드는 Do 옆에 조건을 지정합니다.

Do 옆에 적을 것인지 Loop 옆에 적을 것인지는 처리하려는 작업 내용에 따라 달라 집니다.

 

마지막 행까지 반복실행해야 하는데, 어떤 경우가 마지막 행을 의미하는지 알아야 합니다.

여기서 마지막 행은 셀 값이 없는 경우, 빈 셀인 경우입니다.

그래서 조건으로 while activecell<>""을 입력합니다.

조건을 지정할 때 While은 조건이 참인 경우에 반복하고, Until은 조건이 거짓인 경우 반복합니다.

Until보다 While을 많이 씁니다.

 

Do 아래 빈 줄에 코드를 입력합니다.

if activecell.offset(1,0) <> Temp then

Offset상대적인 위치를 나타냅니다.

첫번째 인수는 행, 두번째 인수는 열을 나타내고 Offset(1,0)은 행 방향으로 1 증가한 셀을 의미합니다.

현재 셀[A3] 셀이라면 Offset(1,0)[A4] 셀을 의미합니다.

 

Offset(1,0)Offset(1,0).Value에서 Value를 생략한 것입니다.

 

ActiveCell이 현재 셀을 의미하니까 ActiveCell.Offset(1,0)은 다음 행의 셀을 의미합니다.

다음 행의 내용과 앞에서 현재 셀의 내용을 저장해둔 Temp 변수의 내용과 다른지 비교합니다.

같은 경우엔 다음 행으로 넘어가면 되고, 다른 경우엔 변수 TempR에 저장해 둔 행 번호부터 현재 셀까지 병합하고 다음 행으로 넘어가야 합니다.

 

If ~ End If 명령문은 조건을 비교해서 참인 경우와 거짓인 경우에 따라 다른 동작을 하도록 합니다.

If로 시작하면 항상 End If로 끝나야 합니다.

그래서 If를 썼다면 바로 다음 줄에 End If를 미리 써 두는 것이 실수를 막는 방법입니다.

Do 명령문도 바로 Loop를 적었습니다.

셀 병합하는 코드는 Range.Merge입니다.

Range 개체에 병합할 셀 범위를 적어야 합니다.

Range 개체에 셀 주소를 적을 땐 'A3'이나 'B3'처럼 행 숫자와 열 문자를 결합한 주소 형식을 적어야 합니다.

그런데 우린 범위를 시작할 숫자 형식의 행 번호를 변수 TempR에 저장해 두었습니다.

 

그래서 행 번호와 열 번호로 셀을 나타내는 Cells 개체를 이용해서 주소 형식을 찾아 나타냅니다.

 

Cells(TempR, ActiveCell.Column).Address

 

ActiveCell.Column은 현재 셀의 열을 숫자 형식의 번호로 나타냅니다.

Address 속성은 $A$3 형식으로 셀 주소를 나타냅니다.

 

병합할 마지막 셀은 현재 셀 주소입니다.

 

ActiveCell.Address

 

완성한 코드입니다.

Range(Cells(TempR, ActiveCell.Column).Address, ActiveCell.Address).Merge

이 코드를 실행하면 병합할 셀에 값이 있는 경우 경고메시지를 표시합니다.

반복해서 빠르게 실행되는 중 경고메시지가 표시되면 일일이 눌러야 다음 단계로 넘어가게 됩니다.

그래서 반복문이 실행되기 전에 경고메시지가 표시되지 않도록 코드를 입력하고, 반복문이 끝나면 원래대로 경고메시지가 나타나도록 코드를 추가합니다.

 

Application.DisplayAlerts = False

Loop 아래 빈 줄을 넣고 경고메시지가 표시되도록 코드를 입력합니다.

 

Application.DisplayAlerts = True

Application 개체는 프로그램 자체, 엑셀을 의미 합니다.

 

If 문에 다음 번 셀 병합을 위해 셀 내용과 셀 행 번호를 변수에 저장해 둬야 합니다.

Temp = ActiveCell.Offset(1, 0)
TempR = ActiveCell.Offset(1, 0).Row

End If 아래 다음 셀로 이동하도록 코드를 작성합니다.

 

ActiveCell.Offset(1, 0).Select

Select 메소드는 선택하는 역할이고 ActiveCell이 바뀌게 됩니다.

현재 셀이 [A3] 셀일 때 ActiveCell[A3] 셀이고, ActiveCell.Offset(1,0)[A4] 셀 입니다.

ActiveCell.Offset(1,0).Select를 실행하면 ActiveCell[A4] 셀이 되는 것입니다.

 

여기까지 작성하면 기능을 구현하는데 필요한 코드는 모두 만들어 졌습니다.

그런데 완성 코드에 한 줄 더 있습니다.

DoEvents 명령문은 제어권을 운영체제에게 넘깁니다.

 

Do ~ Loop 반복문에 문제가 생겨 무한반복되는 경우 강제로 멈출 방법이 없습니다.

DoEvents 명령문을 써 두면 강제로 멈출 수 있습니다.

그래서 보험처럼 반복문 안에 DoEvents를 써 둡니다.

코드가 제대로 동작한다면 나중에 지워도 됩니다.

 

이렇게 해서 코드를 모두 작성했습니다.

 

이 코드는 짧고 간단해서 좋지만 누구나, 어디에서나 쓰기엔 적당하지 않습니다.

사용자가 데이터 시작 셀인 [A3] 셀에 커서를 두지 않고 다른 곳에서 실행을 하거나 데이터 중간에 빈 셀이 있거나 하는 경우엔 제대로 동작하지 않습니다.

여러 열의 데이터를 범위 선택해서 한꺼번에 처리할 수도 없습니다.

그런 고려를 하지 않았기 때문에 짧고 간단한 것입니다.

 

다른 사람이 사용하도록 만드는 프로그램에는 오류 처리를 위한 코드가 아주 많이 포함됩니다.

사용자들은 잘못된 방법으로 프로그램을 쓰려고 하고, 코드를 만들 땐 생각해 보지도 않은 형식으로 씁니다.

 

그래서 이 코드는 이 코드를 만든 사람이나 어떻게 동작하는지 아는 사람이 써야 문제 없이 동작합니다.

 

이런 업무를 하는, 지금 이 강좌를 보고 있는 바로 여러분이 만들고 써야 하는 코드입니다.

 

VBA 문법이나 개체를 모두 다 알아야 프로그램을 만들 수 있는 것이 아닙니다.

이미 많은 강좌들이 인터넷에 올려져 있습니다.

필요한 내용을 검색해서 찾아 내가 하려는 업무에 맞게 조금 바꿔 써도 됩니다.

 

필요하신 분께 도움이 되길 바랍니다.

반응형

+ Recent posts