다음을 통해 공유


연습: 런타임에 응용 프로그램 수준 프로젝트의 워크시트에 컨트롤 추가

업데이트: 2011년 4월

Excel 추가 기능을 사용하여 열려 있는 워크시트에 컨트롤을 추가할 수 있습니다. 이 연습에서는 리본 메뉴를 사용하여 사용자가 워크시트에 Button, NamedRangeListObject를 추가할 수 있게 하는 방법을 보여 줍니다. 자세한 내용은 런타임에 Office 문서에 컨트롤 추가를 참조하십시오.

적용 대상: 이 항목의 정보는 Excel 2007 및 Excel 2010의 응용 프로그램 수준 프로젝트에 적용됩니다. 자세한 내용은 Office 응용 프로그램 및 프로젝트 형식에 따라 사용 가능한 기능을 참조하십시오.

이 연습에서는 다음 작업을 수행합니다.

  • 워크시트에 컨트롤을 추가하기 위한 UI(사용자 인터페이스) 제공

  • 워크시트에 컨트롤 추가

  • 워크시트에서 컨트롤 제거

참고

다음 지침처럼 컴퓨터에서 Visual Studio 사용자 인터페이스 요소 일부에 대한 이름이나 위치를 다르게 표시할 수 있습니다. 이러한 요소는 사용하는 Visual Studio 버전 및 설정에 따라 결정됩니다. 자세한 내용은 Visual Studio 설정을 참조하십시오.

사전 요구 사항

이 연습을 완료하려면 다음 구성 요소가 필요합니다.

-

Microsoft Office 개발자 도구를 포함하는 Visual Studio 2010 버전입니다. 자세한 내용은 [Office 솔루션을 개발할 수 있도록 컴퓨터 구성](bb398242\(v=vs.100\).md)을 참조하십시오.
  • Microsoft Office Excel 2007 또는 Excel 2010

새 Excel 추가 기능 프로젝트 만들기

우선 Excel 추가 기능 프로젝트를 만들어야 합니다.

새 Excel 추가 기능 프로젝트를 만들려면

  1. Visual Studio에서 ExcelDynamicControls라는 Excel 추가 기능 프로젝트를 만듭니다. 자세한 내용은 방법: Visual Studio에서 Office 프로젝트 만들기를 참조하십시오.

  2. 프로젝트가 .NET Framework 4를 대상으로 하는 경우 Microsoft.Office.Tools.Excel.v4.0.Utilities.dll 어셈블리에 대한 참조를 추가합니다. 이 참조는 이 연습의 뒷부분에서 워크시트에 Windows Forms 컨트롤을 프로그래밍 방식으로 추가하는 데 필요합니다.

워크시트에 컨트롤을 추가하기 위한 UI 제공

Excel 리본 메뉴에 사용자 지정 탭을 추가합니다. 사용자는 탭의 확인란을 선택하여 워크시트에 컨트롤을 추가할 수 있습니다.

워크시트에 컨트롤을 추가하기 위한 UI를 제공하려면

  1. 프로젝트 메뉴에서 새 항목 추가를 클릭합니다.

  2. 새 항목 추가 대화 상자에서 **리본(비주얼 디자이너)**을 선택한 다음 추가를 클릭합니다.

    Ribbon1.cs 또는 Ribbon1.vb 파일이 리본 디자이너에서 열리고 기본 탭 및 그룹이 표시됩니다.

  3. 도구 상자Office 리본 컨트롤 탭에 있는 CheckBox 컨트롤을 group1로 끌어 옵니다.

  4. CheckBox1을 클릭하여 선택합니다.

  5. 속성 창에서 다음과 같이 속성을 변경합니다.

    Property

    Name

    Button

    레이블

    Button

  6. group1에 두 번째 확인란을 추가하고 다음 속성을 변경합니다.

    Property

    Name

    NamedRange

    레이블

    NamedRange

  7. group1에 세 번째 확인란을 추가하고 다음 속성을 변경합니다.

    Property

    Name

    ListObject

    레이블

    ListObject

워크시트에 컨트롤 추가

관리되는 컨트롤은 호스트 항목에만 추가할 수 있으며 이때 호스트 항목은 컨테이너로 사용됩니다. 추가 기능 프로젝트는 열려 있는 통합 문서에 대해 작동하므로 추가 기능에서는 컨트롤을 추가하기 전에 워크시트를 호스트 항목으로 변환하거나 기존 호스트 항목을 가져옵니다. 각 컨트롤의 클릭 이벤트 처리기에 코드를 추가하여 열려 있는 워크시트를 기반으로 하는 Worksheet 호스트 항목을 생성합니다. 그런 다음 워크시트의 현재 선택 영역에 Button, NamedRangeListObject를 추가합니다.

워크시트에 컨트롤을 추가하려면

  1. 리본 디자이너에서 Button을 두 번 클릭합니다.

    Button 확인란의 Click 이벤트 처리기가 코드 편집기에서 열립니다.

  2. Button_Click 이벤트 처리기를 다음 코드로 바꿉니다.

    이 코드에서는 GetVstoObject 메서드를 사용하여 통합 문서의 첫 번째 워크시트를 나타내는 호스트 항목을 가져온 다음 현재 선택되어 있는 셀에 Button 컨트롤을 추가합니다.

    Private Sub Button_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles Button.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim buttonName As String = "MyButton"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                Dim button As New Microsoft.Office.Tools.Excel.Controls.Button()
                worksheet.Controls.AddControl(button, selection, buttonName)
            End If
        Else
            worksheet.Controls.Remove(buttonName)
        End If
    End Sub
    
    private void Button_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string buttonName = "MyButton";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                Microsoft.Office.Tools.Excel.Controls.Button button =
                    new Microsoft.Office.Tools.Excel.Controls.Button();
                worksheet.Controls.AddControl(button, selection, buttonName);
            }
        }
        else
        {
            worksheet.Controls.Remove(buttonName);
        }
    }
    
  3. 솔루션 탐색기에서 Ribbon1.cs 또는 Ribbon1.vb를 선택합니다.

  4. 보기 메뉴에서 디자이너를 클릭합니다.

  5. 리본 디자이너에서 NamedRange를 두 번 클릭합니다.

  6. NamedRange_Click 이벤트 처리기를 다음 코드로 바꿉니다.

    이 코드에서는 GetVstoObject 메서드를 사용하여 통합 문서의 첫 번째 워크시트를 나타내는 호스트 항목을 가져온 다음 현재 선택되어 있는 셀에 대한 NamedRange 컨트롤을 정의합니다.

    Private Sub NamedRange_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles NamedRange.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim rangeName As String = "MyNamedRange"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                Dim namedRange As NamedRange = _
                    worksheet.Controls.AddNamedRange(selection, rangeName)
            End If
        Else
            worksheet.Controls.Remove(rangeName)
        End If
    End Sub
    
    private void NamedRange_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string Name = "MyNamedRange";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                worksheet.Controls.AddNamedRange(selection, Name);
            }
        }
        else
        {
            worksheet.Controls.Remove(Name);
        }
    }
    
  7. 리본 디자이너에서 ListObject를 두 번 클릭합니다.

  8. ListObject_Click 이벤트 처리기를 다음 코드로 바꿉니다.

    이 코드에서는 GetVstoObject 메서드를 사용하여 통합 문서의 첫 번째 워크시트를 나타내는 호스트 항목을 가져온 다음 현재 선택되어 있는 셀에 대한 ListObject를 정의합니다.

    Private Sub ListObject_Click(ByVal sender As System.Object, _
        ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) _
            Handles ListObject.Click
    
        Dim NativeWorksheet As Microsoft.Office.Interop.Excel.Worksheet =
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1)
    
        ' Use the following line of code in projects that target the .NET Framework 4.
        Dim worksheet As Microsoft.Office.Tools.Excel.Worksheet =
            Globals.Factory.GetVstoObject(NativeWorksheet)
    
        ' In projects that target the .NET Framework 3.5, use the following line of code.
        ' Dim worksheet = CType(Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets(1),  _
        '    Excel.Worksheet).GetVstoObject()
    
        Dim listObjectName As String = "MyListObject"
    
        If CType(sender, RibbonCheckBox).Checked Then
            Dim selection As Excel.Range = _
                Globals.ThisAddIn.Application.Selection
            If Not (selection Is Nothing) Then
                worksheet.Controls.AddListObject(selection, listObjectName)
            End If
        Else
            worksheet.Controls.Remove(listObjectName)
        End If
    End Sub
    
    private void ListObject_Click(object sender, RibbonControlEventArgs e)
    {
        // Use the following line of code in projects that target the .NET Framework 4.
        Worksheet worksheet = Globals.Factory.GetVstoObject(
            Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // Worksheet worksheet = 
        //     ((Excel.Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]).GetVstoObject();
    
        string listObjectName = "MyListObject";
    
        if (((RibbonCheckBox)sender).Checked)
        {
            Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range;
            if (selection != null)
            {
                worksheet.Controls.AddListObject(selection, listObjectName);
            }
        }
        else
        {
            worksheet.Controls.Remove(listObjectName);
        }
    }
    
  9. 리본 코드 파일의 맨 위에 다음 문을 추가합니다.

    Imports Excel = Microsoft.Office.Interop.Excel
    Imports Microsoft.Office.Tools.Excel
    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Excel = Microsoft.Office.Interop.Excel;
    using Microsoft.Office.Tools.Excel;
    using Microsoft.Office.Tools.Excel.Extensions;
    

워크시트에서 컨트롤 제거

컨트롤은 워크시트가 저장되고 닫힐 때 유지되지 않습니다. 워크시트를 저장하기 전에 생성된 모든 Windows Forms 컨트롤을 프로그래밍 방식으로 제거해야 합니다. 그러지 않으면 통합 문서를 다시 열 때 컨트롤의 윤곽선만 나타납니다. 생성된 호스트 항목의 컨트롤 컬렉션에서 Windows Forms 컨트롤을 제거하는 코드를 WorkbookBeforeSave 이벤트에 추가합니다. 자세한 내용은 Office 문서에서 동적 컨트롤 유지를 참조하십시오.

워크시트에서 컨트롤을 제거하려면

  1. 솔루션 탐색기에서 ThisAddIn.cs 또는 ThisAddIn.vb를 선택합니다.

  2. 보기 메뉴에서 코드를 클릭합니다.

  3. ThisAddIn 클래스에 다음 메서드를 추가합니다. 이 코드에서는 통합 문서의 첫 번째 워크시트를 가져온 다음 HasVstoObject 메서드를 사용하여 해당 워크시트에 생성된 워크시트 개체가 있는지 확인합니다. 그런 다음 생성된 워크시트 개체에 컨트롤이 있으면 해당 워크시트 개체를 가져오고 컨트롤 컬렉션을 반복하여 컨트롤을 제거합니다.

    Sub Application_WorkbookBeforeSave _
        (ByVal workbook As Microsoft.Office.Interop.Excel.Workbook, _
         ByVal SaveAsUI As Boolean, ByRef Cancel As Boolean) _
         Handles Application.WorkbookBeforeSave
    
        Dim worksheet As Excel.Worksheet = workbook.Worksheets(1)
    
        ' Use the following code in projects that target the .NET Framework 4.
        If Globals.Factory.HasVstoObject(worksheet) And
            Globals.Factory.GetVstoObject(worksheet).Controls.Count > 0 Then
            Dim vstoWorksheet As Worksheet = Globals.Factory.GetVstoObject(worksheet)
    
            ' In projects that target the .NET Framework 3.5, use the following code.
            ' If worksheet.HasVstoObject() And worksheet.GetVstoObject().Controls.Count > 0 Then
            ' Dim vstoWorksheet As Worksheet = worksheet.GetVstoObject()
    
            While vstoWorksheet.Controls.Count > 0
                Dim vstoControl As Object = vstoWorksheet.Controls(0)
                vstoWorksheet.Controls.Remove(vstoControl)
            End While
        End If
    End Sub
    
    void Application_WorkbookBeforeSave(Microsoft.Office.Interop.Excel.Workbook workbook, 
        bool SaveAsUI, ref bool Cancel)
    {
        Excel.Worksheet worksheet =
            workbook.Worksheets[1] as Excel.Worksheet;
    
        // Use the following lines of code in projects that target the .NET Framework 4.
        if (Globals.Factory.HasVstoObject(worksheet) && 
            Globals.Factory.GetVstoObject(worksheet).Controls.Count > 0)
        {
            Worksheet vstoWorksheet = Globals.Factory.GetVstoObject(worksheet);
    
        // In projects that target the .NET Framework 3.5, use the following line of code.
        // if (worksheet.HasVstoObject() && worksheet.GetVstoObject().Controls.Count > 0)
        // {
        //     Worksheet vstoWorksheet = worksheet.GetVstoObject();               
    
            while (vstoWorksheet.Controls.Count > 0)
            {
                object vstoControl = vstoWorksheet.Controls[0];
                vstoWorksheet.Controls.Remove(vstoControl);
            }
    
        }
    }
    
  4. C#의 경우 WorkbookBeforeSave 이벤트에 대한 이벤트 처리기를 만들어야 합니다. 이 코드를 ThisAddIn_Startup 메서드에 배치할 수 있습니다. 이벤트 처리기를 만드는 방법에 대한 자세한 내용은 방법: Office 프로젝트에서 이벤트 처리기 만들기를 참조하십시오. ThisAddIn_Startup 메서드를 다음 코드로 바꿉니다.

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        this.Application.WorkbookBeforeSave += 
            new Microsoft.Office.Interop.Excel.AppEvents_WorkbookBeforeSaveEventHandler
                (Application_WorkbookBeforeSave);
    }
    

솔루션 테스트

리본 메뉴의 사용자 지정 탭에서 컨트롤을 선택하여 워크시트에 컨트롤을 추가합니다. 워크시트를 저장하면 이러한 컨트롤은 제거됩니다.

솔루션을 테스트하려면

  1. F5 키를 눌러 프로젝트를 실행합니다.

  2. Sheet1의 셀을 선택합니다.

  3. 추가 기능 탭을 클릭합니다.

  4. group1 그룹에서 Button을 클릭합니다.

    단추가 선택한 셀에 나타납니다.

  5. Sheet1의 다른 셀을 선택합니다.

  6. group1 그룹에서 NamedRange를 클릭합니다.

    선택한 셀에 대한 명명된 범위가 정의됩니다.

  7. Sheet1에서 일련의 셀을 선택합니다.

  8. group1 그룹에서 ListObject를 클릭합니다.

    선택한 셀에 대한 목록 개체가 추가됩니다.

  9. 워크시트를 저장합니다.

    Sheet1에 추가한 컨트롤이 더 이상 나타나지 않습니다.

다음 단계

Excel 추가 기능 프로젝트의 컨트롤에 대한 자세한 내용은 다음 항목을 참조하십시오.

  • 워크시트에 컨트롤을 저장하는 방법에 대한 자세한 내용은 Office 개발 샘플 및 연습에서 Excel 추가 기능 동적 컨트롤 샘플을 참조하십시오.

참고 항목

개념

Excel 워크시트에서 Windows Forms 컨트롤 사용

NamedRange 컨트롤

ListObject 컨트롤

기타 리소스

Excel 솔루션

Office 문서의 컨트롤

변경 기록

날짜

변경 내용

이유

2011년 4월

프로젝트가 .NET Framework 4.0을 대상으로 하는 경우 추가해야 하는 어셈블리 참조를 설명하는 텍스트를 추가했습니다.

콘텐츠 버그 수정