PROGRAMMING WORKSHOP

프로젝트기성관리 |

이번 페이지에서는
UserForm의 각각의 콘트롤을 실행되면서 자동으로 만드는 과정을



빼버리고 디자인 타임에 콘트롤을 그려 넣는 것으로 바꾸도록 하자
이유는 자동으로 컨트롤을 작성하는 부분을 어려워 하니까..
좀 쉽게 가기 위한 작업이다
이전에 만들었던 폼은 그대로 놓아두고(참고로 보시고)
새로 하나 UserForm을 만들어 넣도록 하자
하나, 하나 만들어가면서 UserForm을 자주 사용하도록 하자

TabStrip콘트롤을 하나 그리고, 기본적으로 Tab페이지가 두개
생기는 것에 마우스로 탭페이지를 선택하여 탭추가 하여 세개로
준비하고..
목록상자는 두개를 그려 넣고
버튼도 두개를 그려 넣는다



UserForm은 여러분의 만드는 소루션의 얼굴과 같은 것이라서
일관성을 유지하고 만들어야 보기가 좋다
그러려면 각 콘트롤마다 속성을 똑같이 적용하여야 하는
일이 많아 진다
그것은 UserForm이 초기화될때 프로그래밍적으로 알아서 하게
하는 것이 현명한 방법이다
마우스로 그리는 것은 위치와 크기만 정확히 잡아주고..


'탭의 캡션이라던가, 버튼의 캡션등을 상수로 선언해 두는 것이
'나중에 수정을 하더라고 편리하다
'모든 문자열정보 자원은 이렇게 상수화시켜놓는 것이 좋은 습관이다
Const TAB_PAGE_1_CAPTION As String = "기성물량편집"
Const TAB_PAGE_2_CAPTION As String = "서식편집"
Const TAB_PAGE_3_CAPTION As String = "기성문서편집"
Const BTN_ADD_REPORT_CAPTION As String = "기성추가"
Const BTN_VIEW_ALL_REPORT_CAPTION As String = "전체보기"


'폼이 초기화(Initialize 이벤트)될때 폼의 컨트롤등의
'서식과 속성을 주는 작업을 하도록 한다
'이벤트프로시져에 작성하는 것 보다는 별도의 프로시져를 만들고
'이벤트프로시져에서는 호출하는 것이 좋은 포멧이다
Private Sub UserForm_Initialize()
setForm
End Sub

'아래프로시져에서 콘트롤의 폰트나 캡션을 주는 작업을 한다
Sub setForm()
On Error Resume Next
Me.StartUpPosition = 0

Me.Caption = modMain.PROJ_NAME
Me.Left = 0
Me.Top = 0
Dim oCtl As Control
For Each oCtl In Me.Controls
    oCtl.Font.Name = "맑은 고딕"
    oCtl.Font.Size = 9
Next
Me.TabStrip1.Tabs(0).Caption = TAB_PAGE_1_CAPTION
Me.TabStrip1.Tabs(1).Caption = TAB_PAGE_2_CAPTION
Me.TabStrip1.Tabs(2).Caption = TAB_PAGE_2_CAPTION
Me.cmdAddReport.Caption = BTN_ADD_REPORT_CAPTION
Me.cmdViewAllReport.Caption = BTN_VIEW_ALL_REPORT_CAPTION
Me.TabStrip1.Value = 0

End Sub

아차차...위에서 TabStrip이 아니고 MultiPage컨트롤로 하시는 것이 좋겠다
모양이 그림과 같이 비슷하지만 기능이 다르다
TabStrip은 코딩을 많이 해야 하고 MultiPage가 간편하다



이전 폼을 띄우는 것을 주석처리하고 새폼으로 띄우도록 한다
크래스모듈등에 분산된 것을 폼에 모두 처리하니까, 코드보시면서
학습하시기가 편할 것이다

Sub loadForm()
'frmProjectManager.Show
frmProjectManager_New.Show
End Sub

코드를 옮겨서 좀 편집하시는 것도 학습에 도움이 되실 것이다
소루션을 만들다 보면 이렇게 인터페이스를 바꾸기도 하게 되고
그러다 보면, 왜 코드를 함수나 프로시져로 토막을 내어서 관리하는 것이
편리한 것도 실감하게 되는 것이다

Option Explicit
Const TAB_PAGE_1_CAPTION As String = "기성물량편집"
Const TAB_PAGE_2_CAPTION As String = "서식편집"
Const TAB_PAGE_3_CAPTION As String = "기성문서편집"
Const BTN_ADD_REPORT_CAPTION As String = "기성추가"
Const BTN_VIEW_ALL_REPORT_CAPTION As String = "전체보기"


버튼을 크릭할때 호출되는 프로시져는 당초에 modMain에 사용하던것을
그대로 호출하면 될 것이다
Private Sub cmdAddReport_Click()
modMain.buttonClick cmdAddReport
End Sub
Private Sub cmdViewAllReport_Click()
modMain.buttonClick cmdViewAllReport
End Sub

Private Sub lstItems_Change()
oListBox_Change
End Sub

Private Sub lstReports_Change()
oListBox_Change
End Sub

Multipage의 Change이벤트의 내용은 당초 크래스모듈에 있던
내용을 그대로 복사하여 옮기고..
Private Sub MultiPage1_Change()
On Error Resume Next
Dim oSht As Worksheet
Select Case MultiPage1.Value ' oMultiPage.Value
    Case 1, 2
        Set oSht = Worksheets(modMain.BASIC_DATA_SHT)
        Application.Goto oSht.Range("A1")
        If MultiPage1.Value = 1 Then ' oMultiPage.Value = 1 Then
            oSht.Range(modMain.HIDE_1).EntireColumn.Hidden = True
        End If
        ActiveWindow.SplitRow = 2
        ActiveWindow.FreezePanes = True
        modMain.getWBSColumn.Select
    Case 0
        Set oSht = Worksheets(modMain.MAIN_SHT)
        Application.Goto oSht.Range("A1")
End Select
End Sub

UserForm의 초기화에는 목록상자 채우는 프로시져도
크래스모듈의 것을 갖여다 사용하도록 하고...

Private Sub UserForm_Initialize()
On Error Resume Next
setForm
fillListBox Me.lstItems
fillListBox_completion_nums Me.lstReports
Worksheets(modMain.BASIC_DATA_SHT).Activate
End Sub

Userform의 초기화때 호출되는 콘트롤의 초기화, 캡션속성등
Sub setForm()
On Error Resume Next
Me.StartUpPosition = 0
Me.Caption = modMain.PROJ_NAME
Me.Left = 0
Me.Top = 0
Dim oCtl As Control
For Each oCtl In Me.Controls
    oCtl.Font.Name = "맑은 고딕"
    oCtl.Font.Size = 9
Next
Me.MultiPage1.Pages(0).Caption = TAB_PAGE_1_CAPTION
Me.MultiPage1.Pages(1).Caption = TAB_PAGE_2_CAPTION
Me.MultiPage1.Pages(2).Caption = TAB_PAGE_3_CAPTION

Me.cmdAddReport.Caption = BTN_ADD_REPORT_CAPTION
Me.cmdViewAllReport.Caption = BTN_VIEW_ALL_REPORT_CAPTION
Me.MultiPage1.Value = 0
End Sub

Private Sub fillListBox(oList As MSForms.ListBox)
On Error Resume Next
Dim oSht As Worksheet, rList As Range
Dim rX As Range
Dim iRow As Integer
Set oSht = Worksheets(modMain.BASIC_DATA_SHT)
Set rList = oSht.Rows(modMain.BASIC_DATA_FLD_ROW).Cells(1).Offset(1)
Set rList = oSht.Range(rList, oSht.Range("A10000").End(xlUp)).Resize(, 5)
oList.ColumnCount = 3
oList.ColumnWidths = "50;120;80"
For Each rX In rList.Rows
    If rX.Cells(1) <> "" Then
        oList.AddItem rX.Cells(1).Value
        oList.List(iRow, 1) = rX.Cells(2).Value
        oList.List(iRow, 2) = rX.Cells(5).Value
        iRow = iRow + 1
    End If
Next
End Sub
Private Sub fillListBox_completion_nums(oList As MSForms.ListBox)
Dim oCol As Collection, varX As Variant
Set oCol = modMain.getCompletionNumbers
If oCol.Count = 0 Then
Else
    For Each varX In oCol
        oList.AddItem varX
    Next
End If
End Sub


목록상자의 Change이벤트 발생시 호출되는 프로시져를 크래스모듈에서
그대로 갖여 오고...
Private Sub oListBox_Change()
On Error Resume Next
Dim oSht As Worksheet
Dim rCol As Range
Dim rCurrentWBS As Range
Dim sComBoxValue As String
Dim sWBSValue As String
Dim rWorkListRow As Range
Dim rComColumns As Range
Dim rUnion As Range
Dim oLstWorkList As MSForms.ListBox
Dim oLstCom As MSForms.ListBox

아래와 같이 약간의 편집수정이 필요할 것이고..
'Set oLstWorkList = frmProjectManager.Controls(modMain.TASK_LIST_BOX_NAME)
'Set oLstCom = frmProjectManager.Controls(modMain.TASK_COMPLE_BOX_NAME)
Set oLstWorkList = Me.Controls(modMain.TASK_LIST_BOX_NAME)
Set oLstCom = Me.Controls(modMain.TASK_COMPLE_BOX_NAME)
On Error Resume Next
Application.ScreenUpdating = False
Set oSht = Worksheets(modMain.BASIC_DATA_SHT)
Set rCol = oSht.UsedRange.Columns(1)
Set rCurrentWBS = rCol.Find(oLstWorkList.List(oLstWorkList.ListIndex, 0), , , xlWhole)
Set rWorkListRow = rCurrentWBS.EntireRow
Dim sLabel As String
sLabel = oLstCom.Text
If sLabel <> "" Then
    If Not isThisItemExist(sLabel) Then
        MsgBox modMain.MSG_NO_PARTIAL_COM_RANGE, , modMain.PROJ_NAME
        GoTo X
    End If
    modMain.showOnlyCurrentTableAndSummaryOfMain sLabel
End If
If Not rWorkListRow Is Nothing Then
    If Not rComColumns Is Nothing Then
        Set rUnion = Union(rWorkListRow, rComColumns)
    Else
        Set rUnion = rWorkListRow
    End If
Else
    If Not rComColumns Is Nothing Then
        Set rUnion = rComColumns
    Else
        Set rUnion = Nothing
    End If
End If

If rUnion Is Nothing Then
    oSht.Cells(1).Select
ElseIf rUnion.Areas.Count = 2 Then
    rUnion.Select
    If UBound(Split(rWorkListRow.Cells(1), ".")) = modMain.WBS_MAX - 1 Then
        Intersect(rWorkListRow, rComColumns.Columns(2)).Activate
    End If
Else
    rUnion.Select
End If

X:
ActiveWindow.ScrollRow = rCurrentWBS.Row - 5
Application.ScreenUpdating = True
End Sub

위와 같이 하면 UserForm의 콘트를을 실행시키면서 만들고 크래스모듈을
활용하던 것을 UserForm하나로 처리하도록 하게 되겠다
위와 같이 한번 스스로 편집해 보신후 나중에 화일을 보시면 좀더 학습에
효과를 얻으실것 같다

새폼을 하나 새로 만들어서 해보았더니
기성추가 폼에서 기성추가후 닫아도 기성양식이 만들어지지 않고
메인폼을 닫아야 양식이 만들어지는데...???라는 질문이 있다
아차차..아래의 중요한 점을 설명안드렸다



메인윈도우창의 속성중 ShowModal=False로 해주어야 한다

***[LOG-IN]***