PROGRAMMING WORKSHOP

자재관리 | 프로그램초기화

소루션을 만들어서 관련자들에게 배포를 하려면
현재의 상태에서는 DB화일을 같이 배포하여야한다
그런데 담당자가 바뀌고하다 보면 이런 것들을 잊어먹게 되고
어떤 소루션인지 알지 못한 상태에서 사용하려고 하다보면
여기저기에서 에러가 터지게 된다
스스로 만들어서 스스로 사용하는 소루션도 한참 있다가 보면
헷갈리고 어떻게 해결하려고 하다 보면 당초만들때의 컨셉을
죄다 잊어 먹다 보니..결국은 버리게 된다
그런일을 최대한 방지하려고 노력하는 것이 개발자가 하여야 할 일중의 하나다
관련 화일들(자원)의 준비확인, 관련시트의 존재유무등을 하나,하나
초기화하는 습관을 갖여야 하고 이런것은 어느 정보 소루션이
마무리되는 단계에서 이루어지는 것이 좋다

엑셀소루션이 뛰어나면서도 우습게 보게 되는 것이
이 부분때문인 것이다
다른 프로그램들은 이 부분이 철저하다
그렇지 않으면 작업 자체가 원활하게 돌아가지 않지만
엑셀은 그냥 간단하게 뚝딱 만들어 사용하고
작업순서나 방법에 대한 도움말등로
별로 챙기지 않는 경향이 있는 것들이라서..
잠깐쓰고..버리고..또 만들어 쓰고..버리고..그래서 진정한
가치를 발휘하지 못하게 되는 셈이다

그런 의미에서 이 페이지는 만든 소루션에 좀더 가치를 부여하는
작업이 되는 셈이다

STEP_17 ---------------------------------

DB화일에 접근하려고 할때 DB화일이 없다면 당연히
에러가 나든가..처리한 상태에 따라서 일이 진행이 되지 않을 것이다
이것을 소루션이 돌아가면서 DB에 접근할때 DB화일 유무를 따지고
조치를 취하는 것이 좋을지..
화일이 열리면서 애초에 점검하여 조치를 취할지 이것도 실은
선택적 사항이다..
아무튼 어디에서 하던 , 하여야 한다
그렇지 않으면 엑셀 소루션 순..엉터리라는 소리 듣는다

여기에서는 화일이 열리면서 점검하고 조치하도록 하자

대강 만들어 놓고 초기화작업에 대한 검토를 하거나
관련하여 에러를 찾아서 수정하거나 이런 작업이 본작업보다
시간이 많이 걸릴까..적게 걸릴까??
더 걸린다..
한참 작업에 몰입을 할때는
경우의 수를 그렇게 많이 갖고 시작하지 않는다
어떤 목표를 향하여 질주를 하다 보니..다른 경우의 수를
그냥 넘기고 지나간다
아래의 그림과 같이 DB의 데이타가 없거나 정보가 없는
목록상자가 될때 두개의 버튼은 무용지물이거니와



에러관련조치를 하지 않아두었다면 에러가 나거나..공회전을
하거나, 쓸데없이 시트만 덜렁 만들어낸다..
이럴때 메시지박스를 띄우거나 하는 것 보다는 버튼두개를
비활성화로 죽여 버리는 것이 사용자를 덜 헷갈리게 한다

어떻게 하다 보니까..소루션화일은 2007버전이고
DB화일은 2003버전으로 해 놓았다
만약 DB화일이 없어서 DB화일을 새로 만든다고 할때
2007버전에서 xls확장자로 화일을 만들때 그냥 만들면
통합문서를 판독할수 없는 포멧으로 만들어진다
화일 포멧을 지정해주어야 한다

oBook.SaveAs sFile, Excel.XlFileFormat.xlExcel8
위와 같이 두번째 매개변수를 줄때..FileFormat에 대한 상수목록이
나타나지 않는다 이럴때는 상수의 풀경로를 주면된다
Excel.XlFileFormat 이라고 입력후 쩜을 찍어주면 화일포멧상수가
줄줄이 나타나는 것을 볼수 있다
어떤 것이니 상수목록이 나타나지 않으면 Excel로 시작하는 Full-Path를 앞에
넣어주면 된다

아래화일을 사용하시던 supplyDB.xls화일을 없애 버리고
열어 보시기 바란다
자동화일 생성되고 테이블 만들어지고
기존의 DB화일같이 역할을 하게 될 것이다
사용자들에게 배포할때 DB화일없이 배포해도 되는 셈이 된다
추가되거나 수정되거나 새로 발견된 에러를 핸드링한 부분은
주석부분에 Step_17로 표기 되어 있으니 찾기로 찾으면서
보시면 쉽게 이해하시게 될 것이다

지루하더라도 Step By Step으로 화일을 탐구하시고
의아하거나,에러가 있거나,기타 질문있으면 꼭 메일하시고..
그래야 내공이 쌓여 진다

***[LOG-IN]***

STEP_18 ---------------------------------

또..상상과 예측을 해서..사용자가 목록시트를 망가뜨렸다고 가정하자..
중요한 정보가 있는 목록시트가 없어지면 낭패다
이것도 초기화할때 살펴보고 조치를 해주어야 한다
시트가 있는지 알아보고..
시트가 있어도 기본정보입력범위가 제대로 Naming을 유지하고
있는지 살펴볼 필요가 있다

예를 들어서 mySheet라는 이름의 시트에 중요한 정보가 있는데
이 시트를 여러곳에서 접근을 하게 되었다고 한다면

Sub Proc_1()
Dim shtX As WorkSheet
Set shtX=Worksheets("mySheet")
...
...
...
End Sub

Sub Proc_2()
Dim shtX As WorkSheet
Set shtX=Worksheets("mySheet")
...
...
...
End Sub

Sub Proc_3()
Dim shtX As WorkSheet
Set shtX=Worksheets("mySheet")
...
...
...
End Sub

소루션이 전개 되다 보면 이런 짓을 수도 없이 하게 된다
그런데 mySheet라는 시트를 사용자가 이름이 마음에 안든다고
고쳐버렸다던가..아예 삭제를 해 버렸다거나..
그래서 이렇게 할 것이다

Sub Proc_1()
Dim shtX As WorkSheet
On Error Resume Next
Set shtX=Worksheets("mySheet")
If shtX Is Nothing Then
   Exit Sub
Else
...
...
...
End If End Sub

Sub Proc_2()
Dim shtX As WorkSheet
On Error Resume Next
Set shtX=Worksheets("mySheet")
If shtX Is Nothing Then
   Exit Sub
Else
...
...
...
End If End Sub

Sub Proc_3()
Dim shtX As WorkSheet
On Error Resume Next
Set shtX=Worksheets("mySheet")
If shtX Is Nothing Then
   Exit Sub
Else
...
...
...
End If End Sub

하다 보면 이렇게 누덕누덕 땜질을 해가면서 진행하게 된다
이런 것을 당초에 소루션이 시작될때..

Public shtX As Worksheet

Sub 시작할때프로시져()
On Error Resume Next
Set shtX=Worksheets("mySheet")
if shtX Is Nothing Then
  어떤 조치를 취하여..
  새로 만들던가..아예시작을 하지 않던가
End if
End Sub

Sub Proc_1()
외부변수의 shtX를 그냥 사용하면 된다
End Sub
Sub Proc_2()
외부변수의 shtX를 그냥 사용하면 된다
End Sub
Sub Proc_3()
외부변수의 shtX를 그냥 사용하면 된다
End Sub

물론 또 실행중에 생각없는 사용자가
뭔 이유인지..또 mySheet를 삭제해버릴수도
있겠지..그런 끝없는 경우의 수를
생각 하면서 프로그래밍을 하는 것이다

그러다 지치면..에이..그냥 알아서 쓰라고 그래!!
라고 할 수도 있겠으나..그러면 안되겠지..
프로그래머는 그런 문제를 일으키는 사람들에게 고마워
하면서 열심히 정리 정돈해 나가는 것이다

모든 자동화를 요구하는 사람들은 불평불만이 많고
생각은 많은데 논리가 정리가 안되어있다
이런 불평불만을 잘 해결하는 프로그래머가 좋은 프로그래머
이 곳 워크샵출신들의 코드는 거의 (Fool Proof)완벽하기를 바라면서..

또한 프로그래밍에서 이름의 사용은 필수중의 필수
그런데 소루션에 만들어 놓은 이름들을 잘 관리해주지 않으면
낭패를 본다
이름을 짓는 것은 통합문서상에 변수를 만들어 놓는 것과 같다
여러분이 사용하는 통합문서 아무것이나 열어서
이름상자를 살펴보시면 죽어 자빠져있는 주소불명..#REF!!의
주소들이 산같이 쌓여있을수도 있을 것이다
초보들의 화일을 점검해보면 이눔이 잘 하는 놈인지..못하는 놈인지는
이름 관리를 보면 안다...(VB없는 일반통합문서의 사용에서도...)

프로그램적으로 이름 관리를 한다고 하는것은
아래와 같이 상수를 만들어 놓고 정성껏 관리하여야 한다

Public Const NAME_LIST As String = "sitename|현장명," & _
                                   "workname|공종명," & _
                                   "teamname|팀명," & _
                                   "requester|청구자," & _
                                   "memo|메모," & _
                                   "hp|핸드폰," & _
                                   "requestdate|발주일," & _
                                   "supplydate|입고일," & _
                                   "companyname|업체명," & _
                                   "status|진행상태," & _
                                   "liststart|"

[청구서양식]시트에서 사용하는 이름은 영문이고
[목록표]시트에서 사용하는 이름은 한글로 만들어 둔 것이다
정보의 내용은 같은데 다른 두개의 시트에서 공유하는 정보인 셈이다
위의 이름이 손상되면 에러가 당연히 난다
위와 같이 문자열 상수로 만들어 놓으면 배열화시키셔 순환하면서
사용하는 이름을 쉽게 확인하고 손상되었다면
새로 쉽게 만들수 있는 것이다

Dim arrFlds As Variant, varX As Variant, sName As String
Dim iX As Integer
arrFlds = Split(modMain.NAME_LIST, ",")
For Each varX In arrFlds
    sName = Split(varX, "|")(1)
    If Instr(ThisWorkbook.Names(sName).RefersTo,"#REF!")>0 Then
    	''''손상된 이름...
    End if
Next

위와 같이 순환하면서 손상된 것도 확인하고
손상되었다면 삭제하고 다시 정상적으로 만들어 놓기도 할수 있는 것이다

종종 ERP의 문제를 많이 이야기한다
뭘 만들어 놓기는 했는데...사용자들이 사용을 하지 않는다
왜그럴까??!!
지금 현재 진행중인 이런 소루션같이
조직의 부서별 특화된 업무의 작은
자동화가 우선되고..즉 각각의 부서별 자동화가 이렇게 자동화되었다면
아하..이제 이것을 공유하면 좀더 시너지가 나겠구나..라는
욕구가 조성이 될 때
이것을 통합하는 순서로 통합소루션을 구축하던가
Server와 Office(엑셀,워드등)와 VSTO를 활용한 개성있는 조직의 통합방식을
구축할수 있게 되는것이다
그러나..현실은 꺼꾸로 진행이 된다
회사의 구성요소상 ERP와 유사한 대용량정보관리시스템이 있어야 한다는
요식에 충실하다 보니..그냥 통상적인 것을 하나 만들어 놓겠지..
그러니 실무자들과는 거리가 먼 통합소루션인 셈일 것이다
아무쪼록 부서별 문제점을 많이 제기 하셔서
회사의 전체흐름을 만들겠다는 큰 포부를 갖으시고 한다면
이 코너의 목적에 맞게 되는 것!!Keep A Great Aspiration!!




그림과 같이 flow Chart를 종이에 연필로 끄적 거리는 습관도
프로그래머에게는 좋은 습관이고 필수적인 일이다
생각이 명료해지고, 로직이 확실해진다
그림에서 [청구서시트]가 없다거나,
이름이 손상되었을때는
소루션화일 폐기하고
다시 화일을 개발자로 부터 받는 것이 좋도록 하는 것이 편하다
청구서양식시트도 없으면 프로그래밍적으로 만들면 좋겠으나 이것은 입맛에 맞는 정성껏서식을 한 양식이므로 프로그래밍적으로 만드는 것은
미련한 작업이 될 수있을 것이다
실은 이런 양식은 템프릿을 만들어서 소루션과 함께 템프릿화일을
배포하는 것이 더 좋은 방법이 될수 있을 것이다
자재목록시트는 사용자가 필요에 따라서 추가시키는 것으로 한다

***[LOG-IN]***

STEP_19 ---------------------------------

프로그래밍을 하다 보면 실제 소루션에는 필요없는
디버깅용 프로시져를 만들어서 사용하게 된다
예를 들면 현재 통합문서의 Name개체가 어떤 상황인지 알고 싶다
이름 상자를 찾아보는 것도 좋지만 프로그래머답지 않다
모듈시트 한코너에 디버깅용 도구들을 준비하고 있으면
코딩을 도와주고 잘못된 것을 수시로 찾아주는 역할을 한다
예를 들어서 아래와 같은 것을 하나 작성해두고


'###########################################
'#  just for DEBUGGING
'###########################################
Sub debugNames()
Dim oName As Name
For Each oName In ThisWorkbook.Names
    Debug.Print oName.Name & "|" & oName.RefersTo
Next
End Sub

실행하면 아래의 그림과 같이 이름에 대한 족보를 한눈에
금방 볼수 있을 뿐만 아니라..잘 못되 이름도 살펴보고
상수들을 만들때 이것을 복사하여
붙여 넣고 편집을 하면 시간절약도 많이 된다



직접실행창(Immediate Window)는 개발자의 아주 중요한 도구이다
항상 끼고 살아야 하는 창이니..잘 활용하는 습관을 갖는 것이 좋다

예를 들어서 디버깅을 하는 과정을 보면 아래의 그림과 같이
각 이름 지어진 주소를 관찰하니



같은 용도의 범위의 이름이 하나는 셀을 하나만 참조하고 있고
다른 하나는 3개의 범위를 참조하고 있다
이런 것들이 에러의 원인이 된다
일관성있게 이름을 지어 주어야 한다

핸드폰의 정보를 알아본다고 아래와 같이 접근하면 핸드폰정보에서
에러가 나는것이다
Dim sPhone As String
Dim sStatus As String
sStatus=ThisWorkBook.Names("상태")
sPhone=ThisWorkBook.Names("핸드폰")

sPhone=ThisWorkBook.Names("핸드폰").Cells(1)

이라고 접근해야 한다
손작업으로 이름을 지어줄때 잘 못 지어준 것이다
병합을 하기전에 이름을 지어주거나
병합후에 지어주거나..그런 차이가 난 것이다
이런 것은 손으로 수정을 하던, 프로그래밍적으로
수정을 하던 해주어야 일관성있는 접근방법을 유지하게 된다

또한 안전하게 위와 같이 트릿하게 이름을 지어 주었더라도
항상 병합된 셀에서는

sStatus=ThisWorkBook.Names("상태").Cells(1)

로 접근하면 어떻게 하였더라도 에러 없이 접근된다는 점을
아시면 사태를 피하게 된다

이렇게 이용하여 이것을 복사하여
상수를 좀더 개선하고 효율적으로 몇개를 고쳐 보도록 하자
이전 스텝에서 [양식시트]의 이름이 잘못되면 무조건 작업을 중단시키게
하였으나 이것을 좀 무책임한 짓이다
양식시트가 없을때만 중단시키고 이름은 잘못되면 수정하고
사용하게 하도록 하자
실은 이전의 상수목록에서는 이름을 수정하기 곤란하였다
이름에 관련한 상수를 이렇게 고치니까...요렇게 편리하네!!
라는 것이 될 것이다

***[LOG-IN]***