런타임에 Userform 위에 컨트롤 만들기

nØthing spec¡al by Jimsjoo·2024년 7월 20일
0

VBA

목록 보기
10/13

Userform을 만들려는 경우 디자인 단계에서 원하는 컨트롤을 배치하고, 속성과  이벤트 프로시저를 작성한다. 하지만 경우에 따라 Userform이 실행하면서 컨트롤을 만들고 속성과 이벤트 프로시저를 추가할 필요가 있다. 

이번 예에서 Userform에 콤보 컨트롤을 추가하는 예이다. 이번 예에서는 Userform에 ComboBox를 여러 개 만들고, ComboBox에 워크시트에서 읽어온 목록을 추가할 것이다. 그리고 사용자가 ComboBox에서 선택한 항목을 다른 워크시트에 기록하는 이벤트 프로시저를 추가할 것이다.

이번 예를 몇 가지 단계로 나누어 살펴보고자 한다.

1단계는 컨트롤을 재포장하는 클래스모듈을 만드는 것이다. 다음은 클래스 모듈이다.

' CComboBoxes 클래스 모듈
Public WithEvents Combo As MSForms.ComboBox
 
Private Sub Combo_Change()
    Dim r As Long
    
    With Sheet1
        r = .Range("A1048576").End(xlUp).Row + 1
        .Cells(r, 1) = "ComboBox " & Combo.Tag
        .Cells(r, 2) = Combo.Value
    End With
End Sub

combo변수는 ComboBox 타입의 변수이며, Userform 에 생성될 Combox를 대리하는 변수이다. MSForms컬렉션 개체 는 Userform에서 사용할 수 있는 기본 컨트롤은 제공한다. WithEvents 키워드는 이벤트 프로시저를 같이 만들 것임을 알리는 선언이다. 이번에는 ComboBox 관련 이벤트 프로시저중 Change이벤트를 사용한다. Change 이벤트는 사용자가 ComboBox  목록에서 아이템을 선택할 때 작동한다.  사용자가 목록중 아이템을 선택하면 Change이벤트는 Sheet1의 A 컬럼에 선택한 ComboBox 태크와 선택한 아이템 값을 추가한다.

2단계는 Userform의 초기화 과정에서 ComboBox 컨트롤을 생성하고 그 위치와 크기를 정해주는 것이다. 그리고 생성된 컨트롤에 앞서 만든 CComboBoxes 클래스를 연결한다. 다음은 Userform의 코드이다.

' Userform 코드
Dim Combos() As New CComboBoxes

Private Sub UserForm_Initialize()
    Dim arrayList
    Dim cnt As Long, ix As Long, iy As Long
    Dim cmb As MSForms.ComboBox
    
    cnt = 1
    arrayList = Sheet2.Range(Sheet2.Range("A2"), Sheet2.Range("A2").End(xlDown)).Value2
    
    For iy = 1 To 4
        Me.Height = 40 + (iy * 23)
        For ix = 1 To 4
            Me.Width = 20 + (ix * 60)
            Set cmb = Me.Controls.Add("Forms.ComboBox.1")
            With cmb
                .Left = 10 + ((ix - 1) * 60)
                .Height = 18
                .Width = 50
                .Top = 10 + ((iy - 1) * 23)
                .List = arrayList
                .Tag = cnt
            End With
            ReDim Preserve Combos(1 To cnt)
            Set Combos(cnt).Combo = cmb
            cnt = cnt + 1
        Next
    Next
End Sub

Dim Combos() As New CComboBoxes

Combos는 1단계에서 만든 클래스 CComboBoxes 변수로서 앞으로 만들어질 ComboBox 를 담기 위한 배열이다.

Private Sub UserForm_Initialize()

UserForm_Initialize 프로시저는 Userform이 생성되면서 자동으로 실행되는 이벤트 프로시저로서 Userform이 작동하기 위한 기초작업을 수행한다.

Dim arrayList

ComboBox에 담을 목록을 저장하기 위한 변수이다.

Dim cnt As Long, ix As Long, iy As Long

cnt는 Combos 배열에 ComboBox를 담기 위해 배열의 크기를 동적으로 늘려주기 위해 생성한 ComboBox 갯수를 세기 위한 변수다. ix와 iy는 16개의 ComboBox를 만들면서 ComboBox를 4x4 형태의 레이아웃을 잡기 위한 변수다.

Dim cmb As MSForms.ComboBox

cmb는 새로 생성되는 ComboBox를 가리키는 변수다

arrayList = Sheet2.Range(Sheet2.Range("A2"), Sheet2.Range("A2").End(xlDown)).Value2

Sheet2의  A컬럼의 값을 arrayList변수에 저장한다.

다음은 두 개의 For루프를 사용하여 ComboBox 컨트롤을 Userform에 추가하고 위치(Left, Top)와 크기(Width,Height), 태그값(Tag)을 정해준다.  그리고 앞서 읽어들인 arrayList를 List에 추가한다. 이후 Combos 배열의 크기를 늘려주고 ComboBox 를 추가한다.

For iy = 1 To 4
    Me.Height = 40 + (iy * 23)
    For ix = 1 To 4
        Me.Width = 20 + (ix * 60)
        Set cmb = Me.Controls.Add("Forms.ComboBox.1")
        With cmb
            .Left = 10 + ((ix - 1) * 60)
            .Height = 18
            .Width = 50
            .Top = 10 + ((iy - 1) * 23)
            .List = arrayList
            .Tag = cnt
        End With
        ReDim Preserve Combos(1 To cnt)
        Set Combos(cnt).Combo = cmb
        cnt = cnt + 1
    Next
Next
profile
harmonized or torn between programming and finance

0개의 댓글