PROGRAMMING WORKSHOP

VB.Net |
DataGridView+Excel+Word+Chart

전,전 페이지에서 DataGridView의 정보를 엑셀에 옮기고 저장하는 작업을 하였었다
그런데 중요한 것이 있다
VBA에서 엑셀작업할때야 같은 프로그램에서 같은 모듈속에서
작업을 한 것이라서 별문제가 없지만..
.Net FrameWork에서 다른 동네 Com시스템의 라이브러리를 참조하여
작업을 한후에는 쓰레기가 CPU에 쓰레기로 남아있다
아래의 그림과 같이 전페이지의 내용을 실행시키면서
엑셀화일 저장 버튼을 계속 크릭하면서 엑셀을 생성하면서 작업을 하고
또하고, 또하면 하는 만큼 그림같이 쓰레기가 쌓여간다



물론 윈도우폼을 닫아 버리면 모두 해제가 되지만
디버그중단으로 닫으면 남아있는다
이말은 어떤 윈도우프로그램을 엑셀을 활용하는 것을 만들어서
배포했을때..사용자가 수도 없이 엑셀을 열었다, 닫었다 하면서
작업을 할때 작업하는 동안 쓰레기가 계속 쌓여 간다는 것이다

어떤 문제가 생기냐하면..어렵쇼..갑자기 속도가 왜
더뎌지지...!@# 라는 말을 쭝얼거리게 되는 것이다

아래와 같이 실행후 쓰레기 치우는 ,해제하는 작업을 해주어야 한다

Private Sub releaseObject(ByVal obj As Object)
    Try
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        obj = Nothing
    Catch ex As Exception
        obj = Nothing
    Finally
        GC.Collect()
    End Try
End Sub

ReleaseComObject 라는 메소드를 사용한다
Release COM Object, COM개체를 해제하라!! 라는 소리
엑셀프로그램은 .Net FrameWork가 아니고 COM시스템의 라이브러리이다
즉 .Net FrameWork를 기반으로 만든 윈도우폼에서
COM 라이브러리를 불러서 사용하였으니까..
.Net FrameWork에서 특별히 작업을 좀더 해주어야 하는 것이다

사람 사는 세상과 똑같다!!!
자기네 회사에서 자원을 활용하면..그냥 스스로 알아서 하겠지만
남의 회사에서 뭔가 사람을 빌려오던, 장비를 빌려오던
빌려다 썼으면 조금더 절차가 필요한 것이나 마찬가지다
이번 페이지에서는 엑셀과 DataGridView를 좀더 작업을 하면서
위의 프로시져를 활용하여 깔끔하게 청소까지 하도록 하자
이 작업은 엑셀뿐만 아니라, COM라이브러리를 사용하면 처리하여야 한다

엑셀과 워드작업을 해보고 저장후..
COM개체를 해제하는 것을 해보도록 하자
다른 것을 하기전에 중요한 사항이니까..
그냥 위의 함수를 잘 보관하고 사용하면 된다

1)DataGridView에 데이타를 만들어 채운다
2)Excel에 옮겨서 테이블을 만들고 이것을 쏘스로 Chart를 그린다
3)Chart를 그림화일로 바탕화면에 저장한다
4)Excel은 임무 끝이다..닫고..해제하고
5)엑셀의 도움으로 챠트를 그리고 챠트를 얻은 것이다
6)이 챠트를 윈도우폼의 PictureBox콘트롤에 불러 들인다
요기까지 해보자
아래의 그림과 같이 DataGridView를 폼이 로딩될때
데이타를 만들어 넣고..
여러번 해보아서 이제 감이 잡히게 되셨을 것이다..
좀더 자유롭고,편하게 할때까지 계속 한다



아래와 같은 코드는 VBA에서 챠트그리는 것과 똑같다..
엑셀프로그래머가 신나는 순간이다..
.Net FrameWork에 여러분의 갈고 딱은 것을 접목시키는 순간이니까!!

'엑셀라이브러리 네임스페이스 선언하고
Imports XL = Microsoft.Office.Interop.Excel

Public Class Form1
' 그림의 버튼 크릭하면
Private Sub Button1_Click(ByVal sender As System.Object, _
			 ByVal e As System.EventArgs) Handles Button1.Click
			 
'엑셀개체생성
Dim oXL As New XL.Application
Dim oBook As XL.Workbook = oXL.Workbooks.Add
Dim oSht As XL.Worksheet = oBook.Worksheets(1)
XL.Visible = True

Dim iRow As Integer = 0
'윈도우의 DataGridView의 각행을 순환하면서
With oSht.Range("A1")
    .Offset(iRow, 1).Resize(, 4).Value = New String() {"동부", "서부", "남부", "북부"}
    For Each oRow As DataGridViewRow In DataGridView1.Rows
        iRow += 1
        .Offset(iRow).Value = oRow.Cells(0).Value
        .Offset(iRow, 1).Value = oRow.Cells(1).Value
        .Offset(iRow, 2).Value = oRow.Cells(2).Value
        .Offset(iRow, 3).Value = oRow.Cells(3).Value
        .Offset(iRow, 4).Value = oRow.Cells(4).Value
    Next
End With
' 엑셀 테이블완료
' 챠트그리기

Dim chartPage As XL.Chart
Dim xlCharts As XL.ChartObjects
Dim myChart As XL.ChartObject
Dim chartRange As XL.Range

xlCharts = oSht.ChartObjects
myChart = xlCharts.Add(10, 80, 300, 250)
chartPage = myChart.Chart
chartRange = oSht.Range("A1").Resize(5, 5)
chartPage.SetSourceData(Source:=chartRange)
chartPage.ChartType = Microsoft.Office.Interop.Excel.XlChartType.xlColumnClustered

'챠트그림화일로 바탕화면에 보내기
oSht.ChartObjects(1).chart.Export(FileName:= _
My.Computer.FileSystem.SpecialDirectories.Desktop & "\XLChart.jpg")

'엑셀임무끝!!  저장하지 않고 닫기
oBook.Close(False)
oXL.Quit()

' 이부분이 맨위의 프로시져를 호출하는 부분이다
' 이곳에서 개체 메모리상에서 완벽해제한다

releaseObject(oXL)
releaseObject(oBook)
releaseObject(oSht)

...
...
...
...
End Sub

...
...
End Class

챠트의 서식은 엑셀에서 얼마나 챠트를 많이 다루어왔는지
내공이 쌓인 만큼 멋있게 표현될 것이다
아래의 그림과 같이 그림화일이 윈도우폼으로 쏙 불러 들여 오면
작업 끝이다..



***[LOG-IN]***

이제 위의 내용을 다시 워드 문서에 옮겨보도록 하자
워드 또한 엑셀과 같이 라이브러리를 참조 시켜야 한다
워드문서에 챠트와 테이블을 같이 옮기도록 한다
워드에 옮긴 내용은 아래의 그림과 같다



VBA로 Excel이나 Word를 다룰줄 안다면
윈도우폼으로 사무자동화가 좀더 가치있게 구성될 수 있게 되는 셈이다
여기에 Access DB를 걸던가, SQL DB를 걸던가 하면
좀더 완벽한 것이다

화일을 실행하다가 에러가 나면 ..찬찬히 살피면서 에러를
해제 해나가는 내공을 키우시기를..
VB.Net에서 다른 라이브러리 참조하는 일이 다반사이니
버전의 참조라이브러리 버전의 다름으로 인한 것이 대부분이니
참조라이브러리를 차근 차근 따져서 현재의 여러분환경이 갖고 있는
같은 라이브러리의 다른 버전을 참조시키면 된다

워드에서는 그림같은 것을 삽입할때..위치잡는 것이 엑셀과는
좀 다르고..
AddPicture메소드에서 매개변수가 약간 다름을 알아야 한다
같은 Shape개체의 메소드라도 워드와 파워포인트와 엑셀등에서 약간씩
다른 것이 있을때가 있다
위의 그림에서 그림을 삽입할때 워드에서는 위치잡기가 헷갈린다
엑셀에서는
oShape.Top=Range("B10").Top
등과 같이 하면 되는데
워드에서는 Range("B10").Top같이 위치를 가름할 개체가 헷갈린다
즉 테이블이 끝나는 위치의 값을 알려주는 속성이 없다
이 부분을 관심갖고 보시면 좋겠다

***[LOG-IN]***

챠트를 구현하는 개체가 윈도우폼에도 있지만
엑셀이라는 것이 잘 그려주니 불러서 일을 시키면 좋다
특히 위에서 엑셀프로그램을 열면서 Visible=True로 하였으나
(시각적으로 보여드리기 위하여 True로 하였었다)
이것을 False로 하여 엑셀이 열리고 닫히고 하는 것을 볼 필요는
없을 것이다