PROGRAMMING WORKSHOP

VSTO|
기존통합문서VBA+VSTO

WPF화일을 뜻한 바가 있어서 열심히 하여 올리지만..
VSTO쪽에 관심이 더더욱 많은 것 같다
WPF조금 쉬면서 VSTO쪽을 신경을 써보도록 하자
질문이 오는 쪽 불부터 꺼야 하는 것이 원칙인지라..
실은 WPF이던 Window폼이던 모두 나중에는 VSTO와 연결이 되는 것들이지만..
순서를 조금 조정하자..VBA와 VSTO쪽으로..질문을 소화시키도록 하자

이미 UserForm등을 통하여 정성을 들여서 VBA프로그래밍을
공을 들여서 만들어 놓았는데
VSTO 형식으로 바꾸면서 어떻게 기존의 코드나 UserForm을
사용하고 싶다
리본메뉴시스템으로 VBA코드를 호출하고도 싶다..
리본메뉴시트멤을 손으로 만들려면 ZIP화일로 만들어서
풀어서 XML문을 열어서 편집하고 어쩌구 하는 일이 그렇게
쉽지가 않다
VisualStudio에 VSTO를 활용하면 간단하게 된다던데..
어떻게 해야 하나??
아주 간단하다
엑셀화일을 하나 쌤플로 아래와 같이 하나 만들자
그림과 같이 간단하게 대화상자를 하나 만들고



버튼을 크릭하면 아래와 같은 ThisWorkBook모듈에 있는 지극히 바보같은 프로시져를
호출한다 치고..

Function sampleCall()
Dim sX As String
Select Case Now
   Case Is <= TimeValue("12:00:00")
      sX = "Good Morning!!"
   Case Is <= TimeValue("18:00:00")
      sX = "Good Afternoon!!"
   Case Is <= TimeValue("21:00:00")
      sX = "Good Evening!!"
   Case Else
      sX = "Good Night!!"
End Select
sampleCall = sX & " " & Format(Now, "YY-MM-DD HH MM SS")

End Function
Sub loadForm()
UserForm1.Show
End Sub

코드가 복잡하던 간단하던 VSTO와 연결하는것은 똑 같은 요령이다
우선 리본을 하나 만들어서 버튼을 넣고
버튼을 크릭하면 VBA의 프로시져를 호출하는 것을 해본후
VBA에서 VSTO 프로시져를 호출하는 것을 해보자



그림과 같이 VBA가 들어있는 xlsm화일을 선택하여프로젝트에
사용할것을 지정한다



리본의 버튼을 도구상자에서 삽입하여 만든후 더블크릭하여
이벤트프로시져에 아래와 같이 작성한다

Private Sub Button1_Click(ByVal sender As System.Object, _
   ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
      Handles Button1.Click
   Globals.ThisWorkbook.Application.Run("ThisWorkBook.loadForm")
End Sub

위에서
Application.Run("...") 이라는 구문은 이미 VBA에서 익히 알고 있는
구문이다..이것이 낯섫다면 VBA 기본에 좀더 충실하여야 할 것이다
위에서 ThisWorkBook이 먼저 붙은 것은 Application개체에 접근하기
위한 ThisWorkbook의 속성이니까..그렇게 사용하면 되는 것이다
위에서 Globals라는 개체는 VSTO로 프로젝트가 로딩되면서 자동으로
생성되는 프로젝트 최상위 개체라고 생각하시면 된다
이것을 앞에 놓고 그 다음은 VBA코딩과 같다고 생각하시면 되는 것이다
"ThisWorkBook.loadForm"은 ThisWorkBook모듈에 VBA로 작성되어있는
프로시져 이름이다
VBA의 어떤 프로시져이름도 이렇게 호출하면 리본에서 실행되는 것이다

와..그렇게 쉽나????
맞다 쉽지만..얻어지는 효과는 완전히 아마츄어에서 프로로 등극하는 셈이다

아래 화일로 위의 내용을 그대로 진행해보시고..

***[LOG-IN]***

그렇게 까다로운 리본을 간단하게 사용하게 된 셈이다

이제 리본에 VBA프로시져연결은 누워서 떡먹기가 되었고
열심히 VBA로 작성한 많은 프로시져를
VSTO로 옮기고 감추는 것이 일이다
VSTO로 옮기는 이유는 가장 첫째가 보안상의 문제를 풀어주기 때문이다
열심히 부서별로 소루션을 만들었는데..
이것은 작성한 개인의 자산,부서의 자산인 동시에 회사의 자산이다..
아무놈이나 집에 갈때 갖여 가서 회사를 옮기면서 그냥 갖여가면
아까운 자산은 그냥 남의 회사로 홀라당 넘어간다
엑셀 VBA의 장점이자 단점이기도 하다
그래서 VSTO의 파워가 필요하게 되는 셈이다

VBA라는 언어와 VB의 언어가 같은 뿌리에서 나오기는 했지만
VB는 계속 발전하고..VBA는 과거의 VB상태로 그대로 있었던지라
조금 VB쪽 언어에 관심을 갖여야 하는 시점이 되기도 한다
그런데 VB는 뭐구..VB.Net은 뭐냐??라고 한다면
VB.Net은 .NetFrameWork를 기반으로 사용하는 VB라는 것이지
별 특별한것은 없다는 점 아시고

앞으로 VB라고 부르는 것은 모두 VB.Net을 말하는 것이라는 점
VSTO가 .NetFrameWork를 기반으로 하는것이니..당연하다

VSTO프로젝트의 프로젝트창(소루션창)에 나타나는

Sheet1
Sheet2
Sheet3
...
ThisWorkBook

의 각개체를 오른쪽마우스로 크릭하여 View Desinger메뉴를 크릭하여



그림과 같이 나타나는 속성창에서
EnableVbaCaller=True
로 해주면 알림창이 한번 나타난다
이것은 디버깅모드로 실행을 할때(F5키 실행)
열리는 통합문서(포함된 통합문서)의
VBA코드를 수정하거나 변경하거나 추가하는 편집내용이
모두 프로젝트에 있던 해당통합문서에 덮어씌워지기가
된다는 것을 이야기하는 것이다
즉 프로젝트를 디버깅모드로 실행하면서 VBA편집기의
내용을 편집하는 것이 프로젝트에 모두 반영이 된다는 이야기다

확인버튼 눌러 주면 되고..
그런후 F5키로 디버깅런을 실행하여
열리는 통합문서의 VBA편집기에 가보면
아래와 같이 각시트와 ThisWorkBook통합문서 모듈시트의 선언부에
하나씩 아래와 같은 것이 자동으로 만들어졌다

Property Get CallVSTOAssembly() As VSTO_VBA.Sheet1
   Set CallVSTOAssembly = GetManagedClass(Me)
End Property

Property Get CallVSTOAssembly() As VSTO_VBA.Sheet2
   Set CallVSTOAssembly = GetManagedClass(Me)
End Property

Property Get CallVSTOAssembly() As VSTO_VBA.heet3
   Set CallVSTOAssembly = GetManagedClass(Me)
End Property

Property Get CallVSTOAssembly() As VSTO_VBA.ThisWorkbook
   Set CallVSTOAssembly = GetManagedClass(Me)
End Property

물론 위와 같이 죄다 할 필요는 없고 모듈이 있는 개체의
모듈시트만 하면 될 것이다
아무튼 Sheet1,Sheet2라는 것은 모두 하나의 개체이니까..
필요하면 모두 만들고..

CallVSTOAssembly속성의 Return값은 각각
해당 VSTO모듈시트개체를 얻어 오는 것이고
이 모듈시트개체내의 함수나 프로시져명을 붙이면 VSTO에서
작성된 자원에 VBA로 접근할 수 있는 것이다
다시 정리하면
VBA의 자원은 Application.Run("VBA의 프로시져명")으로
VSTO에서 접근할 수 있고
VSTO의 자원은 위와 같이 만들어지는 속성을 통하여 접근할수 있다는
이야기인 것이다
물론 위와 같은 내용은 통합문서단위의 프로젝트에 대한 이야기이고
추가기능(Add-In)에서는 필요없는 것이라는 점..아시고!!!

아무튼 이렇게 하여 CallVSTOAssembly라는 속성을 얻게 되었고
이것은 .NetFrameWork상의 VSTO에 접근할수 있는 속성을 얻게 된것이다



이제 위에 첨부한 VBA내용이 작성된 화일의 VBA내용을
아래와 같이 VSTO부분으로 옮기고 편집하여
다른 사람들이 VBA내용에서 회사의 로직을 볼수 없는 상태로
해보도록 하자

***[LOG-IN]***

위와 같이 하여 VBA와 VSTO를 상호 참조하는 것을 해보았지만
VBA로 작성되고 UserForm을 정교하게 잘 만들어 놓아서 버리기 아깝다면
위와 같이 하여 사용하여도 좋겠지만..
사용하던 VBA화일이 없다면 그냥 VSTO로 전부 작성하는 것이
바람직 하다는 점..잊지 마시고..기존의 VBA 자원을 최대한 그대로
사용하고 싶을때만..