[엑셀 VBA #11] (배열#1) 배열 이해하기. 배열의 차원과 

정적, 동적배열




이번 시간부터는 엑셀 VBA를 배울 때 가장 까다로운 개념 중 하나인 배열에 대해 알아보겠습니다.


한 포스팅에 담기에는 벅찰 것 같아서 나눠서 진행하도록 하겠습니다.




배열은 확실히 까다로운 개념이 맞습니다.


하지만 정말 중요한 개념이고 많이 쓰이기 때문에 꼭 이해해야 하는 개념이기도 합니다.


엑셀 VBA의 배열은 수학적 개념의 배열과 동일합니다.


변수 i에 한 가지의 수, 문자를 저장할 수 있다면, 배열 i에는 한꺼번에 여러 개의 수와 문자를 저장할 수 있습니다.


하지만 안타깝게도 배열이 이렇게 단순하지만은 않습니다...


엑셀 VBA는 배열을 1차원부터 60차원까지 허용하고 있습니다.


이는 무엇을 의미하고 있는 것일까요?





N차 배열의 의미


1. 1차 배열


1차 배열은 직선형의 단순한 배열을 의미합니다.



배열 속에 있는 각각 개체들이 앞, 뒤 순서로만 배치되어 있습니다.


엑셀의 한 에 위치한 값들의 배열이라고 생각할 수 있습니다.





2. 2차 배열


2차 배열은 직사각형(정사각형) 의 배열을 의미합니다.



배열 속의 개체들이 상하좌우로 나뉘어서 배치되어 있습니다.


엑셀의 한 시트 안에 있는 값들의 배열이라고 생각할 수 있습니다. 배열이 (i, p)와 같은 좌표로 구성이 됩니다.




3. 3차 배열


3차 배열은 직육면체(정육면체) 의 배열을 의미합니다.




배열 속의 개체들이 상하좌우 및 위 아래로 배치되어 있습니다.


여러 시트(sheet1, sheet2, sheet3.....)로 구성된 엑셀 파일에 있는 값들의 배열이라고 생각할 수 있습니다. 배열이 (i, p, o)와 같은 좌표로 구성됩니다.





4. 4차 이상 배열


사실 4차 이상 배열은 잘 사용되지 않습니다. 엑셀의 범위를 넘어가기 때문이지요..


4차 배열의 경우 여러 엑셀 파일을 담고있는 폴더, 5차 배열의 경우 여러 폴더를 담고있는 하드드라이브, 6차 배열의 경우 여러 하드드라이브를 담고있는 컴퓨터, 7차 배열의 경우 여러 컴퓨터들을 담고있는 PC방에 비유할 수 있겠네요.


계속 차원을 넓혀가면 우주까지 다다를 수 있습니다. 


억지스런 비유이긴 하지만, 엑셀 VBA에 이런 고차원적인 요소는 필요 없기에,일반적으로 3차 배열까지만 사용되고 있습니다.


물론 4, 5, 6차 배열도 분명 사용할 수 있고 사용되고 있습니다. 하지만 일반적인 엑셀에는 그 만큼 넓은 배열이 필요하지 않습니다. 







자, 이해가 되시나요? 아직 좀 아리송할겁니다.


더 간단하게 비유해보겠습니다.


배열을 엑셀에 비유했을 때, 엑셀이라는 것이 점점 진화를 한다고 생각해 보겠습니다.


엑셀의 가장 작은 기본 단위는 "셀"입니다.


그렇다면 태초의 엑셀은 아래와 같다고 가정할 수 있습니다.


이 때의 엑셀에는 배열의 개념이 필요 없습니다.


셀이 하나밖에 없기 때문이죠.


하지만 엑셀이 한단계 진화한다면 말은 달라집니다.



엑셀이 한 단계 진화해서 한 개의 행을 이루었습니다.


이 때부터 배열의 개념이 필요하게 됩니다.


배열(0), 배열(1), 배열(2), ... , 배열(n)으로 구성된 1차 배열이 등장하게 됩니다.




엑셀이 한 단계 더 진화해서 시트를 구성했습니다.


배열(0, 0) 배열(0, 1) 배열(0, 2)..... 배열(n, m)으로 구성된 2차 배열이 등장하게 됩니다.




엑셀이 한 단계 더 발전해서 엑셀 파일을 구성했습니다.


배열(0, 0, sheet1) 배열(0, 0, sheet2) ..... 배열(n, m, sheetx)로 구성된 3차 배열이 등장하게 됩니다.






정적배열과 동적배열


정적배열과 동적배열의 개념은 간단합니다.


정적배열은 이미 배열의 용량을 정해준 배열이고, 동적배열은 배열의 용량을 정해주지 않은 배열입니다.


동적배열은 배열이 차지하는 크기가 확실하지 않을 때 사용합니다.


굳이 동적배열을 선언하지 않고 정적배열로 배열을 최대한 크게 만들어도 이론상으로는 상관 없습니다.


하지만 배열은 상당히 많은 메모리를 차지합니다.


배열을 불필요하게 크게 선언한다면 메모리 부족 현상이 나타나기 쉽습니다.


따라서 배열을 동적으로 선언하여 불필요한 메모리 차지를 방지해야 합니다.




정적배열의 선언


1차 정적배열


Dim varArray(1 to 10)


2차 정적배열


Dim varArray(1 to 10, 1 to 20)    '행은 10, 열은 20인 직사각형 배열


동적배열의 선언



1차 동적배열


Dim varArray()

...

...                '배열에 필요한 크기 n을 구함

Redim varArray(n)            'varArray() 배열을 크기 n의 정적배열으로 다시 선언



2차 동적배열


Dim varArray()

...

...                '배열에 필요한 행 크기 n, 열 크기 m을 구함

Redim varArray(1 to n, 1 to m)                'varArray() 배열을 행 크기 n, 열 크기 m의 정적배열으로 다시 선언






이번 포스팅에선 배열의 기본 개념과 배열의 차원, 그리고 정적, 동적 배열에 대해 알아봤습니다.


다음 포스팅은 배열에 대한 좀 더 심화된 내용으로 찾아오겠습니다.



Posted by Simon K
:



[엑셀 VBA #10] Find~Findnext 문 활용해서 검색하기





이번 주제는 바로 실무에 활용할 수 있는 Find~Findnext 문입니다.

Find~Findnext 문은 엑셀 VBA에서 활용도가 정말 높은 문법입니다.


Find문은 컨트롤 F 키를 눌러서 검색하는 것과 비슷한 기능을 할 수 있습니다.

검색된 부분을 다른 셀에 집어넣거나, 검색된 부분만 따로 떼어내는 등 여러 방면으로 응용할 수 있습니다.


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


숨겨진 시트를 숨김 해제하면 이전 내용들도 수록되어 있습니다.











이번 예제는 버튼을 누르면 'E1'셀에 있는 내용을 좌측 데이터베이스 '이름' 항목에서 검색 후, 우측 칸에 입력하는 예제입니다.


위 예제는 이름 전체가 일치해야 검색되는 예제이지만, 상황에 따라 부분검색으로 변환할 수도 있습니다.


Sub example_6()

Dim c as Range

Dim StrFirstaddr as String

Dim StrAddr as String


With Sheet7.Range("a1:a31")


    Set c = .Find(Cells(1, 5).Value, Lookat:=xlWhole)       '부분검색은 Lookat:xlPart



    If Not c Is Nothing Then                'c라는 값이 검색된다면 (c가 데이터베이스에 존재한다면)


    StrFirstaddr = c.Address            '첫 주소 설정 (무한루프 방지용)

    StrAddr = c.Address                '주소값 설정



        Do

        Range(StrAddr).Resize(, 3).Copy Cells(Rows.Count, 6).End(3)(2)        '값이 존재하는 셀 바로 아래에 복사하기

        Set c = .FindNext(c)                                '다음 c 값 찾기

        StrAddr = c.Address                                '셀 주소 설정

        Loop While Not c Is Nothing And StrAddr <> StrFirstaddr            '첫 주소와 겹치지 않을때까지 루프

 

    End If

 



End With


End Sub


정말 간단합니다.


모두 이전 엑셀 VBA 강의에서 배웠던 내용들입니다.


값을 복사하는 것 뿐만 아니라, 검색된 부분 삭제, 다른 시트로 이동 등등 여러 방면으로 응용이 가능합니다.


엑셀으로 데이터베이스의 기본적인 원리를 구현하는 것이라고 생각하면 됩니다.


사전 프로그램의 원리도 이와 비슷합니다.
























Posted by Simon K
:



[엑셀 VBA #9] 값이 있는 마지막 셀을 선택, End 속성







엑셀에서는 컨트롤 키를 사용해서 값이 있는 셀의 끝으로 이동할 수 있습니다. (컨트롤 + 방향키)


엑셀 VBA에서도 물론 가능합니다.


End 속성을 사용하면 됩니다.






Cells(8, 7).End(1).Select









Cells(3, 3).End(2).Select









자, 여기서 의문이 생기죠.

분명히 마지막 셀으로 이동한다고 했는데, 실제로 사용해보니 그렇지 않습니다.

값이 있는 셀을 선택했을 경우 공백을 만나면 멈춰버립니다.


End 속성은 선택된 셀로부터 일정 방향으로 한 칸씩 이동하면서 마지막 값을 만나면 멈춥니다.


만약 공백이 듬성듬성 있는 데이터베이스에서 진짜로 마지막에 위치한 값을 찾으려면 어떻게 해야 할까요?


답은 간단합니다. 반대로 하면 됩니다.


빈 칸을 선택 후 End 속성을 사용하면, 첫 번째 만나는 값이 있는 셀에서 멈춰버립니다.


컨트롤 + 방향키로 선택하는것과 100% 같습니다.






Rows.Count, Columns.Count 속성



Row.Count는 엑셀이 허용하는 행 개수의 최대치를 나타냅니다.


Columns.Count는 엑셀이 허용한는 열 개수의 최대치를 나타냅니다.


엑셀 2013 기준으로 최대 행 개수는 1048576개, 열 개수는 16384개입니다.


따라서 맨 끝 행, 혹은 맨 끝 열부터 셀을 한 칸씩 이동했을 때, 만나는 첫 번째 셀이 값을 지닌 마지막 셀이 되는 것입니다.







Cells(Rows.Count, 7).End(3).Select





맨 아래 셀에서 한 칸씩 올라오면서(End(3)) 만나는 첫 셀을 선택




Cells(8, Columns.Count).End(1).Select





맨 오른쪽 셀에서 한 칸씩 좌측으로 이동하면서(End(1)) 만나는 첫 셀을 선택







응용하기


그렇다면 맨 마지막 셀도 아니고, 마지막 셀의 그 다음 셀을 선택하고자 한다면 어떻게 해야할까요?


저번 시간에 배운 Offset 속성을 사용하면 됩니다.


Cells(Rows.Count, 7).End(3).Offset(1,0).Select











Posted by Simon K
:


[엑셀 VBA 예제2] 여러 시트에 있는 값을 한 시트로 옮기기






이번 엑셀 VBA 예제는 여러 시트에 있는 값을 조건에 맞춰서 한 시트로 취합하는 예제입니다.

With문, For~Next문, Find문, If문, Offset문, Instr문이 사용됩니다.


예제를 받아주세요.






이번 엑셀 VBA 예제의 내용은 아래와 같습니다.





위 두 시트의 자산 총계를 아래 시트의 자산 란에 연도별로 넣고자 합니다.


2015, 2016 두 가지의 자료만 넣는 예제이지만, 시트를 추가하면 2000년부터 2099년까지 활용할 수 있는 예제입니다.




엑셀 VBA를 본격적으로 작성하기 전에 어떻게 만들것인지 구상이 필요합니다.


제 구상은 아래와 같습니다:


1.  시트1(2015년 재무재표) ~시트n(2099년 재무재표) 이름의 연도값(20xx)을 인식 및 변수로 추출

2.  년도별로 해당하는 시트에서 "자산총계" 문자가 있는 셀을 찾고, 바로 아래의 값을 변수로 추출

3.  "비교" 시트의 년도값(20xx)의 행값과 "자산"의 열값을 변수로 추출 (n, 2)

4.  (행값, 열값)셀에 각 시트의 자산총계 바로 아래에 있는 값을 넣는다

5.  마지막 시트까지 반복






이제 엑셀 VBA 코드를 보겠습니다.


COMP는 이름이 "비교"인 시트 값을 뜻합니다.


조건1. 시트의 이름에는 20을 포함하는 년도값이 한번 포함되야 합니다.

조건2. 데이타를 합하는 시트의 시트 값은 "COMP"로 설정되어 있어야 합니다.

조건3. COMP 시트를 제외한 모든 시트 값은 기본값인 Sheet1~Sheetn으로 되어있어야 합니다.

조건4. 코드는 COMP 시트에서 실행하면 안됩니다.





Option Explicit                '변수가 선언(dim) 없이 사용되는 것을 방지


Sub example()

Dim b As Object

Dim c As Object

Dim d As Object

Dim wks As Worksheet

Dim stryear As String

Dim currrow As Integer

Dim currcol As Integer

Dim curval As Long



With ActiveWorkbook                            '해당 워크북에서

    

    For Each wks In Worksheets                '모든 워크시트를 순환

    

        If InStr(wks.Name, "20") <> 0 Then            '해당 워크시트의 이름에 20이 들어가면

                                  

                 With wks.Range("a1:z20")                                    'range 범위는 모든 값을 포함하는 범위로 설정

                      Set b = .Find("자산총계", lookat:=xlWhole)            '"자산총계" 값이 있는 셀을 찾는다

                        If Not b Is Nothing Then                    '"자산총계" 값이 하나라도 있다면

                

                        curval = b.Offset(1, 0).Value                'curval(변수)는 "자산총계" 셀 바로 아래의 셀 값으로 설정

                      End If

                 End With


stryear = Mid(wks.Name, InStr(wks.Name, "20"), 4)                    'stryear(변수)는 시트 이름에 포함된 년도값(20xx)

               

    

                  With COMP.Range("a1:z20")                    'COMP 시트에서 (Range 범위는 모든 값을 포함하는 범위)

            

                  Set c = .Find(stryear, lookat:=xlPart)            'stryear값을 포함하는 셀을 찾는다.

                       If Not c Is Nothing Then                    'stryear 값을 포함하는 셀이 하나라도 있다면

                

                        currrow = c.Row                    'currrow(변수) 값은 그 셀의 행값

                

                        End If

                

                

                   Set d = .Find("자산", lookat:=xlWhole)            '"자산"을 포함하는 셀을 찾는다

                    If Not d Is Nothing Then            

                

                     currcol = d.Column                        'currcol(변수) 값은 그 셀의 열값

                

                   End If

                     

                

                  End With

        

    

COMP.Cells(currrow, currcol).Value = curval       '년도와 항목에 맞춰서 값을 집어넣는다         '


 

        End If

    Next wks                    '다음 시트로 넘어가기



End With

 

 MsgBox "입력 완료"


End Sub



파란색으로 표시한 Instr 문은 string(문자열) 내에서 해당 문자가 시작되는 위치를 찾아줍니다.


따라서 문자가 존재하지 않는 경우 0의 값을 돌려주게 됩니다.


이를 응용해서 년도값을 추출할 때에는 mid문을 사용해서 instr과 조합해서 사용할 수 있습니다.


stryear = Mid(wks.Name, InStr(wks.Name, "20"), 4)


위 코드는 시트 이름에서 20이라는 문자의 위치를 찾고, 그 위치부터 오른쪽으로 4 자리의 숫자를 추출하는 코드입니다.


2020년의 경우에도 알맞은 값을 돌려줍니다. (처음 만나는 20을 찾기 때문)









Posted by Simon K
:


[엑셀 VBA #8] Resize, Offset 문을 이용한 셀 범위 설정



엑셀 VBA를 사용하다 보면 특정 셀 하나가 아닌 범위를 참조해야 하는 경우가 많습니다.


이러한 경우에 쓰이는 문법이 Resize문과 Offset 문입니다.





Resize


Resize문은 셀을 잡고 드래그하는 것과 같은 효과를 줍니다.






Cells(2,1).Resize(, 2).Select


위 사진과 같은 엑셀에 위 엑셀 VBA를 실행시키면 아래와 같이 선택됩니다.




Resize 괄호 안의 첫 번째 값이 커지면 아래로, 두 번째 값이 커지면 우측으로 드래그가 됩니다.


그렇다면 음수 값(마이너스 값)을 넣는다면 어떻게 될까요?


오류가 나게 됩니다.


가끔은 선택된 셀 좌측과 상단으로 범위를 설정해야 하는 경우도 생기게 되는데, 이 경우에 필요한 것이 Offset 문입니다.





Offset


※수정사항 : Offset문을 사용할 때에는 괄호 안 우측 값을 공백으로 두면 안됩니다.

   제가 공개한 스크린샷에는 우측 값이 공백으로 되있는데, 공백의 경우 0 값을 줘야 합니다.


Offset문은 선택된 셀을 기준으로 설정한 만큼 떨어진 곳에 위치한 셀을 선택합니다.


Cells(3,8).offset(, -1).Select


위와 같은 코드를 실행시키면




위와 같이 선택됩니다.

Resize문과 달리 음수 선택이 가능합니다.





그렇다면 선택한 셀의 좌측 혹은 상단으로 블록을 잡으려면 어떻게 해야 할까요?


Offset 문에서 사용한 엑셀을 재활용하겠습니다.




Cells(3, 8).Offset(, -1).Resize(, 2).Select


위 코드를 실행시키면...




이렇게 됩니다.


먼저 Offset으로 좌측의 셀을 지정한 후, Resize로 우측 한칸을 같이 블록지정 하게 됩니다.





Resize문과 Offset문은 엑셀 VBA에서 정말 많이 사용됩니다.

추후 엑셀 VBA 강의에서 계속~ 사용될 예정이니 꼭 확실히 이해하고 넘어가 주세요.














Posted by Simon K
:

[엑셀 VBA 예제1] 텍스트 파일(.txt) 엑셀에 입력하기




실무적인 엑셀 VBA에 관한 질문이 들어와서, 엑셀 VBA 기초 강의와는 별개로 실전 예제도 연재해 보려고 합니다.

익숙하지 않은 내용들이겠지만 실전 예제를 통해 공부하는 것도 큰 도움이 될 것이라 생각합니다.

같이 진행되는 엑셀 VBA 기초 강의와는 번외적인 내용으로, 진도에 맞지 않는 점 인지하여 주시기 바랍니다.




엑셀 VBA는 매우 강력한 프로그래밍 툴으로써, 외부파일과 연계도 가능합니다.


이번 포스팅은 텍스트 파일을 엑셀에 입력하는 예제를 소개해드리도록 하겠습니다.





위와 같이 열과 열이 일정한 관계를 갖고 있는 텍스트 파일의 경우, 동일한 배열으로 엑셀에 옮겨담을 수 있습니다.


위의 텍스트 파일은 열 간의 간격이 탭키로 설정되어 있지만, 콤마( , ), 세미콜론( ; ) 등 뿐만 아니라 어떠한 규칙도 그 규칙이 일정 하다면 충분히 엑셀로 옮길 수 있습니다.


이 텍스트 파일의 첫번째 줄을 제외하고 숫자부분을 열에 맞춰서 엑셀에 옮기고자 합니다.


이 명령을 실행하는 엑셀 VBA 코드는 아래와 같습니다.


Sub text_to_excel()

    Const loadf As Long = 2             '텍스트 파일 속에서 가져와야 하는 시작하는 행 위치

    Const loadt As Long = 99999            '텍스트 파일 속에서 가져와야 하는 마지막 행 위치보다 큰 값을 설정

    Dim strFileName As String              '텍스트 파일 이름 설정

    Dim objText As Object           '텍스트 문서 값 개체변수

    Dim i As Long                       '변하는 행값 변수

    Dim varValue As Variant           '엑셀에 입력되는 값

    

    

    

    Application.ScreenUpdating = False


    With Application.FileDialog(msoFileDialogFilePicker)

                             .Show              '파일피커 열기

        If .SelectedItems.Count = 0 Then        '아무것도 선택되지 않았을 경우 프로시저 종료

            Exit Sub

        Else

            strFileName = .SelectedItems(1)        '파일 이름 지정

        End If

    End With

    

    If Len(strFileName) > 0 Then                   '파일 이름의 길이가 0보다 크면 (파일이 존재하면)

        

        Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(strFileName, _

        IOMode:=1, Create:=False, Format:=-2)           '지정된 이름의 파일을 열기

        

        For i = 1 To loadt                      '지정한 행 수 만큼 반복하기

            If Not objText.AtEndOfStream Then           '텍스트파일의 끝이 아니라면

            If i < loadf Then                            '행의 위치가 지정된 시작 행(loadf)보다 작다면

            objText.skipline                            '그 행을 뛰어 넘는다

            Else

                varValue = Split(objText.ReadLine, vbTab)         '텍스트파일의 한 행의 값을 탭으로 분리해서 가져온다    

'vbTab을 "," ";" " " 등으로 바꿔서 사용할 수 있다.

                Cells(Rows.Count, 1).End(3)(2).Resize(, UBound(varValue) + 1) = varValue        '셀에 텍스트파일 값을 넣기                  

            End If

            End If

        Next i

    End If

       objText.Close

    Set objText = Nothing

    

End Sub



위 엑셀 vba 프로시저를 끝낸 후 엑셀에 출력되는 값은 아래와 같습니다.




만약에 특정 열의 값만 추출하고 싶다면 파란색으로 표시된 varValue 를 varValue(숫자) 로 바꿔주시고, 주황색으로 표시된 UBound(varValue)+1 부분을 1로 바꿔주시면 됩니다.   


varValue의 숫자값은 0부터 시작하는 정수가 되어야 합니다.


예를 들자면, varValue(1)는 2번째 열만 가져오게 됩니다.


이러한 방법을 통해서 텍스트 파일을 엑셀으로 옮겨올 수 있습니다.





그냥 넘어가긴 아쉬우니 제가 엑셀 VBA에서 자주 쓰는 간단한 편법을 하나 공개하도록 하겠습니다.


엑셀 VBA에서는 Worksheetfunction을 사용해서 엑셀 고유의 함수 기능을 구현할 수 있습니다.


하지만 Worksheetfunction을 굳이 사용하지 않고 엑셀 함수를 적용할 수 있는 방법 또한 존재합니다.


예를 들어 텍스트 파일의 2번째 열만 추출해서 평균값을 "E2"셀에 넣고, 평균값을 제외한 모든 값을 삭제해 보겠습니다.


Sub text_to_excel()

    Const loadf As Long = 2             '텍스트 파일 속에서 가져와야 하는 시작하는 행 위치

    Const loadt As Long = 99999            '텍스트 파일 속에서 가져와야 하는 마지막 행 위치보다 큰 값을 설정

    Dim strFileName As String              '텍스트 파일 이름 설정

    Dim objText As Object           '텍스트 문서 값 개체변수

    Dim i As Long                       '변하는 행값 변수

    Dim varValue As Variant           '엑셀에 입력되는 값

    

    

    

    Application.ScreenUpdating = False


    With Application.FileDialog(msoFileDialogFilePicker)

                             .Show              '파일피커 열기

        If .SelectedItems.Count = 0 Then        '아무것도 선택되지 않았을 경우 프로시저 종료

            Exit Sub

        Else

            strFileName = .SelectedItems(1)        '파일 이름 지정

        End If

    End With

    

    If Len(strFileName) > 0 Then                   '파일 이름의 길이가 0보다 크면 (파일이 존재하면)

        

        Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(strFileName, _

        IOMode:=1, Create:=False, Format:=-2)           '지정된 이름의 파일을 열기

        

        For i = 1 To loadt                      '지정한 행 수 만큼 반복하기

            If Not objText.AtEndOfStream Then           '텍스트파일의 끝이 아니라면

            If i < loadf Then

            objText.skipline

            Else

                varValue = Split(objText.ReadLine, vbTab)         '텍스트파일의 한 행의 값을 탭으로 분리해서 가져온다

                Cells(Rows.Count, 1).End(3)(2).Resize(, 1) = varValue(1)        '셀에 텍스트파일 값을 넣기      '

            End If

            End If

        Next i

    End If

        objText.Close

  '(a2:a99999) 값은 평균 낼 데이터를 포함하는 범위

        Cells(2, 5).value = "=average(a2:a99999)"                'average 함수식을 셀(E5)에 집어넣는다

        Cells(2, 5).value = Cells(2, 5).value                         '출력된 함수값을 일반 형식의 값으로 바꾼다.

        Range("a2:a99999").Value = ""                                 '텍스트파일에서 추출한 데이터를 삭제한다

    Set objText = Nothing

    

End Sub


초록색으로 표시된 부분이 추가된 부분입니다.


특정 셀에 함수식을 넣는 것만으로 함수식의 결과값을 얻어낼 수 있습니다.


average 함수 뿐만 아니라 엑셀의 모든 함수를 사용할 수 있습니다.


하지만 편법이다 보니 광범위하게 사용하기는 힘듭니다.


이런 방법도 있구나.. 하고 알아두시면 됩니다.


Worksheetfunction에 대한 내용은 추후에 엑셀 기초강의에서 다루도록 하겠습니다.











Posted by Simon K
:


[엑셀 VBA #7] SELECT CASE 조건문 활용하기



이번 시간에는 조건이 많을 경우 사용되는 SELECT CASE 조건문에 대해 알아보겠습니다.

조건문을 처음 접하시는 분은 저번 포스팅(if~else 조건문)을 먼저 읽어 보시고 시작해주세요.


늘 그렇듯이 예제와 함께 시작하겠습니다.

숨겨진 시트에 과거 포스팅 내용들이 담겨있습니다.







이번 예제는 지난번 예제와 비슷합니다.

학생의 점수 구간 별로 등급을 매기는 엑셀 VBA입니다.


SELECT CASE 조건문의 구조는 아래와 같습니다.


Select case 변수


case n1


명령


case n2


명령2


...


End Select


즉, 변수의 값을 케이스별로 구분해서 명령을 내린다는 뜻입니다.


예제를 살펴보겠습니다.


Dim i As Byte

Dim p As Byte


For i = 3 To 17 Step 1

p = Sheet6.Cells(i,2).Value


Select Case p

Case Is >= 90

Sheet6.Cells(i, 3).Value = "A"

Case Is >= 70

Sheet6.Cells(i, 3).Value = "B"

Case Is >= 50

Sheet6.Cells(i, 3).Value = "C"

Case Is >= 30

Sheet6.Cells(i, 3).Value = "D"

Case Is < 30

Sheet6.Cells(i, 3).Value = "F"


End Select


Next i


조건이 단순한 값인 경우에는 'Case a' 처럼 쓸 수 있지만,


조건을 범위로 둘 경우, 'Case is ~~'라고 작성해야 합니다.


또 한가지 주의해야 할 점으로, Select Case 문 역시 여타 엑셀 VBA 문법처럼 위에서 아래로 내려가는 실행 구조를 갖고 있습니다.


따라서 If~Else문과 같이, 합집합의 범위가 가장 작은 조건부터 작성해야 합니다.


간단하게 오류가 나는 예를 들어보겠습니다.


Dim i As Byte

Dim p As Byte


For i = 3 To 17 Step 1

p = Sheet6.Cells(i, 2).Value


Select Case p

Case Is < 30

Sheet6.Cells(i, 3).Value = "F"

Case Is >= 30

Sheet6.Cells(i, 3).Value = "D"

Case Is >= 50

Sheet6.Cells(i, 3).Value = "C"

Case Is >= 70

Sheet6.Cells(i, 3).Value = "B"

Case Is >= 90

Sheet6.Cells(i, 3).Value = "A"


End Select


Next i


위 예제가 앞서 보여드린 예제와 다른 점은 조건의 순서가 바뀐 것입니다.


이 예제에는 30보다 크거나 같은 조건을 앞에다 위치시켰습니다.


이런 경우에는 30보다 큰 모든 값이 D로 표시되게 됩니다.


F8을 눌러서 순차적으로 실행해 보면 알 수 있겠지만, Select Case문 같은 경우, 조건에 맞는 Case를 찾게 되면 명령을 실행한 후 바로 End Select로 넘어가게 됩니다.


따라서 각 조건의 관계는 아래 그림과 같이 형성되야 합니다.

A에서 D까지의 순서로 조건을 지정해 주어야 오류를 방지할 수 있습니다.


A의 조건을 먼저 실행하고 나면 그 다음 B 조건의 실제 범위는 A를 포함하지 않는 B의 범위가 됩니다.


따라서 조건이 서로 겹치지 않게 됩니다.





엑셀 VBA에서 가장 중요하고 기초가 되는 문법이 조건문과 반복문입니다.


꼭! 이해하고 넘어가 주세요.


다음 포스팅부터는 아주 조금 난이도를 높혀서 진행하도록 하겠습니다.













Posted by Simon K
:


[엑셀 VBA #6] IF~ELSE 조건문 활용하기




엑셀 VBA의 조건문은 두 가지로 분류될 수 있습니다.

첫째는 IF~ELSE문, 둘째는 CASE 문 입니다.

이번 포스팅에서는 조건문 중 하나인 IF~ELSE문에 대해 알아보도록 하겠습니다.


이번에도 마찬가지로 예제와 함께 시작하겠습니다.

시트 숨김을 해제하시면 이전 예제들도 확인할 수 있습니다.






이번 예제는 조건에 맞는 셀에 색상을 입히는 엑셀 VBA입니다.


위 예제는 조건문과 반복문이 같이 응용된 구조입니다.


IF~ELSE 조건문은 일반적으로 아래와 같이 구성됩니다.


If 조건1 and 조건2 ... 조건n


명령


else


명령


end if


상황에 따라 여러가지 조건을 부여할 수 있습니다.

조건식은 논리연산식을 기초로 합니다.


엑셀 VBA의 IF~ELSE 조건문은 엑셀 자체의 함수와 비슷합니다.

다만 단순 연산이 아닌 명령을 실행하는 데에 엑셀 자체 기능은 한계가 있기 때문에 그런 경우에 엑셀 VBA로 사용합니다.


예제의 코드를 살펴보겠습니다.


Dim i As Byte


For i = 3 To 10 Step 1           '3번째 행부터 10번째 행까지 색을 입혀야 하기 때문에 행을 i 로 하는 반복문을 만듭니다.


If Sheet5.Cells(i, 2).Value <= 60 Then                '셀의 값이 60보다 작거나 같을 경우

Sheet5.Cells(i, 1).Interior.Color = RGB(100,100,100)                '왼쪽 셀의 색깔을 RGB(100,100,100)으로 바꿉니다.

Else                   '60보다 같거나 작은 경우, 60보다 큰 경우, 두 가지뿐이 없기 때문에 Else 이하 명령은 생략합니다.

End If


Next i








두 번째 예제는 엑셀 VBA의 IF~ELSE 문을 활용한 다중조건문입니다.

엑셀 자체의 IF 함수에 다중 조건문을 형성할 수 있는 것처럼, 엑셀 VBA의 IF~ELSE 조건문도 다중으로 구성할 수 있습니다.


Dim i As Byte


For i = 14 To 21 Step 1


    If Sheet5.Cells(i, 2).Value = 0 Then

    Sheet5.Cells(i, 1).Interior.Color = RGB(100, 10, 10)


    Else

    

        If Sheet5.Cells(i, 2).Value = 100 Then

        Sheet5.Cells(i, 1).Interior.Color = RGB(200, 200, 200)

        

        Else

            If Sheet5.Cells(i, 2).Value <= 60 Then

            Sheet5.Cells(i, 1).Interior.Color = RGB(100, 100, 100)

            Else

            End If

        End If

    

    End If

        

Next i


잘 보시면 위의 식과 순서가 바뀌어있습니다.

값이 60보다 작거나 같을 경우를 가장 아래에 놓은 이유는, 0 또한 60보다 작거나 같을 경우에 해당하기 때문입니다.

따라서 조건이 가장 작고 다른 조건과 교집합이 존재하지 않는 조건을 가장 앞에 둬야 합니다.




사실 엑셀 VBA의 IF~ELSE문은 조건이 여러개일 경우 적합하지 않습니다.

식도 길어지고 제한이 많이 있습니다.

따라서 조건이 여러개일 경우에는 CASE문을 사용하는 것이 알맞습니다.


다음 포스팅은 CASE 조건문을 사용한 다중 조건문에 대해 알아보겠습니다.








Posted by Simon K
:

"엑셀 VBA, 왜 필요할까?"


           



컴퓨터가 발명된 이래, 사람의 뇌를 컴퓨터로 이식하려는 노력은 끊임없이 이어지고 있습니다.

사람의 뇌가 컴퓨터보다 못한 부분도 물론 있긴 하지만, 아직 컴퓨터가 따라오지 못하는 부분도 많이 존재합니다.

엑셀 또한 마찬가지입니다. 

엑셀 자체로도 아주 뛰어난 프로그램이긴 하지만, 엑셀은 분명한 한계를 지니고 있습니다.


엑셀의 가장 기본적인 기능을 예를 들어서 표현하자면 아래와 같습니다.

① "  '셀 A'의 값과 '셀 B'의 값을 더해서 '셀 C'에 출력하라.  "

하지만 위 명령이 이렇게 바뀐다면 어떨까요?

② "  '셀 A'의 값과 '셀 B'의 값을 더하는 행위를 100번 시행하고, 그 값을 '셀 C'에 출력하라.  "


엑셀은 1번과 같은 명령은 처리할 수 있지만, 2번과 같은 명령은 처리하지 못합니다.

이유가 무엇일까요?


사실 예제 ①의 경우에도 약간 오류가 있습니다.

엑셀은 사용자의 '명령'을 받는 프로그래밍 언어가 아닙니다.

엑셀은 내장된 함수로 구현할 수 있는 범위에서만 작동합니다.


엑셀에는 2013버전 기준으로 461개의 함수가 내장되어 있습니다.

엑셀의 각 셀은 제공되는 함수를 사용하여 다른 셀과 연계하여 연산을 진행합니다.

하지만 함수로 정의되지 않은 명령들(복잡한 다중 조건문, 반복문)등은 사용자가 직접 명령을 만들어줘야 하는데,

이 때 필요한 것이 엑셀 VBA입니다.


즉, 예제 ①의 경우는 간단하게 '+' 연산자로 연산식을 만들 수 있지만,

예제 ②의 경우는 저런 기능을 하는 함수가 없기 때문에 엑셀 자체에서는 구현할 수 없다는 것입니다.

따라서 엑셀은 사용자들이 직접 명령을 내릴 수 있게 프로그래밍 툴인 VBA(Visual Basic Advanced)를 빌려오게 됩니다.





엑셀 VBA, 어떻게 배워야 하나?


결론부터 말하자면, 엑셀 VBA는 프로그래밍 지식이 없어도 충분히 독학할 수 있습니다.

물론 전문가처럼 마스터할 수는 없지만, 자신이 필요로 하는 기능을 구현하는 정도까지는 누구나 할 수 있습니다. 

하지만 독학이 '책을 사서 혼자 공부하는 것'은 절대 아니라는것을 명심하셔야 합니다.

엑셀 VBA는 지극히 실용적인 지식입니다. '공부'라는 단어는 엑셀 VBA와 어울리지 않습니다.

직접 해보셔야 합니다. 



프로그래밍 지식이 전혀 없다면 자기 자신을 돌도 지나지 않은 아기라고 생각하세요.

아기들은 본능적으로 서서 걸으려고 시도합니다. 

자꾸 넘어져도 계속 일어나려고 애를 씁니다.

하지만 아기들은 '걷는 법'이라는 책을 사서 공부하지는 않습니다.

이상한 비유이긴 하지만, 엑셀 VBA도 똑같습니다.

어떻게 하는지 모르더라도 일단 시도해 보세요.

'자기가 필요한게 뭔지, 엑셀로 구현해야 하는 기능이 무엇인지 생각을 하고, 그 기능을 직접 알아내셔서 적용시켜 보는 그 과정'

이 과정이 엑셀 VBA를 독학하는 과정입니다.

개인적인 이야기를 하자면 저는 엑셀 VBA를 군생활 할 때 처음 접했습니다.

당시에 부대 PC 윈도우즈 OS를 대대적으로 업그레이드 하면서 일부 프로그램이 작동을 안하게 된 적이 있었지요.

주소를 검색하는 프로그램이었는데, 인트라넷으로는 외부 파일을 가져오기도 힘들고, 다른 프로그래밍 툴을 구하기도 힘들었기에

그나마 엑셀에 기본 내장되있던 엑셀 VBA를 사용해서 주소를 검색하는 엑셀 프로그램을 만들었었습니다.

프로그래밍 지식이 하나도 없었음에도 불구하고, 엑셀 VBA에 내장되어 있는 도움말만으로도 충분했습니다.

도움말으로 공부하라는 것이 아닙니다. 저는 무엇이 중요한가를 말하고 싶습니다.

자기 자신이 필요로 하는 기능을, 처음엔 당연히 허접하겠지만, 그래도 한 번 만들어 보세요.

인터넷에서 검색해보고, 다른 사람들이 올려놓은 예제를 참고하면 충분히, 충분히 만들 수 있습니다.

얼마나 많은 명령어를 외우고 있느냐가 중요한 것이 아닙니다.

인터넷에 검색하면 명령어는 1분이면 찾을 수 있습니다.

'실제로 구상하는 기능을 엑셀 VBA를 사용하여 엑셀에 응용시킬 수 있는가?'

이것이 엑셀 VBA의 관건이고, 공부해야하는 능력입니다.

단언컨데, 절대로 책에선 배울 수 없습니다. 실천만이 답입니다.

다음 포스팅은 좀 더 구체적인 독학 방법으로 찾아오겠습니다.






위 포스팅에 사용된 아이콘 이미지는 www.flaticon.com의 Freepik에 의하여 제작되었습니다

Icon made by Freepik from www.flaticon.com










 




Posted by Simon K
: