PROGRAMMING WORKSHOP

화일관리도구 |

이런 저런 일에 몰려서 뜸했습니다..계속 그럴 것 같지만,
짬을 내어서 다시 계속 하도록 합니다
아래의 그림과 같이 항목삭제하는 부분을 다음회에 한다고 하고, 미적거렸다



삭제를 한다고
덜런 항목하나만 삭제를 해 버리면 될까??
이 시스템에서 각각의 항목은 부모,자식간의 관계를 유지하고 있다
그러니
항목만 덜렁 삭제를 해버리면 해당 항목의 부모와 자식간의 관계가
트릿했진다..
자식 항목에 있던 놈은 졸지에 고아가 되고
부모입장에서는 자식 하나 잊어 먹는 것이고, 이것은 상관없겠으나
자식항목은 쓰레기가 되는 셈이다
이것은 데이타베이스설계의 기본컨셉인 데이타무결성(Data Integrity)에
해당되는 이야기다
즉 데이타무결성을 어기면 데이타가 온전한 데이타 역할을 못하게 되는 셈이다
즉 결함이 있는 데이타가 된다는 이야기다
아래의 그림과 같이 상위레벨 A를 선택하여 보면 아무것도 없지만



자식레벨에서 화일정보를 갖고 있다
그러니 상위 A를 그냥 삭제를 하면 자식으로 있던 화일정보는 고아가 되는 셈이다
그러려면 두개의 테이블의 족보를 차례대로 자식쪽으로 내려가면서
찾아 보아야 할 것이다
찾아내려가다가, 중간자식이 정보를 갖고 있던, 맨 마지막 자식이
정보를 갖고 있던 제어를 해 주어야 한다
하위정보가 있는데 모두 삭제하시겠습니까???를 확인하여야 할 것이다
그러려면 선택된 정보를 테이블에서 찾으려면 해당 항목명의 ID를 사용하는 것이
원칙이다, 왜냐면 항목명은 같을수도 있으니까..
(물론 같은 항목명을 채우지 못하게 제어를 해 두기는 했지만..)
주민번호같은 ID를 사용하여 찾아가는 것이 원칙이다



이미 만들어 놓은 많은 함수들이 있어서 걱정할 것이 하나도 없다
항목명을 사용하여 ID를 갖여 오는 함수

iID = modMain.getIDByCategory(sItem)

그리고 각각의 테이블을 갖여 오는 함수

Set rCategoryTable = modMain.getTable(modMain.CATEGORY_TABLE_START)
Set rFileTable = modMain.getTable(modMain.FILE_TABLE_START)

아래와 같이 프로시져를 하나 만들자
이것은 아래의 그림과 같이 선택한 항목이하의 항목과 화일의 상태를 문자열로
갖여 오는 프로시져이다



삭제를 하겠다고 확인 버튼을 크릭하면
그림과 같이 해당 행을 UNION메소드에 담아 놓은 범위를 그냥
삭제하게 하도록 하면 되겠다
작은 소루션이지만 엑셀프로그래밍의 고급테크닉이 모두 들어 있는 아주
좋은 소루션이라고 볼수 있겠다
항목에서 하나의 항목을 선택하면 줄줄이 관련된 것을 죄다 찾고
범위를 선택한 상태까지 하고 사용자에게 삭제하겠냐고 하는 것
삭제 버튼을 크릭하면 아래의 프로시져

Private Sub cmdCategoryDelete_Click()
Dim sItem As String
Dim iID As Integer
Dim rCategoryTable As Range
Dim rFileTable As Range
Dim sFiles As String
Dim rList As Range
Dim shtMain As Worksheet
sItem = Me.lstCategoryView.Text
sItem = modMain.stripBad(sItem)
Set rList = modMain.getRowByCategory(sItem)
iID = rList.Cells(1)
Set rCategoryTable = modMain.getTable(modMain.CATEGORY_TABLE_START)
Set rFileTable = modMain.getTable(modMain.FILE_TABLE_START)
sFiles = sItem
Me.collectChildsForDelete iID, rCategoryTable, 0, sFiles, rFileTable, rList
Set shtMain = ActiveSheet
Application.Goto rList.Worksheet.Range("A1")
rList.Select
If MsgBox(sFiles & " 를 모두 삭제하시겠습니까", vbYesNo) = vbYes Then
    rList.Delete
    fillCategories
End If
Application.Goto shtMain.Range("A1")
End Sub

선택항 항목명으로 해당항목이 있는 행을 항목테이블에 찾아서
rList변수에 담아서

collectChildsForDelete (최초항목의 ID값, 항목테이블, 최초시작레벨 0, 자식항목을 찾아서 담을 문자열 변수, 화일테이블, 해당범위를 담을 변수)

라는 재귀프로시져에 보내 시동을 건다
아래가 전체 작업을 하는 재귀프로시져이다


Sub collectChildsForDelete(iID As Integer, rTable As Range, iLevel As Integer, sPath As String, rSubTable As Range, rList As Range)
Dim rChild As Range
Dim iChildID As Integer
Dim rRow As Range
On Error Resume Next
iLevel = iLevel + 1
For Each rRow In rSubTable.Rows
    If rRow.Cells(modMain.TBL_FILE_CATEGORY_ID_COL) = iID Then
        Set rList = Union(rList, rRow)
        sPath = sPath & vbNewLine & modMain.CATEGORY_TXT_INDENT & String(iLevel, "--") & rRow.Cells(modMain.TBL_FILE_FILENAME_COL)
    End If
Next
Set rChild = rTable.Columns(modMain.TBL_CATE_P_CATEGORY_ID_COL).Find(iID, , , xlWhole)
If Not rChild Is Nothing Then
    iChildID = rChild.Offset(, -1) 
    Set rList = Union(rList, rChild.EntireRow.Cells(1).Resize(, 4))
    sPath = sPath & vbNewLine & modMain.CATEGORY_TXT_INDENT & String(iLevel, "_") & rChild.Offset(, 1)
    collectChildsForDelete iChildID, rTable, iLevel, sPath, rSubTable, rList
End If
End Sub

아래 화일로 위의 내용을 잘 살펴보시고 각자의 업무상황에 적절히
응용을 해보세요
응용을 해보면 해볼수록 자신의 파워가 됩니다

***[LOG-IN]***