PROGRAMMING WORKSHOP

자재관리 | DB기능을 좀더 활용하자

STEP_15 ---------------------------------

청구서를 주욱 만들면서 이력시트를 만들었지만
실제청구서화일과 동기화가 실질적으로 사용자의 주의가 요구되는 것이라서
불안하다
이것을 통합문서에서 없애고 DB의 [청구서]목록을 활용하는 것이
훨씬 정보의 보안성이 강화될 것이다
청구 이력이 필요할때 항상 UserForm 의 두번째탭의 목록상자에
불러 들이는 것이 기능적으로 강화되는 모습이 될 것이다

UserForm의 MultiPage콘트롤등과 같이 Page의 처리에 있어서
MultiPage1.Value가 0일때는 어떤 콘트롤을 어떻게 하고
아닐때는 어떻게 한다는 시나리오를 만들때
아래와 같이 만들면 융통성이 없다
소루션이 확장되면서 페이지가 늘어나게 되면
조건식을 계속 추가 시켜야 한다

If MultiPage1.Value = 0 Then
   Me.CommandButtonGetDetail.Enabled = False
Else
   Me.CommandButtonGetDetail.Enabled = True
End If

이렇게 하는 것이 바람직하다
Me.CommandButtonGetDetail.Enabled = False
If MultiPage1.Value = 1 Then
   Me.CommandButtonGetDetail.Enabled = True
End If

CommandButtonGetDetail은 페이지값이 1일때만 사용하고 싶은 것이니까..
다른 페이지가 추가되더라도 이렇게 False로 해둔후
True로 하는 것이 편리하다
아래와 같이 페이지탭을 더 추가하여
모든 자원을 UserForm에서 관리하도록 하자



첫째 탭은 청구서를 작성할때 청구품목이 추가될때마다 목록과
시트에 추가되어 최종 청구서가 작성될때까지 모니터링하게 하고
두번째 탭은 DB에서 현재까지 작성된 청구서목록을 갖여와 목록상자에 채운다
세번째 탭은 화일폴더에서 현재까지 작성보관되고 있는 보고서화일의 목록을 채운다

두번째 탭을 채우는 것은 아래와 같다

Dim oCon As New ADODB.Connection
Dim oRST As New ADODB.Recordset
oCon.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
           "Data Source=" & ThisWorkbook.Path & _
           "\supplyDB.xls;" & _
           "Extended Properties=Excel 8.0;"
           
	 '###
	 '# LogSheet대신에 DB의 청구서테이블에서 그동안
	 '# 청구하였던 청구서 목록을 갖여 온다
	 '###########################
oRST.Open "[청구서$]", oCon, adOpenKeyset, adLockOptimistic, adCmdTable
Dim varData As Variant
					 
	 '######
	 '# Recordset의 GetRows는 메모리상의 테이블에서
	 '# 원하는 행만큼의 정보만 배열로 갖여 올수 있다
	 '#####################################
varData = oRST.GetRows(oRST.RecordCount)

	 '#######
	 '# 이 배열을 행열 방향바꾸어서 그냥 목록상자의
	 '# List속성에 주면 채워진다
	 '#####################################
Me.ListBoxOrderHistory.List = Application.Transpose(varData)
oRST.Close
oCon.Close
Set oRST = Nothing
Set oCon = Nothing

***[LOG-IN]***

STEP_16 ---------------------------------

Log_Sheet에서 하던 기능을 UserForm으로 옮기고
Log_Sheet는 삭제 해 버리자

기능이 확장되다보면 같은 기능을 여러곳에서 호출하게 되는 것은 당연하다
그러니 귀찮더라도 항상 기능별 프로시져나 함수를 만드는 습관이 좋다
당초에는 Log Sheet에서 수행하던 일을
UserForm에서 하게 한다 라는 시나리오로 바꾸면
당초에 별도의 프로시져를 Log Sheet에서 호출하는 방식으로 작성하였다면
그냥 UserForm에서 호출하도록 방향만 바꾸면 된다
그러나 별도의 프로시져의 개념없이 LogSheet에
한꺼번에 때려 넣고 작성한것을 찾아서어서 복사하고 붙여 넣고
편집하고..번접을 떨어야 하는 것이다
그래서 귀찮더라도 분산시킨 프로시져작성 습관이 좋은 것이다
프로그래밍워크샵의 목적은 이렇게 연속성으로 문제를 수십개의
화일로 확장시켜가면서 단발적으로 하나의 프로시져를 학습할 때
경험하지 못하는 현실적,실무적으로 적용할수 있는 경험을 쌓아가기
위한 곳이니..그런 개념으로
화일을 중간에서 다운 받아서 보려고 하지 마시고
처음 문제 제시부분을 충분히 질문을 제시한 분과 같이 공감하는 것으로
부터 화일 하나,하나 꾸준히 경험하시는 것이 좋다

LogSheet대신에 UserForm의 목록에서 워크시트에 값을 옮기고 싶으면
순환문을 돌고 자시고 할 것이 없이 아래와 같이 하면 한방에 처리된다
배열활용을 항상 염두에 두고 살면 되면 , 코딩이 그렇게 된다

Dim varHistory As Variant
frmPanel.ListBoxOrderHistory.List
shtReport.Range("A1").Resize(UBound(varHistory, 1) + 1, UBound(varHistory, 2) + 1) = _
   varHistory

UBound(배열,1)은 행방향갯수..0부터 시작하므로 하나가 적다 그래서+1
UBound(배열,2)는 열방향갯수..마찬가지
UserForm의 목록상자에서 배열로 값을 통째로 받아오는 것은 ListBox.List
즉 List라는 속성의 정보형식은 배열인 것이다
엑셀시트의 범위도 배열..목록상자의 List속성도 배열 !!!
그러니 그냥 집크기만 정확히 잡아서..한번에 전달하면 된다
배열을 주고 받을때는 반드시 Variant타입변수를 사용함을 잊지 말고!!

그런데 여기에서도..주의할점은 열머리제목을 갖여 오지 않는 다는 것!!
ADO의 Recordset에서도 CopyFromRecordset에서 배열을 갖여올때도
역시 열머리 휠드명은 없었다는 점을 감안하시고..

그래서 중요한 테이블의 열머리는 상수화시켜서 관리하는 것이 좋다
아래와 같이..

Public Const DB_MAIN_TBL_FLDS As String = _
    "청구ID,업체명,발주일,입고일,현장명,공종명,팀명,청구자,핸드폰,메모"

테이블에 휠드명을 한꺼번에 옮기려면 위의 상수를 이용하여

shtReport.Range("A1").Resize(,UBound(varHistroy,2)+1).Value= _
   Split(DB_MAIN_TBL_FLDS,",")

와 같이 배열을 한꺼번에 전달받고, 전달하는 것에 익숙해지는 것이 좋다

이런 배열로 옮길때 함정이 하나 있다
ID같은 것이 숫자로 주욱되어 있는 것을 예를 들면
120428134102 와 같은 코드를 배열로 한꺼번에 갖여 오면
1.20428E+11 과 같은 공학숫자표기로 바뀌어 버린다
나중에 이것으로 DB의 관련정보를 찾을수 없다..전혀 의미가 다른 값이 되어 버린것이다
아휴...그럼 천상 순환하면서 ' 표시를 하나씩 찍어가면서
처리해야겠군!!!! 이라는 생각을 할수도 있고
엑셀의 성질머리를 잘 아시는 분들은 아래와 같이 값을 받을범위의
형식을 바꿔버리면 엑셀런트!!!

shtReport.Columns(1).NumberFormat = "@"

즉 이곳에 들어오는 숫자는 문자로 받겠다!!라는 의미가 된다
좀더 경험이 있는 사람과 없는 사람의 차이는 손발이 덜 피곤한 셈이다
VBA 초보는 순환문에 감탄하지만
고수가 되면 어떻게 하면 순환문을 없애버릴까?에 골몰한다

이번 화일에서는 아래의 그림과 같이



Log_sheet의 내용을 UserForm의 목록상자선택에 따른 각 버튼에서
처리하게 되는 작업..
많이 활용하시기를..
UserForm의 사용의 매력에 잘빠져들면
나중에 VB.Net의 전통적 윈도우폼으로 업그레이드는
누워서 떡먹기 된다
왜나면 전통적 윈도우폼(Win32 폼)은 UserForm에서의 불편하고
없는 기능들이 아주..아주 많아진다는 것만 다르고 개념은 같은 것이니
UserForm을 어려워하지 마시고 모두 도전하시기를!!

***[LOG-IN]***