안녕하세요. 엔지엠소프트웨어입니다. 오늘부터 몇차례에 걸쳐서 엑셀 커스텀 액션을 만드는 방법에 대해 알아보도록 하겠습니다. 엑셀, 워드, 파워포인트와 같은 Office 제품들은 윈도우와 호환성이 높고 인터페이스가 잘 정리되어 있어 누구나 쉽게 개발할 수 있다는 장점이 있습니다. 물론, 개발자들에게 그렇다는거죠^^; 그래서 초보자(?)도 쉽게 엑셀을 비롯한 Office 제품들과 인터페이스를 하고 간단하게 처리할 수 있는 방법에 대해 알려드리겠습니다. 우선, 이 내용을 따라하려면 커스텀 액션 제작 내용을 미리 학습하면 좋습니다.
[ 커스텀 액션 강좌 ]
우선, 관리자에게 커스텀 개발 모듈을 신청(제품 라이센스를 보유한 경우)해야 합니다
[ 커스텀 모듈 신청 ]
관리자로부터 커스텀 모듈을 받았으면 아래 폴더에 복사해둡니다.
C:\Users\<사용자 계정>\Documents\NGM6\ToolExtension
개발 도구는 Visual Studio 2019 Cummunity를 설치하면 됩니다. 비주얼 스튜디오를 설치한 후 아래 그림과 같이 워크로드에서 ".NET 데스크톱 개발"을 체크하고 추가 설치하셔야 합니다. 이외에 추가적으로 필요한 워크로드가 있다면~ 체크하고 같이 설치해주세요. 대부분 이 글을 보시는 분들은 개발자가 아닌 일반인이기에 추가적으로 더 해야 하는건 없을겁니다.
비주얼 스튜디오를 실행한 후 아래 그림과 같이 프로젝트를 생성합니다. "클래스 라이브러리" 선택 후 "다음"을 클릭하세요.
아래 내용을 참고해서 프로젝트 구성을 설정하세요.
- "CustomExcelExampleModule" 이름을 설정하세요. 엔지엠에 커스텀 모듈을 설치하려면 프로젝트의 이름은 항상 Custom으로 시작해야 합니다.
- ".NET Framework 4.6.1" 프레임워크를 선택하세요.
- "만들기"를 클릭하세요.
①"Class1.cs"에서 우클릭 후 ②"이름 바꾸기"를 클릭하세요.
Class1.cs를 ExcelModel.cs로 변경하고, 아래 메시지창에서 "예"를 클릭하세요.
ExcelModel.cs를 더블클릭하면 코드 보기로 전환됩니다. 기본 코드를 삭제하고, 아래 코드를 붙여넣기 하세요.
using System; using System.Reflection; using System.Windows.Forms; using Excel = Microsoft.Office.Interop.Excel; namespace CustomExcelExampleModule { public class ExcelModel : NGM.Models.Interface.BaseCustomToolModel { public override string DisplayCategory => "엑셀 예제"; public override string DisplayName => "테스트 1"; public override void Execute() { Excel.Application oXL; Excel._Workbook oWB; Excel._Worksheet oSheet; Excel.Range oRng; try { //Excel을 시작하고 Application 개체를 가져옵니다. oXL = new Excel.Application(); oXL.Visible = true; //새 통합 문서를 받으십시오. oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value)); oSheet = (Excel._Worksheet)oWB.ActiveSheet; //셀 단위로 표 머리글을 추가합니다. oSheet.Cells[1, 1] = "First Name"; oSheet.Cells[1, 2] = "Last Name"; oSheet.Cells[1, 3] = "Full Name"; oSheet.Cells[1, 4] = "Salary"; //A1 : D1 형식을 굵게, 세로 정렬 = 가운데로 지정합니다. oSheet.get_Range("A1", "D1").Font.Bold = true; oSheet.get_Range("A1", "D1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; //한 번에 여러 값에 대한 배열을 만듭니다. string[,] saNames = new string[5, 2]; saNames[0, 0] = "John"; saNames[0, 1] = "Smith"; saNames[1, 0] = "Tom"; saNames[1, 1] = "Brown"; saNames[2, 0] = "Sue"; saNames[2, 1] = "Thomas"; saNames[3, 0] = "Jane"; saNames[3, 1] = "Jones"; saNames[4, 0] = "Adam"; saNames[4, 1] = "Johnson"; //A2 : B6을 값 배열 (이름 및 성)로 채 웁니다. oSheet.get_Range("A2", "B6").Value2 = saNames; //C2 : C6을 상대 공식 (= A2 & ""& B2)으로 채 웁니다. oRng = oSheet.get_Range("C2", "C6"); oRng.Formula = "=A2 & \" \" & B2"; //D2 : D6을 수식 (= RAND () * 100000)으로 채우고 형식을 적용합니다. oRng = oSheet.get_Range("D2", "D6"); oRng.Formula = "=RAND()*100000"; oRng.NumberFormat = "$0.00"; //자동 맞춤 열 A : D. oRng = oSheet.get_Range("A1", "D1"); oRng.EntireColumn.AutoFit(); //분기 별 판매 데이터에 대해 가변 개수의 열을 조작합니다. DisplayQuarterlySales(oSheet); //Excel이 표시되는지 확인하고 사용자가 Microsoft Excel의 수명을 제어 할 수 있도록합니다. oXL.Visible = true; oXL.UserControl = true; } catch (Exception theException) { String errorMessage; errorMessage = "Error: "; errorMessage = String.Concat(errorMessage, theException.Message); errorMessage = String.Concat(errorMessage, " Line: "); errorMessage = String.Concat(errorMessage, theException.Source); MessageBox.Show(errorMessage, "Error"); } } private void DisplayQuarterlySales(Excel._Worksheet oWS) { Excel._Workbook oWB; Excel.Series oSeries; Excel.Range oResizeRange; Excel._Chart oChart; String sMsg; int iNumQtrs; //데이터를 표시 할 분기 수를 결정합니다. for (iNumQtrs = 4; iNumQtrs >= 2; iNumQtrs--) { sMsg = "Enter sales data for "; sMsg = String.Concat(sMsg, iNumQtrs); sMsg = String.Concat(sMsg, " quarter(s)?"); DialogResult iRet = MessageBox.Show(sMsg, "Quarterly Sales?", MessageBoxButtons.YesNo); if (iRet == DialogResult.Yes) break; } sMsg = "Displaying data for "; sMsg = String.Concat(sMsg, iNumQtrs); sMsg = String.Concat(sMsg, " quarter(s)."); MessageBox.Show(sMsg, "Quarterly Sales"); //E1부터 선택한 열 수에 대한 헤더를 채 웁니다. oResizeRange = oWS.get_Range("E1", "E1").get_Resize(Missing.Value, iNumQtrs); oResizeRange.Formula = "=\"Q\" & COLUMN()-4 & CHAR(10) & \"Sales\""; //머리글의 방향 및 WrapText 속성을 변경합니다. oResizeRange.Orientation = 38; oResizeRange.WrapText = true; //헤더의 내부 색상을 채 웁니다. oResizeRange.Interior.ColorIndex = 36; //열을 수식으로 채우고 숫자 형식을 적용합니다. oResizeRange = oWS.get_Range("E2", "E6").get_Resize(Missing.Value, iNumQtrs); oResizeRange.Formula = "=RAND()*100"; oResizeRange.NumberFormat = "$0.00"; //판매 데이터 및 헤더에 테두리를 적용합니다. oResizeRange = oWS.get_Range("E1", "E6").get_Resize(Missing.Value, iNumQtrs); oResizeRange.Borders.Weight = Excel.XlBorderWeight.xlThin; //판매 데이터에 대한 합계 수식을 추가하고 테두리를 적용합니다. oResizeRange = oWS.get_Range("E8", "E8").get_Resize(Missing.Value, iNumQtrs); oResizeRange.Formula = "=SUM(E2:E6)"; oResizeRange.Borders.get_Item(Excel.XlBordersIndex.xlEdgeBottom).LineStyle = Excel.XlLineStyle.xlDouble; oResizeRange.Borders.get_Item(Excel.XlBordersIndex.xlEdgeBottom).Weight = Excel.XlBorderWeight.xlThick; //선택한 데이터에 대한 차트를 추가합니다. oWB = (Excel._Workbook)oWS.Parent; oChart = (Excel._Chart)oWB.Charts.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value); //ChartWizard를 사용하여 선택한 데이터에서 새 차트를 만듭니다. oResizeRange = oWS.get_Range("E2:E6", Missing.Value).get_Resize( Missing.Value, iNumQtrs); oChart.ChartWizard(oResizeRange, Excel.XlChartType.xl3DColumn, Missing.Value, Excel.XlRowCol.xlColumns, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); oSeries = (Excel.Series)oChart.SeriesCollection(1); oSeries.XValues = oWS.get_Range("A2", "A6"); for (int iRet = 1; iRet <= iNumQtrs; iRet++) { oSeries = (Excel.Series)oChart.SeriesCollection(iRet); String seriesName; seriesName = "=\"Q"; seriesName = String.Concat(seriesName, iRet); seriesName = String.Concat(seriesName, "\""); oSeries.Name = seriesName; } oChart.Location(Excel.XlChartLocation.xlLocationAsObject, oWS.Name); //데이터를 덮지 않도록 차트를 이동하십시오. oResizeRange = (Excel.Range)oWS.Rows.get_Item(10, Missing.Value); oWS.Shapes.Item("Chart 1").Top = (float)(double)oResizeRange.Top; oResizeRange = (Excel.Range)oWS.Columns.get_Item(2, Missing.Value); oWS.Shapes.Item("Chart 1").Left = (float)(double)oResizeRange.Left; } } }
이제 참조를 추가해야 합니다. 아래 그림과 같이 참조에서 우클릭 후 "참조 추가"를 클릭하세요.
좌측의 COM을 클릭하고, "Microsoft Excel 16.0 Object Library"에 체크하고 확인을 누르세요. 라이브러리는 사용자 컴퓨터에 설치된 Office에 따라 버전은 다를 수 있습니다.
다시 참조 추가를 클릭한 후 찾아보기를 클릭하세요. 관리자에게 받은 Extensions.dll을 선택하고, 확인을 클릭하세요. Extensions.dll은 아래 폴더에 있습니다.
C:\Users\<사용자 계정>\Documents\NGM6\ToolExtension
빌드 옵션을 Release로 변경하세요.
아래 그림을 참고해서 빌드(컴파일) 하세요. 하단의 로그에 빌드 성공 메시지가 표시됩니다.
프로젝트에서 우클릭 후 빌드 선택
컴파일된 모듈을 가져오기 위해 아래 그림과 같이 처리합니다. 프로젝트에서 우클릭 후 "파일 탐색기에서 폴더 열기"를 선택하세요. 그리고, "bin/release" 폴더에 "CustomExcelExampleModule.dll"을 복사하세요.
복사한 모듈을 아래 폴더에 복사해줍니다.
C:\Users\<사용자 계정>\Documents\NGM6\ToolExtension
이제 엔지엠 에디터를 실행하세요. 그리고, 새 스크립트에 커스텀 모듈 액션을 추가하세요.
실행 해볼까요? 여러분도 이미 만들어진 엑셀 설정대로 동작할겁니다.
여기까지 잘 되시죠? 다음 시간에는 엑셀을 자동화 할 수 있는 코드에 대해 설명하도록 하겠습니다. 또한, 커스텀 액션에서 변수로 데이타를 주거나 받을 수 있기 때문에 다이나믹하게 처리할 수 있는 방법도 같이 알아보도록 하겠습니다. 이 예제를 실습하다가 문제가 있다면 댓글로 남겨주세요.
개발자에게 후원하기
추천, 구독, 홍보 꼭~ 부탁드립니다.
여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~
감사합니다~
댓글