[엑셀 VBA #18] 엑셀 매크로로 서식 지정하기(테두리, 폰트, 글자크기 등)



이번 엑셀 매크로 강의에서는 엑셀 셀의 서식을 설정하는 방법에 대해 알아보겠습니다.


엑셀 매크로로 셀 테두리, 색깔, 폰트, 글자 크기 등 다양한 서식을 구성할 수 있습니다.


매크로 파일을 받고 따라와주세요.




셀 테두리 만들기

Cells(3, 3).Borders(xlEdgeLeft).LineStyle = xlContinuous    '셀의 왼쪽 테두리 설정

Cells(3, 3).Borders(xlEdgeRight).LineStyle = xlContinuous    '셀의 오른쪽 테두리 설정

Cells(3, 3).Borders(xlEdgeTop).LineStyle = xlContinuous    '셀의 위쪽 테두리 설정

Cells(3, 3).Borders(xlEdgeBottom).LineStyle = xlContinuous    '셀의 아래쪽 테두리 설정


위와 같이 테두리가 생성됩니다.

테두리의 모양을 바꾸고 싶다면 xlContinuous를 다른 값으로 바꿔주면 됩니다.


xlDashDotDot       


xlDash                 


xlSlantDashDot      


xlDouble              



테두리의 굵기를 바꾸고 싶다면 .weight 설정을 하면 됩니다.


Cells(3, 3).Borders(xlEdgeLeft).Weight = xlThin

Cells(3, 3).Borders(xlEdgeRight).Weight = xlThin

Cells(3, 3).Borders(xlEdgeTop).Weight = xlMedium

Cells(3, 3).Borders(xlEdgeBottom).Weight = xlThick






셀 색상 변경하기


Cells(4, 3).Interior.Color = vbRed




색상값은 vbRed, vbBlue등으로 설정할 수 있지만, 다양한 사용자 정의 색상은 RGB로 설정할 수 있습니다.


Cells(4, 3).Interior.Color = RGB(111, 222, 50)







문자 서식 지정하기


Cells(3, 4).Font.Size = 8        '폰트 크기(글자 크기) 설정 

Cells(4, 4).Font.Bold = True        '폰트 볼드체로 바꾸기 True/False

Cells(5, 4).Font.Name = "궁서체"    '폰트 바꾸기

Cells(6, 4).Font.Italic = True        '폰트 이탤릭체(기울임꼴) 바꾸기 True/False

Cells(7, 4).Font.Underline = True        '폰트에 밑줄 긋기 True/False








Posted by Simon K
:

[엑셀 VBA 예제5] 값에 따라 셀 색깔 바꾸는 엑셀 매크로




이번 예제는 엑셀에 값을 입력할 때 마다 지정한 값에 따라서 셀 색상이 바뀌는 엑셀 매크로입니다.


[엑셀 VBA 강의 #15]에서 강의한 내용을 응용했습니다.






위와 같은 시트에서, 거래금액 란의 금액에 따라 색깔이 자동적으로 바뀌는 매크로를 만들어 보고자 합니다.


Private Sub worksheet_change(ByVal Target As Range)


Dim i As Integer

Dim n As Integer

Dim m As Integer


If Not Intersect(Range("c2:c9"), Target) Is Nothing Then

'----------------------여기부터 범위가 1보다 클 경우

If Target.Count > 1 Then            '타겟의 범위가 1보다 크다면(바뀌는 값의 범위가 한개가 아니라면)


n =  Target.Row                    '값을 수정하는 범위의 첫 행 (가장 윗행)

m = n + Target.Count - 1            '값을 수정하는 범위의 마지막 행(첫 행 + 범위 크기 - 1)


For i = n To m                            '범위의 첫 행부터 마지막 행까지 반복


    Select Case Cells(i, 3).Value            '셀의 값을 조건으로 한 조건문

    Case 0                                        '값이 0이라면(없다면)

    Cells(i, 3).Interior.color = xlNone        '셀을 투명하게(초기화)

    Case Is < 300000                            '값이 300000보다 작다면

    Cells(i, 3).Interior.color = RGB(255, 0, 0)        'red 색상으로 변경

    Case 300000 To 10000000                '값이 300000과 10000000 사이라면

    Cells(i, 3).Interior.color = RGB(0, 255, 0)        'green 색상으로 변경

    Case Is > 10000000                        '값이 10000000보다 크다면

    Cells(i, 3).Interior.color = RGB(0, 0, 255)        'blue 색상으로 변경

    End Select

Next i                    '다음 셀에서 반복


Exit Sub                '프로시져 종료

else

End If

'-------------------------여기까지 범위가 1보다 클 경우


'-------------------------여기부터 범위가 1일경우(한개의 셀만 수정할 경우)



    Select Case Target

        Case 0

        Target.Interior.color = xlNone

        Case Is < 300000

        Target.Interior.color = RGB(255, 0, 0)

        Case 300000 To 10000000

        Target.Interior.color = RGB(0, 255, 0)

        Case Is > 10000000

        Target.Interior.color = RGB(0, 0, 255)

    End Select

End If


End Sub





※ 이해가 안된다면 [엑셀 VBA #15] 강의를 읽어보세요.





Target의 범위가 무엇을 뜻하는 것인가요?


셀의 값을 수정할 경우, 일반적으로 한 개의 셀을 선택한 후 값을 집어넣지만,

복사 붙혀넣기를 통해 여러 값을 한번에 넣을 수도 있고, 셀을 드래그 블록지정 한 후 삭제를 해서 값을 없앨 수도 있습니다.


이러한 경우 Select Case Target으로 조건문을 만든다면, 타겟의 범위가 넓고, 값이 여러개이기 때문에 에러가 나게 됩니다.

따라서, Range 범위가 1일 경우와 1보다 큰 경우를 따로 설정하여 에러를 방지하기 위함입니다.


범위가 1보다 클 경우 반복문을 사용해 셀을 하나씩 읽어들이는 방법을 사용합니다.












Posted by Simon K
:

[엑셀 VBA 예제4] 기간별(날짜별) 합계 구하기



이번 예제는 기간/날짜별 합계를 구하는 예제입니다.


사업체를 운영하거나, 가계부를 작성하거나, 모종의 이유로 장부를 작성하고 있는 경우에 날짜별로 합계를 구할 필요가 있습니다.







위와 같은 장부에서, 날짜별 액수를 더하고 E1셀부터 날짜를, E2셀부터 입금액을 넣는 VBA입니다.

버튼을 누르게 되면 아래와 같은 결과를 얻을 수 있습니다.







Sub example()


Dim sumdata()                '값을 넣을 배열 추가

Dim nrow As Long            '시작하는 셀의 행

Dim ncol As Long                '시작하는 셀의 열

Dim lastD As String             

Dim i As Integer   

Dim D as string



    nrow = 2                '시작하는 셀의 행

    ncol = 1                '시작하는 셀의 열

    i = 1                    '카운터(배열의 행을 추가하기 위한)

    lastD = Left(Cells(nrow, ncol).Value, 7)        '날짜 중복을 방지하기 위한 설정

        For nrow = 2 To Cells(2, 1).End(4).Row        '시작행 2부터 값이 있는 마지막 셀까지 반복

        

        D = Cells(nrow, ncol).Value         '날짜 값 변수에 넣기               

            If D <> lastD Then                '이전 날짜 값과 같지 않다면

            i = i + 1                            '카운터에 1을 더한다

            End If

                ReDim Preserve sumdata(1 To 2, 1 To i)    '배열 재선언(카운터만큼 열을 늘린다)

                sumdata(1, i) = D                '날짜값을 배열의 첫 값에 넣음

                sumdata(2, i) = sumdata(2, i) + Cells(nrow, ncol).Offset(0, 1)   '누적되는 액수를 두번째 칸에 넣음

                lastD = D                'lastD값 재생성

        Next nrow             '날짜가 변할때 까지 액수 누적 반복       

   

    Cells(1, 4).Resize(2, i) = sumdata        '배열을 셀에 집어넣기

    


End Sub







ReDim Preserve는 무엇일까요?


Redim 배열()을 할 경우에는 배열의 값이 empty로 초기화됩니다.


하비만 Redim Preserve 배열()을 선언하는 경우에는, 배열의 칸이 작아지거나 아예 변경이 되지 않는 이상, 값이 변동되지 않습니다.






Posted by Simon K
:

[엑셀 VBA #17] 중복되지 않는 난수 랜덤 추출하기






본 강의에서는 겹치지 않는 난수를 추출하는 방법에 대해 알아보겠습니다.


난수를 추출하는 것은 Rnd 구문으로 쉽게 처리할 수 있지만 난수를 중복되지 않게 처리하려면 일련의 과정을 거쳐야 합니다.






RND 함수


Rnd 함수는 0부터 1 사이의 소수 난수를 생성합니다. (0.00000...1 ~ 0.99999...9)



INT 함수


Int 함수는 인수로 지정된 숫자의 정수부분만을 추출합니다.



원하는 만큼 정수 난수 생성하기


Rnd 함수와 Int 함수를 사용하면 원하는 만큼 정수 난수를 생성할 수 있습니다.


Int(Rnd * 정수 최대값) + 1


예를 들어, Int(Rnd * 50) 는 0에서 49까지의 정수를 반환합니다.


그 값에 1을 더하게 되면 1에서 50까지의 정수를 반환하게 됩니다.





예제 : 로또 번호 추출기 만들기


이번 예제는 7개의 서로 다른 번호(로또)를 추출하는 예제입니다.


Rnd, Int함수와 지난 강의에서 배웠던 배열 오름차순 정렬(버블정렬), 그리고 숫자가 중복되지 않게 하는 방법이 사용됩니다.




Sub example_12()


Dim lotto(1 To 7) As Integer

Dim i As Integer

Dim a As Integer

Dim ii As Integer

Dim n As Integer

Dim m As Integer

Dim sorttemp As Integer


i = 1                


For i = 1 To 7                    '로또 번호가 7개이기 때문에 7번 반복해서 난수 추출


restart:


Randomize                        '난수 재생성

   a = Int(Rnd * 50) + 1        '난수 a 생성(1~50)


lotto(i) = a                        'lotto배열의 각 항에 난수값 입력

            


            For ii = LBound(lotto) To (i - 1)        '첫 난수부터 지금 추출된 난수의 전값(i - 1)까지 반복

                Select Case lotto(ii)             '즉 lotto배열의 마지막 값(지금 추출한 난수)과 이전 난수를 반복 비교

                    Case lotto(i)

                  GoTo restart                    'lotto(ii) 이전 난수값과 lotto(i) 지금 추출한 난수값이 같으면 restart로 이동

                End Select

            Next ii                    '여기까지 중복값 배제하는 코드


Next i



'여기부터 난수 오름차순 정렬(버블정렬) 이해가 안가면 전강의 보세요.

'정렬이 필요가 없다면 아래 For~Next 부분은 전부 삭제해도 무방합니다.

For n = 1 To UBound(lotto) - 1            

    

    For m = 1 To UBound(lotto) - n

        If lotto(m) > lotto(m + 1) Then

            sorttemp = lotto(m + 1)

            lotto(m + 1) = lotto(m)

            lotto(m) = sorttemp

        End If

    

    Next m


Next n                                                '버블정렬 종료


Cells(3, 1).Resize(, UBound(lotto)) = lotto        '세로1 가로7의 배열을 셀에 입력



End Sub



위 코드를 실행하면,




위와 같이 각기 다른 난수를 오름차순으로 추출할 수 있습니다.






저의 강의는 순차적으로 난이도를 높혀가고 있습니다.


강의가 이해가 안된다면 처음 강의부터 차근차근 공부하면 쉽게 이해할 수 있습니다.














Posted by Simon K
:

이전 포스팅 바로가기

배열 관련 포스팅 바로가기


[엑셀 VBA #16] (배열#3)배열 내림차순/오름차순 정렬

(버블 정렬)




이번 포스팅에서는 배열 내의 값을 내림차순/오름차순으로 정렬하는 법에 대해 배워보겠습니다.




엑셀 VBA로 엑셀의 정렬 기능을 구현하는 방법은 여러가지가 있습니다.


그 중 가장 간단한 버블 정렬에 대해 알아보도록 하겠습니다.


예제를 받고 따라와주세요.





버블 정렬이란?


예를 들어 3 , 4 , 6 , 5  이라는 배열이 있다고 쳐봅시다.


버블 정렬을 위 배열에 사용하게 되면 아래와 같은 프로세스가 진행됩니다. (내림차순 정렬으로 설명하겠습니다.)


1. 배열의 첫 항은 두번째 항보다 작은가? 작다면 두 항 위치를 바꾸고, 그렇지 않다면 그냥 내버려 둔다.

배열 변경 : 4 , 3 , 6 , 5


2. 새로운 배열의 두번째 항은 세번째 항보다 작은가? 작다면 위치를 바꿔주고, 그렇지 않다면 내버려 둔다.

배열 변경 : 4 , 6 , 3 , 5


3. 새로운 배열의 세번째 항은 네번째 항보다 작은가? 작다면 위치를 바꾸고, 그렇지 않다면 움직이지 않는다.

배열 변경 : 4 , 6 , 5 , 3

4. 다시 배열의 첫번째 항은 두번째 항보다 작은가? 작다면..... 그렇지 않다면 .....    (생략하겠습니다.)

배열 변경 : 6 , 4 , 5 , 3


5. 배열의 두번째 항은 세번째 항보다 작은가? ........

배열 변경 : 6 , 5 , 4 , 3


6. 다시 배열의 첫번째 항은 두번째 항보다 작은가? ......

배열 변경 : 6 , 5 , 4 , 3 (변화 없음)


7. 내림차순 배열(6 , 5 , 4 , 3) 완성



버블 정렬은 앞 항과 바로 뒤 항의 비교의 반복입니다.


첫 항부터 시작해서, 마지막 항까지의 비교 및 위치 교체가 완료되면 가장 작은 수는 마지막으로 가게 됩니다.


그 다음엔 마지막 항(가장 작은 수)를 배재하고 나머지 숫자들끼리 비교 및 위치 교체를 진행합니다.


그러면 맨 뒤에 가장 작은 수, 뒤에서 두번째에 두번째로 작은 수가 위치하게 됩니다.


이런 프로세스를 항의 개수만큼 진행하면, 마지막에는 내림차순으로 정렬된 배열을 만들 수 있습니다.






이번 예제는 정렬이 안된 성적을 내림차순으로 정렬하는 예제입니다.





Sub example_11()


Dim score()                '점수 배열 선언

Dim sortemp as integer        '바뀌는 대상을 임시로 저장하는 변수   

Dim maxval As Long            '총 항 개수를 구하기 위한 변수

Dim n As Long                   

Dim m As Long


     maxval = Cells(2, 2).End(4).Row - 1        '점수 총 개수를 구함


   ReDim score(1 To maxval)                '점수의 개수에 맞춰서 배열 재선언

    

    score = Application.Transpose(Cells(2, 2).Resize(maxval, 1).Value)        '값을 score 배열에 집어넣음


'Application.Transpose는 열을 행으로(또는 반대로) 바꿔주는 함수. 1차배열은 우로 나열되기 때문에 위치를 바꿔준다


For n = 1 To UBound(score) - 1        '첫번 째 행부터 몇번 반복되야하는지 설정 총 100개라면 99번 반복

    

    

    For m = 1 To UBound(score) - n            '배열의 개수만큼 반복하는 반복문

        If score(m) < score(m + 1) Then        'm번째 항이 m + 1번째 항보다 작다면

            SortTemp = score(m + 1)            '임시저장변수에 m + 1 항의 값을 넣고

            score(m + 1) = score(m)            'm 항의 값을 m + 1 항에 넣는다

            score(m) = SortTemp                'm 항에는 임시저장변수에 저장되있던 m + 1항의 원래값을 넣는다

'(결국 m과 m + 1 항의 값이 바뀜)

        End If

    

    Next m

    

Next n


Cells(2, 3).Resize(maxval, 1) = Application.Transpose(score)            '옆 열에 정렬된 배열을 삽입.



End Sub



※주황색 글자로 쓰인 부분이 버블 정렬의 기본 구조입니다.







Posted by Simon K
:

[엑셀 VBA #15] 셀에 특정 값이 입력될때 실행되는 메크로




지금까지 제가 다뤘던 엑셀 VBA 메크로는 버튼을 눌렀을 때 실행되는 메크로였습니다.


이번 엑셀 VBA 강의에서는 엑셀의 셀에 값을 입력했을 때 실행되는 메크로에 대해 살펴보겠습니다.







어떤 상황에서 사용할 수 있을까?


▶셀에 입력할 수 있는 글자 수를 제한하고 싶을 때(금지어 설정할 때)

▶셀에 값이 입력될 때 폰트, 글자크기, 글자무게(볼드체 여부), 밑줄 등 서식을 바로 지정하고 싶을 때

▶셀에 값을 입력할 때, 함수 없이 연산을 진행하고 싶을 때

▶ ..........



이 외에도 정말 많은 상황에서 사용할 수 있습니다.





사용 방법


Private Sub worksheet_change(ByVal Target As Range)

If Not Intersect(범위, Target) Is Nothing Then

...

...

End If

End Sub


Target은?


Target은 변경되는 대상을 뜻합니다.


ByVal은?


ByVal은 ByRef와 대비됩니다.

코드를 작성할 때 기본값은 ByRef로 되어 있습니다.

ByVal은 상위 프로시져에서 프로시져를 실행 후 같은 값을 유지합니다.

ByRef는 프로시져 실행 도중에 값이 변할 수 있습니다.


따라서, Target 값이 중간에 변동되는 것을 방지하기 위해 ByVal으로 Target을 선언해 줍니다.


Intersect는?

Intersect는 인수의 교집합을 구합니다.

즉, Intersect("A1:B2", Target)의 경우,

변경되는 셀과 "A1:B2" 범위의 교집합이 있을 경우에 교집합 셀/범위를 지정합니다.





▶셀에 입력할 수 있는 글자 수 제한하기




위와 같은 엑셀에서, 생년월일이 입력되는 B2 셀에 입력되는 글자 수를 제한하려고 합니다.


※모듈에서 작성해야 합니다.


Private Sub worksheet_change(ByVal Target As Range)


If Not Intersect(Range("b2"), Target) Is Nothing Then  '변경되는 셀과 B2셀의 교집합. 즉, B2셀에서만 프로시저 발동


        Select Case Len(Target)        '변경되는 셀의 문자 길이값을 조건으로 설정

        

            Case 8, 0                '문자 길이값이 8 혹은 0일때 (8은 정확히 입력된 경우, 0은 아무것도 없을 경우)

            Exit Sub                 '프로시저 종료

            

            Case Else                '8과 0을 제외한 다른 값일 경우

            

            MsgBox "yyyymmdd 형식으로 정확히 입력하세요." 


            Target.Clear            '값 초기화

            

            End Select

            

        

    End If

End Sub


위 프로시저를 작성한 후 B2셀에 글자수가 8이 아닌 문자를 입력할 경우 오류메세지가 출력되며 값이 삭제됩니다.





▶셀에 값이 입력될 때 서식 지정하기




이름이 입력될 때, 글씨체 : 맑은 고딕; 폰트 크기 : 15pt; 폰트 무게 : Bold; 로 설정하고자 합니다.


Private Sub worksheet_change(ByVal Target As Range)


If Not Intersect(Range("b1"), Target) Is Nothing Then

    

    With Target

        .Font.Name = "맑은 고딕"

        .Font.Size = 15

        .Font.Bold = True

    End With

    

End If


End sub



B2셀에 값을 입력과 동시에 글씨체와 폰트 크기, 무게가 바뀐 것을 알 수 있습니다.





▶셀에 값이 입력될 때, 함수 없이 연산하기



위와 같은 시트에서 년도별로 액수를 입력할 경우 보험료 총액이 자동으로 계산되는 코드를 짜보겠습니다.


Private Sub worksheet_change(ByVal Target As Range)


If Not Intersect(Range("B4:B19"), Target) Is Nothing Then

    Sheet13.Cells(3, 2).Value = Application.WorksheetFunction.Sum(Range("B4:B19"))

    End If


    

End Sub








※ Worksheet_change 프로시저는 한 번만 작성할 수 있습니다.


따라서, 시트변경 함수를 여러개 지정하고 싶은 경우, 같은 Worksheet_change 프로시저에 작성해야 합니다.

글머리에 업로드된 예제 파일의 엑셀 VBA 콘솔창을 열어보면 위에 설명한 3가지 코드가 같은 프로시저에 들어가 있는 것을 알 수 있습니다.







Posted by Simon K
: