엑셀 & VBA/엑셀 VBA 강좌

엑셀 VBA 강좌(8): 엑셀 VBA 언어 기본-자료형(Data type), 자료구조(Data structure)

ProDA 2021. 8. 2.

이 글은 새로운 블로그로 옮겼습니다. 5초후 자동으로 이동합니다.

▶ 새로운 블로그 주소: https://prodskill.com/

▶ 새로운 글 주소: https://prodskill.com/excel-vba-lecture-8-datatype/

이번 글은 엑셀 VBA 언어 기본 중 자료형(Data type)과 제공되는 자료구조(Data structure)에 대해 살펴본다.

 

이전 글에서 이어지는 내용이다.

엑셀 VBA 강좌(7): 엑셀 VBA 언어 기본-문법(Syntax)

 

엑셀 VBA 강좌(7): 엑셀 VBA 언어 기본-문법(Syntax)

이번 글은 엑셀 VBA언어 기본 중 문법(Syntax)에 대해 살펴본다. 이전 글에서 이어지는 내용이다. 엑셀 VBA 강좌(6): 엑셀 VBA 언어 기본-변수 엑셀 VBA 강좌(6): 엑셀 VBA 언어 기본-변수 이전 글에서 

prodtool.tistory.com

 

목차

     

    3.3. 자료형

     

    3.3.1. 기본 자료형

    VB(또는 VBA)에서 지원하는 자료형을 요약하면 다음 표와 같다. 아래 출처의 표 내용중 Collection, Dictionary는 "자료 구조"에서 별도로 설명한다.

    기본 자료형 목록

    출처: https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/data-type-summary

     

    Data type summary

    Data type summary In this article --> A data type is the characteristic of a variable that determines what kind of data it can hold. Data types include those in the following table as well as user-defined types and specific types of objects. Set intrinsic

    docs.microsoft.com

    데이터 형식 저장 용량 범위
    Boolean 2 bytes True 또는 False
    Byte 1 byte 0 ~ 255
    Collection Unknown Unknown
    Currency (scaled integer) 8 bytes -922,337,203,685,477.5808 ~ 922,337,203,685,477.5807
    Date 8 bytes January 1, 100, to December 31, 9999
    (100-01-01 ~ 9999-12-31)
    Decimal 14 bytes +/-79,228,162,514,264,337,593,543,950,335 with no decimal point

    +/-7.9228162514264337593543950335 with 28 places to the right of the decimal

    Smallest non-zero number is+/-0.0000000000000000000000000001
    Dictionary Unknown Unknown
    Double (double-precision floating-point) 8 bytes -1.79769313486231E308 to -4.94065645841247E-324 for negative values

    4.94065645841247E-324 to 1.79769313486232E308 for positive values
    Integer 2 bytes -32,768 to 32,767
    Long (Long integer) 4 bytes -2,147,483,648 to 2,147,483,647
    LongLong (LongLong integer) 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

    Valid on 64-bit platforms only.
    LongPtr (Long integer on 32-bit systems, LongLong integer on 64-bit systems) 4 bytes on 32-bit systems

    8 bytes on 64-bit systems
    -2,147,483,648 to 2,147,483,647 on 32-bit systems

    -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 on 64-bit systems
    Object 4 bytes Any Object reference
    Single (single-precision floating-point) 4 bytes -3.402823E38 to -1.401298E-45 for negative values

    1.401298E-45 to 3.402823E38 for positive values
    String (variable-length) 10 bytes + string length 0 to approximately 2 billion
    String (fixed-length) Length of string 1 to approximately 65,400
    Variant (with numbers) 16 bytes Any numeric value up to the range of a Double
    Variant (with characters) 22 bytes + string length (24 bytes on 64-bit systems) Same range as for variable-length String
    User-defined (using Type) Number required by elements The range of each element is the same as the range of its data type.

    이 중에서 가장 자주 사용하는 데이터 형식은 Int, Long, String, Boolean 정도이다.

     

    Variant, User-defined 데이터 형식에 대해 아래에 추가로 설명한다.


    Variant 데이터 형식

    Variant 데이터 형식은 여러 데이터 형식을 저장하고 처리할 수 있는 특별한 데이터 형식이다. 변수를 선언할 때 데이터 형식을 생략하면 Variant 데이터 형식으로 지정된다. Variant 데이터 형식에 대한 자세한 내용은 아래 URL을 참고하기 바란다.

    https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/variant-data-type

     

    Variant data type

    Variant data type In this article --> The Variant data type is the data type for all variables that are not explicitly declared as some other type (using statements such as Dim, Private, Public, or Static). The Variant data type has no type-declaration cha

    docs.microsoft.com

     

    실행중에 Variant 변수가 어떤 데이터 형식을 저장하고 있는지 확인하려면 VarType 함수를 이용한다.

    https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/vartype-function

     

    VarType function (Visual Basic for Applications)

    VarType function In this article --> Returns an Integer indicating the subtype of a variable, or the type of an object's default property. Syntax VarType(varname) The required varname argument is a Variant containing any variable except a variable of a use

    docs.microsoft.com

     

    구문

    VarType(varname)

    필수 요소인 varname 인수사용자 정의 형식의 변수를 제외한 변수가 들어 있는 Variant입니다.

    반환 형식

    상수 설명
    vbEmpty 0 Empty(초기화되지 않음)
    vbNull 1 Null(유효한 데이터 없음)
    vbInteger 2 정수
    vbLong 3 긴 정수
    vbSingle 4 단정도 부동 소수점 수
    vbDouble 5 배정도 부동 소수점 수
    vbCurrency 6 통화값
    vbDate 7 날짜값
    vbString 8 문자열
    vbObject 9 개체
    vbError 10 오류값
    vbBoolean 11 Boolean 값
    vbVariant 12 Variant(variant 배열에서만 사용)
    vbDataObject 13 데이터 액세스 개체
    vbDecimal 14 십진값
    vbByte 17 바이트값
    vbArray 8192 배열

     

    나는 개인적으로 Variant 데이터 형식을 잘 사용하지 않고 시트 데이터를 한번에 읽고 쓸때에만 주로 사용한다. Variant arry를 이용하여 많은 양의 시트 데이터를 읽고 쓰는 방법에 대해서는 아래 글을 참고한다.


    VBA 코딩 패턴: Range Loop-읽기(Read)

     

    VBA 코딩 패턴: Range Loop-읽기(Read)

    목차 요약 Range Loop는 엑셀 시트에 입력되어 있는 데이터를 VBA 코드로 읽어서 처리할 때 자주 사용하는 코딩 패턴이다. 시작 cell부터 마지막 cell까지 순차적으로 읽는 기본적인 패턴과, 순차적으

    prodtool.tistory.com

     

    VBA 코딩 패턴: Range Loop-쓰기(Write)

     

    VBA 코딩 패턴: Range Loop-쓰기(Write)

    목차 요약 Variant Array를 이용하여 엑셀 시트에서 많은 데이터를 쓸때 성능을 개선하는 코딩 패턴에 대해 소개한다. 엑셀 시트에서 많은 데이터를 읽을 때 성능을 개선하는 방법은 아래 글에서 이

    prodtool.tistory.com


     

    Variant 데이터 형식을 사용하는 예제 코드이다. 정수, 문자열, 실수, 날짜 데이터 형식을 모두 처리할 수 있는 것을 보여준다.

    Sub VariantTest()
        Dim a As Variant '데이터 형식을 생략하면 Variant 형식임
        a = 1: Debug.Print a
        a = "1": Debug.Print a
        a = 1.1: Debug.Print a
        a = CDate("2021-07-31"): Debug.Print a
    End Sub

     

     

    User-defined(사용자 정의) 데이터 형식

    사용자 정의 자료형을 선언하고 사용할 수 있다. C언어의 'struct'와 비슷한 'Type' keyword로 사용자 정의 자료형을 선언한다. User-defined 데이터 형식은 개체가 아니라서 선언하면 바로 instance가 생성되어 메모리가 할당되고 값을 입력할 수 있다.

     

    User-defined 데이터 형식에 대한 자세한 내용은 아래 URL을 참고하기 바란다.

    https://docs.microsoft.com/en-us/office/vba/language/how-to/user-defined-data-type

     

    User-defined data type (VBA)

     

    docs.microsoft.com

     

     

    User-defined 데이터 형식의 예시 코드는 다음과 같다.

    Type EmployeeRecord    ' 사용자 정의 형식을 만듭니다.
        ID As Integer    ' 데이터 형식의 요소를 정의합니다.
        Name As String
        Address As String
        Phone As Long
        HireDate As Date
    End Type
    
    Sub CreateRecord()
        Dim MyRecord As EmployeeRecord    ' 변수를 선언합니다.
        MyRecord.ID = 12003    ' 요소에 값을 할당합니다.
        MyRecord.Name = "Andy"
        MyRecord.HireDate = CDate("2021-07-31")
    End Sub

     

     

    3.3.2. 자료구조

    자주 사용하는 자료구조는 Array, Collection, Dictionary가 있다. 각각에 대해 살펴보자.

     

    Array

    고정 개수의 Item을 가진다. 개체가 아니라서 선언하면 instance가 생성된다. 선언할 때 차원의 수와 각 차원의 하한, 상한 범위를 지정할 수도 있고, 실행시에 동적으로 배열의 차원, 범위를 변경할 수도 있다. 각 차원의 하한과 상한을 지정하지 않고 item의 개수만 지정할 경우 기본적으로 하한은 0이다. Option Base 1을 사용하면 기본 하한은 1이 된다.

     

    선언 예시 코드

    Dim DayArray(50)
    Dim Matrix(3, 4) As Integer
    Dim MyMatrix(1 To 5, 4 To 9, 3 To 5) As Double

     

    각 차원 하한값/상한값 선언, 확인: LBound, UBound 사용

    Dim A(1 To 100, 0 To 3, -3 To 4) 
    LBound(A, 1) ->  1,  UBound(A, 1) -> 100 ' 1차원 하한/상한
    LBound(A, 2) ->  0,  UBound(A, 2) -> 3   ' 2차원 하한/상한
    LBound(A, 3) -> -3,  UBound(A, 3) -> 4   ' 3차원 하한/상한

     

    차원 크기 변경: Redim 문으로 동적 배열의 차원 크기를 변경한다.

    Dim MyArray() As Integer ' 동적 배열을 선언합니다. 
    Redim MyArray(5) ' 5개의 요소를 할당합니다. 
    Redim Preserve MyArray(15) ' 15개의 요소로 크기를 변경합니다.

     

    Item Loop(For Next)

    'Split & Trim 처리
    Public Function SplitTrim(aExpression As String, aDelimeter As String) As String()
        Dim saOut() As String, i As Integer
        saOut = Split(aExpression, aDelimeter)
        For i = LBound(saOut) To UBound(saOut)
            saOut(i) = Trim(saOut(i))
        Next i
    
        SplitTrim = saOut
    End Function

     

    초기화: Erase 문으로 배열 변수를 초기화한다.

    ' 배열 변수를 선언합니다.
    Dim NumArray(10) As Integer    ' 정수 배열입니다.
    Dim StrVarArray(10) As String    ' 변수 문자열 배열입니다.
    Dim StrFixArray(10) As String * 10    ' 고정 문자열 배열입니다.
    Dim VarArray(10) As Variant    ' Variant 배열입니다.
    Dim DynamicArray() As Integer    ' 동적 배열입니다.
    ReDim DynamicArray(10)    ' 저장 공간을 할당합니다.
    Erase NumArray    ' 0으로 지정된 각 요소입니다.
    Erase StrVarArray    ' 길이가 0인 문자열 ("")로 지정된 각 요소입니다.    
    Erase StrFixArray    ' 0으로 지정된 각 요소입니다.
    Erase VarArray    ' Empty로 지정된 각 요소입니다.
    Erase DynamicArray    ' 배열에 의해 사용되는 빈 메모리입니다.

     

    Collection

    Collection class는 동적 배열(Array)과 유사하다. 가변 갯수의 unique item을 Add, Remove할 수 있다. 개체이기 때문에 "Set" 과 "New"키워드를 이용하여 instance를 생성한다. Visual Basic 언어에서 개체에 reference를 생성하거나 새로운 reference를 할당할 때는 꼭 "Set" keyword를 사용해야 하고, 변수에 값을 할당할 때는 "Set" keyword가 필요없다. 개체를 다룰 때와 변수를 다룰 때를 잘 구분해야 문법 오류가 발생하지 않는다. 자주 실수할 수 있으니 주의가 필요하다.

     

    Collection 개체 선언, instance 생성, Item 추가 등의 작업별 코드는 아래 표를 참고한다.

    Task Sample Code
    선언 Dim oCol As Collection
    Instance 생성 Set oCol = New Collection
    선언과 동시에 Instance 생성 Dim oCol As New Collection
    Item 추가 oCol.Add "Apple"
    IndexItem 접근 oCol(1)
    Item 개수 oCol.Count
    Item Loop (For) Dim l As Long
    For l = 1 to oCol.Count
        Debug.Print oCol(l)
    Next
    Item Loop (For Each) Dim fruit As Variant
    For Each fruit in oCol
        Debug.Print fruit
    Next
    Item 제거 (Index 지정) oCol.Remove(1)
    Instance 제거 Set oCol = Nothing

     

    Collection 을 사용하는 예시 코드는 다음과 같다. 참고로 Collection의 Item은 1부터 시작한다.

    Sub CollectionTest()
        Dim oCol As Collection
        Set oCol = New Collection
        
        oCol.Add "Apple"
        oCol.Add "Strawberry"
        oCol.Add "Lemon"
        oCol.Add "Banana"
        
        Debug.Print oCol(1)
        Debug.Print oCol.Item(1)
        Debug.Print "----------"
    
        Dim l As Long
        For l = 1 To oCol.Count
            Debug.Print oCol(l)
        Next
    
        Debug.Print "----------"
    
        oCol.Remove (1)
    
        Dim fruit As Variant
        For Each fruit In oCol
            Debug.Print fruit
        Next
    
        Set oCol = Nothing
    End Sub
    
    '출력
    Apple
    Apple
    ----------
    Apple
    Strawberry
    Lemon
    Banana
    ----------
    Strawberry
    Lemon
    Banana

     

     

    Dictionary

    Key-Value 구조의 가변 unique Item을 관리할 수 있고, item을 동적으로 Add/Remove 할 수 있다.

    Python 언어의 Dictionary, C++의 HashMap, Java의 HashMap과 유사한 자료구조이다. Key값으로 접근할 때 성능은 O(1) 수준이다.

    Dictionary class는 기본으로 제공되지 않는다. Early binding 방식으로 사용하려면 먼저 “Microsoft Scripting Runtime”을 참조해야 한다. Late binding 방식으로 사용하려면 CreateObject를 통해 instance를 생성하고 사용한다.

    Dictionary class 사용을 위한 "Microsoft Scripting Runtime" 참조 추가

     

     

    Dictionary 개체 선언, instance 생성, Item 추가 등의 작업별 코드는 아래 표를 참고한다.

    Task Sample Code
    선언 (early binding) Dim oDic As Dictionary
    Instance 생성 (early binding) Set oDic = New Dictionary
    선언 (late binding) Dim oDic As Object
    Instance 생성 (late binding) Set oDic = CreateObject("Scripting.Dictionary")
    Item 추가 oDic.Add "Apples", 50
    Value 변경 oDic("Apples") = 60
    Value 얻기 appleCount = oDic("Apples")
    Key가 존재하는지 확인 oDic.Exists("Apples")
    Item 삭제 oDic.Remove("Apples")
    모든 Item 삭제 oDic.RemoveAll
    Item 개수 oDic.Count
    Item Loop (For Each) Dim key As Variant
    For Each key in oDic.Keys
        Debug.Print key, oDic(key)
    Next key
    Item Loop (For, Early binding only) Dim l As Long
    For l = 0 To oDic.Count -1
        Debug.Print oDic.Keys(l), oDic.Items(l)
    Next l

     

    Dictionary를 사용하는 예시 코드는 다음과 같다. 참고로 Dictionary의 Items는 0부터 시작한다.

    Sub DictionaryTest()
        Dim oDic As Dictionary
        Set oDic = New Dictionary
    
        oDic.Add "A", "Apple"
        oDic.Add "S", "Strawberry"
        oDic.Add "L", "Lemon"
        oDic.Add "B", "Banana"
    
        Debug.Print oDic("A")
        Debug.Print oDic.Items(0)
        Debug.Print "----------"
    
        Dim l As Long
        For l = 0 To oDic.Count - 1
            Debug.Print oDic.Items(l)
        Next
        
        Debug.Print "----------"
        
        oDic.Remove ("A")
    
        Dim key As Variant, fruit As String
        For Each key In oDic.Keys
            fruit = oDic(key)
            Debug.Print fruit
        Next
    
        Set oDic = Nothing
    End Sub
    
    '출력
    Apple
    Apple
    ----------
    Apple
    Strawberry
    Lemon
    Banana
    ----------
    Strawberry
    Lemon
    Banana

     

    Dictionary 개체를 For Loop 구문으로 탐색할 때 key값을 담을 변수는 Variant 또는 Object 형식만 가능하다. 위 예시에서 23, 24 행의 코드에서는 Variant 형식을 사용했다.

     


    이번 글에서는 VBA 데이터 형식과 자료구조에 대해 살펴보았다. 특히 Collection과 Dictionary는 자주 사용할 가능성이 매우 높기 때문에, 잘 익혀 두기 바란다. 다음에는 VBA 코딩시 알아두면 좋은 How-To에 대해 살펴보겠다.

     

    댓글

    💲 추천 글