PROGRAMMING WORKSHOP

자재관리 | 도구상자에 사용자 옵션추가

자재청구서 도구에서 분류명대신에 제품코드번호가 나오게
쉽게 바꿀수는 없냐는 요청이 있었다
그런 질문이 자꾸 들어와야 계속 업그레이드를 할텐데..
진도들을 못나가서 그런 질문까지는 하지 않고 있는데
다행이다
관심을 갖고 본다면 당연히 나오는 질문이고 요구사항이 된다
특정현장에서는 분류명을 사용하기도 하고 또 다른 현장에서는
제품코드명을 사용하고 싶기도 할 것이다



소루션은 최대한 그런 요구사항을 많이 받아들일수 있는
상태가 될때 좋은 소루션이 된다

이것은 이 페이지의 연속으로 보시면 좋겠다
도구상자의 옵션컨트롤은 이런곳에 쓰라고 있는 것이다
아래의 그림과 같이 탭페이지를 하나더 추가하고



옵션버튼을 두개 추가하여 하나는 분류명, 다른 하나는 제품코드명으로
하고 폼이 로딩될때는 분류명을 디폴트로 선택상태가 되게 하여
별도의 지정이 없는 한 기존대로 분류명이 나타나게 하고
제품코드옵션을 선택하면 제품코드명을 읽어들이면 된다
그렇게 추가적 기능을 삽입해 보자

컨트롤을 만들면 항상 콘트롤의 값을 담을 변수를 준비하는 습관이 좋다
modMain시트에 변수를

Public bCategory As Boolean

으로 하고 UserForm의 두개의 옵션컨트롤(optCategory, optCode)의
값이 바뀔때 위의 변수는 항상 값이 바뀌게 되도록 연결하고

Private Sub optCategory_Change()
categoryOrCode
End Sub
Private Sub optCode_Change()
categoryOrCode
End Sub

' 만약 이미 다른 휠드명으로 편집중에 옵션버튼을 바꾸면
' 안되게 한다
' 옵션버튼을 바꾸는 유효한 시점은 편집시트에서 청구서로 옮기고
' 한번의 청구서작업이 일단락된 시점
' 혹은 최초작업이 시작될때..그것을 콘트롤하기도 하고
' bCategory변수값을 갱신하기 위한 프로시져, 위의 두개의 옵션버튼에서 호출한다

Sub categoryOrCode()
bCategory = optCategory.Value
If Not oMain.EditSheet Is Nothing Then
    If bCategory And oMain.EditSheet.Range("B1") = "자재코드" Or _
        Not bCategory And oMain.EditSheet.Range("B1") = "분류명" Then
        MsgBox "이미 편집중이라서 적용휠드를 수정할수 없습니다" & vbNewLine & _
            "처음새로 시작할때 변경하세요"
            If bCategory Then
                Me.optCode.Value = True
            Else
                Me.optCategory.Value = True
            End If
        Exit Sub
    End If
End If
End Sub

옵션버튼의 값을 바꿀때마다 변수는 True가 되었다, False가 되었다 한다
UserForm의 로딩할때 optCategory값을 True로 초기화하고
이것은 곧 bCategory변수의 값이 True로 초기화됨을 의미한다
그런데 폼이 로딩되는 시점은 최초 청구서작성을 시작할때와
혹은 청구서작성중 폼을 닫았다가 다시 여는 경우가 있을 것이다
이때 폼을 초기화할때, 두개의 옵션버튼을 현재작성중의 내용에 마추어
초기화해주어야 할 것이다
폼초기화부분에 몇줄 더 추가하자

Private Sub UserForm_Initialize()
oMain.fillItemShtListCombo Me.ComboBoxItemShts
oMain.fillEditItemListToListBox Me.ListBoxOrderEdit
oMain.fillRequestFileList Me.ListBoxRequestFileList
Me.Caption = oMain.ProjName
oMain.fillRequestHistoryList Me.ListBoxOrderHistory
Me.MultiPage1.Value = 1
Me.MultiPage1.Value = 0
checkCategoryOrCode ' 분류명|코드명확인초기화
Me.MultiPage1.Value = 3
Me.Height = modMain.FRM_SML_H
modMain.bLoaded = True
End Sub

Sub checkCategoryOrCode()
If Not modMain.oMain Is Nothing ThenoMain개체가 이미 활성화되어 있다면
    If oMain.EditSheet Is Nothing Then그리고 편집시트(EditSheet)가 이미 있다면
        GoTo X
    Else
        If oMain.EditSheet.Range("B1") = "분류명" Then편집테이블의 휠드명을 확인하여
            GoTo X
        Else
            Me.optCode.Value = True
        End If
    End If
Else
X:
    Me.optCategory.Value = True
End If
End Sub

버튼 두개이지만 각종이벤트가 발생할때 영향을 받는지 않는지를
잘 관찰하여 조치를 취해주어야 할 것이다
이제 bCategory 변수를 읽어서 실제 작업하는 부분을 보면..
중요한 작업위치는 워크시트의 청구하고자 하는 제품의 행을 더블크릭하면
편집테이블로 값이 옮겨질때의 내용이다

Sub AddOrderItemsToList(sh As Worksheet, Target As Range)
    Const CATEGORY_COL As Integer = 5
    Const CATEGORY_COL_ As Integer = 2
    Const ITEM_COL As Integer = 8
    Const ITEM_CODE_COL As Integer = 7자재코드로 입력할때 시트상의 열위치 상수추가
    Const ITEM_COL_ As Integer = 3
    Const SIZE_COL As Integer = 9
    Const SIZE_COL_ As Integer = 4
    Const UNIT_COL As Integer = 10
    Const UNIT_COL_ As Integer = 5
    
    Dim oTemp As Collection
    
    If Val(sh.Name) > 0 Then
        Dim shtTempEdit As Worksheet
        
        If Me.EditSheet Is Nothing Then
            Dim rBtn As Range
            Set shtTempEdit = getSheet(modMain.EDIT_SHT_NAME, True)
            With shtTempEdit
                Set rBtn = .Range(modMain.LOG_SHT_BTN_CELL)
                If modMain.bCategory Then
                .Range("A1").Resize(, 7).Value = Array("NO", "분류명", "자재명", "규격", "단위", "수량", "비 고 / 메이커")
                Else
                 .Range("A1").Resize(, 7).Value = Array("NO", "자재코드", "자재명", "규격", "단위", "수량", "비 고 / 메이커")
                End If편집테이블을 새로만들때
                .Cells.Font.Name = "맑은 고딕"
                .Cells.Font.Size = 10
                With .Buttons.Add(rBtn.Left, _
                rBtn.Top, rBtn.Width * 3, rBtn.Height)
                    .Caption = "자재청구서로 옮기기"
                    .Font.Size = 9
                    .Font.Name = "맑은 고딕"
                    .OnAction = "writeToRequest"
                End With
            End With
            sh.Activate
            ClearItemsSheets
        End If
        
        Dim rOrig As Range
        Set rOrig = Target.EntireRow
        With EditSheet.Range("A5000").End(xlUp).Offset(1).EntireRow
            If rOrig.Interior.ColorIndex = modMain.BACK_COLOR_GRAY Then
            Else
                If modMain.bCategory Then
                    .Cells(CATEGORY_COL_) = rOrig.Worksheet.Name
                Else
                    .Cells(CATEGORY_COL_) = rOrig.Cells(ITEM_CODE_COL)
                End If값넣을때 방식이 다르겠지..
                .Cells(ITEM_COL_) = rOrig.Cells(ITEM_COL)
                .Cells(SIZE_COL_) = rOrig.Cells(SIZE_COL)
                .Cells(UNIT_COL_) = rOrig.Cells(UNIT_COL)
                .Cells(1) = Application.Max(.Cells(1).EntireColumn) + 1
				....
				....
				....
End Sub
위의 코드에서 이 부분은..
If modMain.bCategory Then
	.Range("A1").Resize(, 7).Value = Array("NO", "분류명", "자재명", "규격", "단위", "수량", "비 고 / 메이커")
Else
	.Range("A1").Resize(, 7).Value = Array("NO", "자재코드", "자재명", "규격", "단위", "수량", "비 고 / 메이커")
End If
아래와 같이 IIF함수를 활용하여 한줄로 처리하는 것이 좀효율적일 것이다 
.Range("A1").Resize(, 7).Value = Array("NO", IIf(bCategory, "분류명", "자재코드"),"자재명", "규격", "단위", "수량", "비 고 / 메이커")

이제 청구서로 옮길때 청구서상의 열머리내용을 바꿔주어야 할 것이다



청구서로 편집내용을 옮기는 프로시져에서 아래의 한줄만 수정한다

oNewOrderSheet.Range(modMain.REQUEST_LIST_START_CELL).Offset(-1, 1) = IIf(modMain.bCategory, "분류명", "자재코드")

이렇게 bCategory라는 변수하나만 잘 관리하면 되는 셈이다
그러니 프로그래밍의 생명은 변수를 여하히 잘 관리하냐는 문제인 셈이다
데이타베이스에 저장하는 과정은 다음 화일에서 하도록 하자

아래 화일을 실행해 보시고 생각지도 않은 경우의 수도 있을수 있으니 잘 발견해 보시기를..

***[LOG-IN]***