PROGRAMMING WORKSHOP

자재관리 | 기능이 많아졌다..콘트롤파넬을 하나 만들자

STEP_12 ---------------------------------

기능이 많아졌다
DB에 대하여 다음 페이지에서 더 추가하도록 하고
이시트, 저시트 왔다,갔다 하려면 헷갈린다
당초의 목록시트는 좀 깝깝하고 유치해 진다
콘트롤 패널이 하나 있어야겠다
기능간의 이동, 기능별 명령등을 한곳에 보기 좋게 모아 놓아야 한다
메뉴를 사용해도 되겠지만...
UserForm을 활용해 보도록 하자



그림과 같이 자동으로 UserForm이 만들어진다
어떻게 만들어져야 하냐면..
자재목록시트가 추가 될때마다 UserForm의 버튼을 일일이
그려서 만들어야 한다면 프로그래밍이 아니다..
그냥 워크시트의 내용을 읽어서 스스로 알아서 만들게 하여야
엑셀프로그래머라고 할 수 있다
그러면 마음 놓고 사용자가 자재목록시트를 추가할 수 있다
시트를 이동할때마다, 시트가 추가되거나 삭제되거나
상관없이 버튼이 추가되고, 삭제되게 한다면 훌륭한
엑셀 프로그래머라고 할 수 있다
어느 시트로 이동을 하더라고 UserForm이 관제탑같이
상단에 떠있으면 쉽게 이동하고 쉽게 작업을 할수 있는 도구가 되는 것이다
메뉴보다 편리하다

아래의 화일에서 만들어진 버튼을 크릭하면
아무런 실행이 일어나지 않는다..
왜그럴까..
버튼을 생성하면서 버튼을 크릭할때 발생하는 이벤트프로시져를
어디에 작성해야 할 지 깝깝해진다
VBA가 아닌 VB에서 버튼을 생성할때는
AddHandler 버튼.Click, AddressOf 프로시져명
으로 처리하는 방법이 있는데 VBA의 UserForm의 개체에서는
그런 기능이 없다
VB에서 AddHandler외의 방법으로는
WithEvents 로 선언을 하면 크래스모듈에 버튼의 이벤트를
사용할수 있는 프로시져들이 나타나지만..
UserForm에는 없다
그럼 어쩌란 말인가..
버튼만 만들면 뭐하나..지능을 심어주지 못하여 허당이다
그런 문제의식을 갖고 그냥 버튼만 만드는 모듈을 보시고
이전화일에서 유사한 문제를 풀었던 것이 기억이 나면
당연히 풀수 있지만..
아무튼 다음 화일에서 멍청이 버튼을 똑똑하게 해주도록 하자

***[LOG-IN]***

STEP_13 ---------------------------------

크래스모듈을 꼭 사용하여야 하는 경우가 이런 버튼을
만들었을때 편리하게 사용할수 있도록 할 때 이다
꼭 필요하게 되는 것이다
위의 Step에서 어떻게 하면 풀수 있을까 생각을 많이 하였다면
크래스모듈에 대한 감각은 그 만큼 커질수 있는 기회가 된다

아래의 그림과 같이



뭔가 복잡해 보이지만 알고 나면 참으로 유용하고 편리한 것이니..
꼭 이 스텝화일에서 소화를 잘 시키셨으면 좋겠다
크래스모듈을 하나 삽입한다
크래스모듈내에는 위의 그림의 파랑색 구문만 달랑 입력하면 된다
UserForm모듈의 외부변수에 위의 크래스에서 사용자정의개체를 생성하여
담아 놓는 전역 집합체 변수를 하나 준비해둔다
이곳에 생성되는 모든 버튼이 담기게 된다
워크시트를 순환하면서 워크시트의 이름을 캡션으로하는 버튼을 생성한다
동시에 위의 크래스모듈에서 사용자정의 개체를 만든다
사용자정의개체속에 선언되어있는 버튼개체에 접근하여
방금 생성한 버튼을 담는다(Assign)
그리고 사용자정의개체를 집합체 변수하 하나,하나 담아 놓는다
그럼 끝이다..
크래스모듈내에 있는 버튼의 크릭이벤트프로시져 하나로
버튼을 100개를 만들던, 1000개를 만들던 이 하나의 프로시져를
활용할수 있게 되는 것이다

이렇게 되면 목록시트에 자재시트목록의 하이퍼링크같은 것은 필요없게 된다
프로그래밍은 어떤 수단과 방법을 강구하던..
사용자가 직관적으로(Intuitive Way)이해하고 활용할수 있게 만들어야
사용자로 부터 사랑을 받는다
그런 직관적인 방법중의 하나가 이런 UserForm을 사용하는 것일 것이다
다음 스텝에서 좀더 개선하도록 하자..
문제는 자채시트가 많아질수록 버튼의 갯수가 늘어나야 한다는 것은
또한 문제다...콤보상자 같은 것을 활용하는 것이 좋은 방법일 것이다
일반작업을 위한 것은 버튼으로 하고
자재시트는 몇개가 박힐지 모르니..콤보상자로 하는 것을 해보자

***[LOG-IN]***

STEP_14 ---------------------------------

UserForm을 띄운후 대개의 경우 워크시트의 편집작업을 할수 없다
위의 UserForm과 같이 폼을 항상띄워놓고 시트작업을 하려면
아래의 그림과 같이 ShowModal=False로 하여 놓으면 된다
그럼 자유롭게 폼을 구석에 띄워놓고 다른 작업을 할 수 있게 되는 것



이제 UserForm을 좀더 적극적으로 활용하여 소루션화일을
좀더 정리된 분위기로 만들어 보도록 하자

우선 소루션화일내의 Log_Sheet는 DB의 청구서의 내용과 중복된다
Log_sheet를 없애도 되는 것이다
DB만 잘 보관하고 있으면 되는 것
그리고 DB의 내용을 UserForm상의 목록으로 모니터링을 항상
실시간으로 하게 하면 된다
UserForm의 설계를 아래와 같이 바꾼다



버튼을 여러개 만들 필요가 없으니 크래스모듈도 없애 버리자..
크래스모듈을 껄끄러워하시는 분들을 위하여..
자재청구명을 더블크릭하면서 [청구편집시트]에 집계가 되지만..
현재 어떤 자재를 추가하였는지 일일이 [청구편집시트]로 가서
보아야 하는 것은 거추장스럽다
항상 떠있게 한 UserForm의 목록상자에 [청구편집시트]의 내용이
항상 동기화시켜 놓는다면 그런 번거로운 일이 없을 것이다
다른 분류의 자재시트로 이동하려면 그냥
자재시트별목록 콤보상자에서 선택하면 이동된다
UserForm상의 목록상자는 편집용이 아니고 모니터링용인 것이다
그리고 모두 집계가 되면 [청구편집시트]로 이동하여 수량과 기타
사항입력후 청구서를 작성완료하면 될 것이다

또한 소루션내용이 복잡해 지면서 화일을 열때
사용자에게 일관성있는 모양을 유지하게 하는 것이 좋다
청구목록을 편집하다가 닫았다가
몇일있다가 화일을 열때 지난번에 작업하던 것이 지저분하게
나타나면 별로 좋지 않다
열릴때 화일의 상태를 어떤 형태로던 일정한 모양을 유지하는
것이 좋다
WorkBook_Open프로시져에

On Error Resume Next
Application.DisplayAlerts = False
Worksheets(modMain.SHT_TEMP_EDIT).Delete
Application.DisplayAlerts = True
clearItemsSheets
Application.Goto Worksheets(modMain.SHT_LIST).Range("A1")

임시 편집시트는 아예 삭제해 버리고
각 자재목록시트의 색상을 깨끗하게 지워주고
항상 목록시트가 열리게 하자

테이블의 범위를 목록상자에 채울때는
일일이 순환하면서 매번 처리하면 효율이 떨어진다
그냥 청구내용이 추가될때마다(시트더블크릭할때마다)
임시편집시트의 목록범위를 다시 갱신하도록 아래 프로시져를 호출한다

Sub fillEditItemListToListBox()
On Error Resume Next
Dim varDatas As Variant
varDatas = Worksheets(modMain.SHT_TEMP_EDIT).Range("A1").CurrentRegion
Me.ListBoxOrderEdit.List = varDatas
Me.ListBoxOrderEdit.ListIndex = Me.ListBoxOrderEdit.ListCount - 1
End Sub

해당목록범위를 찾아서
이것을 Variant타입변수에 담아서
폼의 목록상자의 List속성에 직접 전달하면 간단하게 처리된다
그리고 목록의 선택은 최근추가목록을 선택하게 하고

STEP_13보다 훨씬 코드는 간략하지만 기능은 업그레이드 되었을 것이다

***[LOG-IN]***