rand(life)

[vba] 사용자정의폼(목록 상자) 만들기 본문

컴퓨터/엑셀

[vba] 사용자정의폼(목록 상자) 만들기

flogsta 2017. 3. 20. 13:05

어쩌다보니 이런 것도 하게 되었다.


사용자정의폼을 만들어서, 각 시트에 있는 특정 정보를 한 시트에 모으는 방법이다. 

목록상자가 복수의 항목을 선택할 수 있게 하였다.


제일 어려운 부분은 목록상자에 .Rowsource로 목록을 집어넣는 것인데,

가볍게 "A1:A10"하면 간단하지만

앞으로 목록이 추가될 경우에도 자동으로 목록이 갱신되도록 하다보니 어려워졌다. 

결국 구글신의 도움을 받아 해결


Private Sub UserForm_Initialize()

With ListBox1

.ColumnCount = 1

.ColumnHeads = False

.ColumnWidths = "10"

.AddItem "수입"

.AddItem "지출"

End With

Sheet1.Range("M3:p18").ClearContents

End Sub


요건 처음에 폼이 로딩될 때 기본값 지정


Private Sub ListBox1_Click()

Dim wsht As Worksheet

Dim src1 As Range

Dim src2 As Range

Dim LastAddressA As String

Dim LastAddressB As String


LastAddressA = Worksheets("항목").Cells(Rows.Count, 1).End(xlUp).Address

LastAddressB = Worksheets("항목").Cells(Rows.Count, 2).End(xlUp).Address

                          ' 이 부분이 핵심이다. 데이타가 있는 마지막 행의 주소를 받아두고 

With Me.ListBox2

        .ColumnCount = 1

        .ColumnWidths = "100"

        .ColumnHeads = False

        .MultiSelect = fmMultiSelectMulti

        .ListStyle = fmListStyleOption

        Select Case Me.ListBox1.ListIndex

        Case 0

            .RowSource = "항목!A2:" & LastAddressA       '이렇게 합치기하면 된다

        Case 1

            .RowSource = "항목!B2:" & LastAddressB

        End Select

        .ListIndex = 0

    End With

End Sub

 요건 목록상자에서 제1항목을 선택하면 제2항목이 뜨는 동작



Private Sub CommandButton1_Click()

Dim strInput As String

Dim sht As Worksheet

Dim rngkind As Range

Dim rng As Range

Dim rng내용 As Range

Dim rng날짜 As Range

Dim rng금액 As Range

Dim rng비고 As Range

Dim k As Integer

Dim i As Integer


Set rng내용 = Sheet1.Range("M2") '내용

Set rng날짜 = Sheet1.Range("N2") '날짜

Set rng금액 = Sheet1.Range("O2") '금액

Set rng비고 = Sheet1.Range("P2") '비고


With ListBox2

k = 1

For i = 0 To .ListCount - 1


If .Selected(i) = True Then

  strInput = .List(i)


    For Each sht In Worksheets

     If sht.Name <> "항목" And sht.Name <> "Sheet1" Then   

        Set rngkind = sht.Range(sht.Cells(2, 2), sht.Cells(Rows.Count, "b").End(3)(2 - 7))      

      For Each rng In rngkind

        If rng.Value2 = strInput Then

           rng내용.Offset(k, 0).Value2 = rng.Value2

           rng날짜.Offset(k, 0).Value2 = sht.Name

           rng금액.Offset(k, 0).Value2 = rng.Offset(0, 1).Value2

           rng비고.Offset(k, 0).Value2 = rng.Offset(0, 3).Value2

           k = k + 1        

        End If

      Next rng

     End If      

   Next sht

End If

Next i

End With

End Sub


요건 '실행' 버튼을 누르면 각 항목에 해당하는 값을 모든 시트에서 찾아준다


Private Sub CommandButton2_Click()

Unload UserForm1

End Sub


닫기 기능까지 설정하면 완벽하다!


=-========== ListBox 관련 추가 팁=============

목록 상자를 열면 기본값이 D3셀의 값으로 지정되어있는 상태가 되도록 하는 방법

Private Sub UserForm_Initialize()

    Dim d As Variant
    For Each d In Range("데이터")
        If d.Value = [d3].Value Then ListBox1.Value = d.Value
    Next
End Sub



아니면 다음과 같이 간단하게...

Private Sub UserForm_Initialize()
    ListBox1.Value = [d3].Value
End Sub


나는 이렇게 했다

Private Sub UserForm_Initialize()

Dim i As Integer, r As Range, rng As Range


Set rng = Range("b3:b12")


For Each r In rng

If r.Value = Range("d3").Value Then

i = r.Row - 3

Me.ListBox1.Selected(i) = True

End If

Next r

End Sub


역시 고수는 간결하다!
[ ] 로 넣으니까 셀주소를 간단히 지정할 수 있구나.......