PROGRAMMING WORKSHOP

.Net FrameWork,VB.Net | VBA_XL프로그래밍학습도구만들기

인터페이스만들기

VBA와 XL프로그래밍을 어떻게 하면 쉽게 습득하실수 있게 할까??
그리고 .Net시스템과 윈도우프로그래밍을 어떻게 쉽게 하시게 할수 있을까?
라는 것이 항상 마음에 걸려 있는 문제다
이렇게, 저렇게 많이 시도를 하지만, 주제가 까다로운 것이라서
Uno_Weekly에서 CodeLibrary등을 많이 제공도 하고 있지만, Add-In설치의
까다로움에서 많은 분들이 접근을 하지 못하여 잘 활용하는것 같지 않다
아예, 이 워크샵에서
VSTO로 만들어 보이는 것도 좋겠으나, 쌤플화일 배포과정에서 별로 흐름이 안좋고
그래서 이번 기회에 UNO_Weekly의 CodeLibrary를 리뷰도 하면서 같이 유지하면서
윈도우버전으로 공통의 내용으로 인터페이스만 다르게 만들어서
접근하기 쉽게 하여 프로그래밍도구의 활용에 도움이 되도록 하려고 한다



.Net 시스템도 익숙하게 하고 , Window의 콘트롤들을 흥미있게 접근해 보기도 하고
크래스 라이브러리를 만들어서 엑셀의 VBA에서 참조하여 사용하게도 하도록 해보려고 한다
만들면서 수정도 자주 하고 할것이니, 중간중간에서 보려고 하지 마시고
차례대로 페이지를 소화시키면서 보시기 바란다

.Net 시스템과 동시에 VBA와 Excel 개체의 새로운 관찰이 되시도록 할 것이다

실은 엑셀도 알아야하고, VBA도 알아야 하고, .Net 시스템을 알아야 하고
Window폼에서 대하여 알아야하고 , 참 복잡하다면 복잡할수 있지만,
이번 기회에 통합된 무언가를 만들어 보면서, 다양하게 경험할수 있도록 해보자

빈 폼을 로딩하면서
Run Time으로 컨트롤을 아래 그림과 같이 생성하여 붙여 나가도록 하자..



아래와 같이 코딩한다..

Public Class Form1
    '' 필요한 전역변수...만들면서 수정,추가될것이다
    '' TabControl의 이벤트를 사용하게 WithEvents 지시어를 사용하여 선언하고
	'' TabPage를 선택할때마다 발생하는 이벤트를 활용하기 위하여..
	'' WithEvents 지시어를 같이 선언하고
    Private WithEvents myTab As TabControl
    '' 콘테이너 콘트롤 두개
    Private mySplitContainer As SplitContainer
    ''mySplitContainer의 두개의 파넬중 오른쪽파넬에 배치한 FlowLayoutPanel콘트롤
    Private myFlowLayoutPanelRightHandSide As FlowLayoutPanel

    ''정보를 보관할 전역변수들
    Private myXLWidth As Long
    Private myXLHeight As Long
    Private myXLLeft As Long
    Private myXLTop As Long
    Private sCurrentTabPage As String
    '' TabControl의 TabPage콘트롤의 캡션으로 사용할 엑셀의 중요개체명
    '' 이것도 역시 추가 되겠지..
    Private TOPIC_LIST As String = "Application,Range,PivotTable,Shape"

    '' 폼이 로딩되면서.. Load 이벤트에서

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        '' 별도의 콘트롤 생성하는 내용의 프로시져를 호출한다
        setControls()
    End Sub
...
...
...
End Class

setControl 프로시져는 아래와 같이..

Private Sub setControls()
	''  SplitContainer 만들기
	mySplitContainer = New SplitContainer
	mySplitContainer.Dock = DockStyle.Fill
	mySplitContainer.IsSplitterFixed = False
	Me.Controls.Add(mySplitContainer)

	'' TabControl만들어서 SplitContaner 의 Panel1에 추가한다
	myTab = New TabControl
	myTab.Dock = DockStyle.Fill
	''탭페이지를 위의 전역변수로 선언한 문자열상수를 배열화하여
	''순환하면서 TabPage를 추가해나간다
	''이것의목록의 갯수를 확장하려면, 위의 문자열상수에 계속 목록을 추가하면 된다
	For Each sX As String In TOPIC_LIST.Split(",")
		myTab.TabPages.Add(sX)
	Next
	'' SplitContainter는 두개의 파넬로 구성되어 있다
	'' 왼쪽 파넬에 TabControl이 들어가고, 이것의 폭의 정보를 갖고 있는 속성은
	'' SplitDistance 라는 속성이다
	'' 윈도우폼의 폭의 3분의 2로 하고
	mySplitContainer.SplitterDistance = Me.Width / 3 * 2
	'' 이곳에 TabControl을 추가하고..
	mySplitContainer.Panel1.Controls.Add(myTab)

	''SplitContainter의 오른쪽 파넬에 넣을 
	''FlowLayoutPanel 콘트롤을 생성하여 넣는다
	myFlowLayoutPanelRightHandSide = New FlowLayoutPanel
	myFlowLayoutPanelRightHandSide.FlowDirection = FlowDirection.TopDown
	myFlowLayoutPanelRightHandSide.Dock = DockStyle.Fill
	mySplitContainer.Panel2.Controls.Add(myFlowLayoutPanelRightHandSide)

	''윈도우의 바닥의 StatusBar가 나타나게 StatusBar개체를 생성하여
	Dim myStatusBar As New StatusBar
	'' 예비버튼을 StatusBar에 나타나게 하자
	'' 이것은 앞으로 메뉴가 전개되면서, 사용할지 안할지 두고 볼일..
	'' 사용하지 않으면 없애면 되니까..
	'' 알파벳 26문자를 나타나게 버튼을 만들자
	'' 26버 순환하면서
	For iX As Integer = 1 To 26
		Dim oBtn As New System.Windows.Forms.Button With {.Text = Chr(64 + iX), .Left = (iX - 1) * 21, .Size = New Size(20, 20)}
		'' 버튼을 크릭하면 실행될 프로시져를 다른 곳에 만들지 않고
		'' 이렇게 InLine으로 표현하는 것을 Lambda Expression 이라고 한다
		'' 다른 코너에서 많이 이야기했었던 것이다..
		'' 앞으로 Lambda Expresion등도 자주 이야기하게 될 것이다
		AddHandler oBtn.Click, Sub(q As Object, erg As EventArgs)
								   MsgBox("예비버튼...")
							   End Sub
		'' 버튼이 만들어지는 대로 StatusBar컨트롤에 추가하고..
		myStatusBar.Controls.Add(oBtn)
	Next
	'' 그리고 버튼을 다 담고, 폼의 Controls에 추가하면 된다
	Me.Controls.Add(myStatusBar)

	'' 폼의 폰트속성에 폰트개체를 주면 모든 폼의 컨트롤에 부여되는 셈이다
	Me.Font = New System.Drawing.Font("맑은 고딕", 10)
	Me.Text = "UNO_VBA-XLProgramming"
	'' 폼이 열리면서 상태는 PC스크린에 꽉차게 펼쳐주게 하고
	Me.WindowState = FormWindowState.Maximized
	myXLLeft = 10
	myXLTop = 30
	'' 전역변수의 이값은 앞으로 사용하게 될
	'' 엑셀통합문서가 만들어질 위치와 크기를 정해준것..
	myXLWidth = myTab.Width - 20
	myXLHeight = myTab.Height - 50


	'' 모두 완료되면, TabControl은 이벤트가 발생하지 않은 상태다
	'' TabControl의 이벤트에서 호출할 프로시져를 호출하여 사용한다, 즉 첫째탭을 연것과 같은
	'' 효과가 나게 한다..

	myTabIndexChanged(0)
End Sub

위의 생성된 TabControl의 TabPage를 선택할때마다 이벤트가 발생하는 이벤트프로시져
SelectedIndexChanged 이벤트프로시져를 아래와 같이 작성하여 탭콘트롤의 페이지
선택때마다 다른 버튼 목록 세트가 만들어지게 한다

Private Sub myTab_SelectedIndexChanged(sender As Object, e As EventArgs) Handles myTab.SelectedIndexChanged
	''폼이 로딩할때도 사용하기 위하여 별도로 프로시져를 만들어서 호출한다
	myTabIndexChanged(CType(sender, TabControl).SelectedIndex)
End Sub
'' 아래가 이벤트프로시져에서 호출한 프로시져
Private Sub myTabIndexChanged(iIndex As Integer)
	'' 패널상의 이전에 만들어졌던, 다른 탭페이지의 것,을 전부지우고
	myFlowLayoutPanelRightHandSide.Controls.Clear()
	Dim sDatas As String = Nothing
	'' 전역변수에 현재선택된 탭의 제목이 무엇인지 담아주고
	'' 즉 어떤 페이지가 작동인지 상황을 유지하기 위한 
	sCurrentTabPage = TOPIC_LIST.Split(",")(iIndex)
	'' 그리고 어떤 페이지인지에 따라서 
	'' 만들 버튼을 다르게 하다
	Select Case sCurrentTabPage
		Case "Application"
			'' 문자열로 버튼의 캡션이 될 내용을 작성
			'' 실은 이렇게 작성하는 것은 문제가 있고,
			'' 다음 화일에서 다른 방법을 살펴보도록 한다
			sDatas = "1)교차되는 범위 접근하기|Intersect," &
					  "2)떨어진 범위를 한꺼번에 접근하기|Union"


		Case "Range"
			sDatas = "1)범위의 주변범위를 모두 접근|CurrentRegion," &
					 "2)범위의 마지막셀에 접근|End," &
					 "3)범위에서 이동된 범위에 접근|Offset," &
					 "4)범위에서 확장된 범위에 접근|Resize," &
					 "5)범위에서 특정한 값이 있는 범위에 접근|SpecialCells"

		Case "Shape"
			sDatas = "1)도형만들기|AddShape," &
					 "2)양식콘트롤만들기|AddFormControl"
		Case "PivotTable"
			sDatas = "1)피벗케시만들기|Create," &
				   "2)피벗테이블만들기|CreatePivotTable"
	End Select
	'' 각 페이지에 따라서 다른게 작성된 문자열정보를 매개변수로
	'' 버튼을 만드는 프로시져를 호출한다
	createButton(sDatas)

End Sub
'' 버튼을 만드는 프로시져
'' 이런 내용도 다음 화일에서는 개선될 것이니...
'' 각자 좋은 방법이 없을까..문제의식을 갖고 다음 화일을 기다리시는 것이 좋겠다
Private Sub createButton(sDatas As String)
	If sDatas Is Nothing Then Return
	'' 보내온 문자열을 Split 메소드로 배열화하여
	'' 순환하면서 버튼을 생성하여 패널의 Controls에 추가 한다
	For Each sX As String In sDatas.Split(",")
		Dim oBtn As Button = New System.Windows.Forms.Button
		oBtn.AutoSize = True
		oBtn.Text = sX.Split(")")(1).Trim
		oBtn.Cursor = Cursors.Hand
		oBtn.Tag = Val(sX.Split(")")(0))
		'' 버튼을 크릭하면 발생하는 이벤트프로시져는 Lambda expresion으로 
		'' Inline으로 작성했다..
		'' 간단한 것이니까, 나중에 작업내용이 길어지면,
		'' 별도의 프로시져로 분리하게 되겠지..
		AddHandler oBtn.Click, Sub()
								   MsgBox("다음 화일에서..")
							   End Sub
		'' 패널의 콘트롤에 추가하고..
		myFlowLayoutPanelRightHandSide.Controls.Add(oBtn)
	Next
End Sub

아래 화일에 위의 내용을 실행시켜보면서
문제의식을 갖여 보시기를...

***[LOG-IN]***