PROGRAMMING WORKSHOP

화일관리도구 |

이제 목록상자에서 화일을 선택하면 버튼이 하나 더 활성화되게 하자
화일을 여는 버튼을 준비한다
이런 순서를 잊지말자
1)화일열기 버튼을 콘트롤상자에서 추가한다
2)속성상자에서 버튼의 이름을 지어 준다(cmdFileOpen)
3)화일캡션으로 사용될 상수를 modMain에 추가 선언한다
    Public Const FILE_OPEN_CAPTION = "화일열기"
3)폼이 열릴때 콘트롤이 초기화되는 부분에 이 버튼의 초기화도 추가한다

    

상수등을 선언해두면 코드가 복잡해지면 , 복잡해질수록
편리함을 느끼게 된다, 그렇지 않으면 일관성없는 작업으로
머리가 아파지기 시작한다
그러니 준비작업을 잘 하면 잘 할수록 모든 일이 질서있고, 일관성을 유지하게 한다
이런 작업은 프로그래밍뿐이니라 , 모든 일이 마찬가지 일것이다
그리고 버튼의 Enabled=False로 해주고 목록에서 어떤 화일을
선택할때만 활성화되게 하는 것이 편리할 것이다

그 다음 작업은 화일목록상자에서 화일을 선택할때 버튼이 활성화되게 하는 것을 한 줄 집어 넣고..

Private Sub lstFile_Change()
Dim iX As Integer
Me.cmdFileDelete.Enabled = False
Me.cmdFileOpen.Enabled=False
For iX = 0 To Me.lstFile.ListCount - 1
    If Me.lstFile.Selected(iX) Then
        Me.cmdFileDelete.Enabled = True
        Me.cmdFileOpen.Enabled = True
        Exit Sub
    End If
Next
End Sub 

이제 준비작업끝난 것이다
항상 콘트롤을 추가삽입할때의 작업순서라고 생각하시면 편리할 것이다
점심먹으로 가려고 할때도
이런 하나의 일의 싸이클을 일단락 짓고 가는 것이 좋은 습관이다
중간에 배곺으다고 나가면, 점심먹고 오면 헷갈린다..^ ^

이제 버튼을 크릭하면 어떤 일을 할지 프로그래밍을 하면 될 것이다
아래의 이벤트프로시져에 지능을 심어 주는 일이 여러분이 하여야할 일



엑셀화일을 열려면 어떻게 하더라???
그 것 보다도 어떤 화일이 선택되었는지 정보를 갖여 오는 것이 우선이다
그러면 어떤 화일이 선택되었는지 정보가 필요하였던 다른 곳에서의 기능이 있었던가???
를 생각해 볼일이다
왜냐면 이미 선택된 화일의 정보가 필요했던 기능에서 만들었을 것이니까??
어디에서 했었더라???
화일을 삭제할때 필요 했었다
이때도 화일명과 경로명을 알아야 삭제를 할수 있었으니까..
이번에는 화일을 열려고 하는 것이니까..
삭제냐, 여는 것이냐의 동사만 다를뿐 필요한 정보는 같았었다
삭제하던 기능을 보면 아래와 같았었다

Private Sub cmdFileDelete_Click()
Dim sPath As String
Dim sFile As String
Dim iRowNum As Integer
Dim iX As Integer
Dim oX As New Collection
For iX = 0 To Me.lstFile.ListCount - 1
    If Me.lstFile.Selected(iX) = True Then
        With Me.lstFile
            sFile = .List(iX, 0)
            sPath = .List(iX, 1)
            iRowNum = .List(iX, 3)
            oX.Add iRowNum & "|" & sPath & "|" & sFile
        End With
    End If
Next
deleteFile oX
fillFilesList modMain.stripBad(Me.lstCategoryView.Text)
cmdFileDelete.Enabled = False
End Sub

위에서 빨강색으로 표현한 부분이 선택된 화일을 수집하여
집합체에 담는 과정이였다
그렇다면 이부분을 분리 독립시킨다면 삭제하는 작업과 화일을 여는 작업에서
공동으로 사용할수 있는 함수가 되는 것이다
함수의 이름을 지을때 이렇게 정보를 갖여 오기 위한것은
Get이라는 동사를 앞에 붙이면 나중에 인식하기 편리하다
그래서 함수명을
GetSelectedFiles
라고하면 흠..선택된 화일을 갖여 오는 함수로구나!! 라고 쉽게
식별할수 있는 것이다
좀더 설명적이라고 하면
GetSelectedFilesFromListBox
선택된 화일을 목록상자에서 갖여오기 라고 하면 좀더 설명적일것이고
아무튼 이름짓는 것에 흥미를 갖는 것이 좋을 것이다
화일열기 버튼을 달고, 제대로 화일명과 경로명을 읽어 오는지
확인을 해보면...아라...경로명이 왜 안나타나지???
분명히 화일삭제에서는 있었던 것 같은데..!!###
역시 이런 문제가 소루션이라는 좀 규모가 큰 것을 해보아야 나타나게 된다
그러니 워크샵은 참으로 좋은 코너다...^ ^
다양한 문제를 경험하는 기회가 되니까..
알고는 있는데 경험을 하지 않으면 자신의 것이 되지 않는 법



지난번에 함수를 하나 만들었었다
화일을 추가하면서 화일이 중복되지 않는지 체크하는 함수었다
sFile이라는 매개변수를 전달하고 테이블의 다른 화일정보와 비교를 하게 하는 함수였다 이때 sFile매개변수를 받아서 그냥 사용하여 문제가 생겼다

Private Function isNotDupeFile(sFile As Variant, oDupe As Collection)
On Error Resume Next
Dim iX As Integer
sFile = Right(sFile, Len(sFile) - InStrRev(sFile, "\"))
For iX = 0 To Me.lstFile.ListCount - 1
    If sFile = Me.lstFile.List(iX) Then
        oDupe.Add sFile
        isNotDupeFile = False
        Exit Function
    End If
Next
isNotDupeFile = True
End Function

위의 것은 다음과 같이 둘중의 하나로 하여야 한다
Private Function isNotDupeFile(sFile As Variant, oDupe As Collection)
On Error Resume Next
Dim sFile_ As String
Dim iX As Integer
sFile_=sFile
sFile_ = Right(sFile, Len(sFile_) - InStrRev(sFile_, "\"))

와 같이 하거나 아래와 같이 매개변수를 ByVal로 바꿔주거나
디폴트로 매개변수는 ByRef 로 되어있다
Private Function isNotDupeFile(ByVal sFile As Variant, oDupe As Collection)
On Error Resume Next
Dim iX As Integer
sFile = Right(sFile, Len(sFile) - InStrRev(sFile, "\"))

변수하나를 더 만들기가 귀찮으면 이런 낭패에 빠진다
이 함수를 호출한 곳에서 sFile이라는 매개변수로 전달한 변수를
계속 다른 작업을 이어서 진행하여 간다면 함수에서 경로명을 짤라버린 상태의 정보를
갖고 작업하는 셈이 되니..엉뚱한 값을 만들게 되고
목록상자에 경로정보를 올리지 못하게 되는 결과를 갖여 온것이다
그래서 작업을 하면서 항상, 정상적인 정보를 현재 갖고 있는지
확인사살하는 습관이 일이 복잡하게 얽히기전에 사전에 조치가 되는 것이다
위와같은 경우는 흔하게 발생할수 있는 일이다
그러나 수시 확인사살습관이 없으면 흔하게 발생하는 실수가
전체를 고민하게 만드는 수가 있으니
당장은 느린것 같아도 전체적인 것으로 볼때는 훨씬 빠르고
관리할수 있고 통제할수있는 자신만의 코드의 구조를 꾸며 나갈수 있다
그래서 ByVal로 매개변수타입을 바꿔 놓았다
ByRef가 어떻고, ByVal이 어떠한것인지는 이미 알고 있으나
실무에서는 깜빡, 깜빡한다는 점, 자꾸 작성해 보아야 한다는 점!!
잊지 마시고!!
참고로 VB.Net에서는 디폴트로 ByVal로 되어 있다
그들도 하다 보니까, ByVal로 하는 것이 조금더 효율적이라고
생각한 모양이다

아무튼, 그래서 정확한 경로명과 화일명을 알아낼수 있다는 점을 화일을
여는 작업을 하기전에 디버깅확인하였다
다음은 이제 열기만 하면 된다
pdf 화일도 있을 것이고, doc화일도 있을것이고
xls화일도 있을 것이고, 다양한 화일을 해당 화일의 프로그램을 찾아서
Shell함수등을 사용하려고 하면 복잡하다
그것보다는 알아서 처리하는 Workbook개체의 FollowHyperlink 메소드를
사용하는 것이 좋을 것이다

목록상자에 몇개의 화일을 화일형식이 다르게 선택해도
모두 자연스럽게 열릴 것이다
위의 내용을 아래의 화일로 실행시키면서 응용을 더 해보시기 바란다

Private Sub cmdFileOpen_Click()
Dim oX As Collection
Dim varX As Variant
Dim sFile As String
Set oX = getSelectedFilesFromListBox
For Each varX In oX
    sFile = Split(varX, "|")(1) & Split(varX, "|")(2)
    ActiveWorkbook.FollowHyperlink sFile
Next
End Sub

***[LOG-IN]***