.NET 개발자의 관점에서 파악한 Excel 개체 모델

Ken Getz

MCW Technologies, LLC

적용 대상:

    Microsoft Visual Studio Tools for the Microsoft Office System

    Microsoft Office Excel 2003

    Microsoft Visual Studio .NET 2003

요약 : Microsoft Office Excel 2003에서 제공되는 개체 중 일부를 설명하고 이를 사용하여 Microsoft Visual Studio Tools for the Microsoft Office System(VSTO)와 함께 관리되는 코드 솔루션을 만드는 방법을 설명합니다. 주로 Application, Workbook, Worksheet, Range 개체를 중점적으로 다루며, Visual Basic .NET과 Visual C# 코드 샘플을 통해 각 개체의 속성, 메서드, 이벤트에 대해 설명합니다.

Microsoft 다운로드 센터 tous.gif

에서 ExcelObj.exe를 다운로드하십시오.

목차

소개 소개
Application 개체 Application 개체
Excel의 상태와 표시를 제어하는 구성원 Excel의 상태와 표시를 제어하는 구성원
개체를 반환하는 구성원 개체를 반환하는 구성원
작업을 실행하는 구성원 작업을 실행하는 구성원
파일 조작을 처리하는 구성원 파일 조작을 처리하는 구성원
WorksheetFunction 클래스 WorksheetFunction 클래스
Application 이벤트 Application 이벤트
Workbook 클래스 Workbook 클래스
Workbook 클래스의 속성 Workbook 클래스의 속성
Document 속성 사용 Document 속성 사용
스타일 사용 스타일 사용
시트 사용 시트 사용
Workbook 클래스의 메서드 Workbook 클래스의 메서드
Worksheet 클래스 Worksheet 클래스
Sheet 클래스 없음 Sheet 클래스 없음
보호 작업 보호 작업
개체 속성 개체 속성
Range 개체 Range 개체
선택 대상 관리 선택 대상 관리
코드에서 범위 참조 코드에서 범위 참조
기술 사용 기술 사용
범위 사용 범위 사용
범위 내의 데이터 정렬 범위 내의 데이터 정렬
다음 단계 다음 단계

소개

Microsoft Visual Studio Tools for the Microsoft Office System(VSTO)을 활용하거나 간단히 COM Automation을 이용하여 Microsoft Office Excel 2003 응용 프로그램을 제어하고자 하는 개발자들은 Excel 개체 모델에서 제공되는 개체들을 다룰 수 있어야 합니다. Excel은 수백 가지의 개체를 제공하고 있지만 그 중 극히 일부만 집중적으로 익혀도 개체 모델을 시작하는 데에는 충분합니다. 중요한 개체는 다음과 같습니다.

  • Application

  • Workbook

  • Worksheet

  • Range

구체적인 수치를 제시할 수는 없지만 Excel을 통해 수행하는 작업의 상당 부분은 이 4개의 클래스와 그 구성원들을 중심으로 이루어집니다. 이 문서에서는 이 4개의 클래스를 사용하는 방법을 설명하고 각각의 속성, 메서드 및 이벤트를 소개하도록 하겠습니다. 또한 각 개체의 특징 중 일부를 보여주는 예제도 제시되어 있습니다.

대부분의 경우, Excel 개체 모델은 그 사용자 인터페이스를 직접 에뮬레이트합니다. Application 개체는 전체 응용 프로그램을 둘러싸는 래퍼를 제공하고 각 Workbook 개체에는 Worksheet 개체의 컬렉션이 포함되어 있다는 것을 쉽게 짐작할 수 있을 것입니다. 마찬가지로 셀을 표현하는 것은 기본적으로 Range 개체이며 이를 통해 개별 셀 또는 셀 그룹을 다룰 수 있습니다.

아래의 각 섹션에서는 주요 Excel 개체를 하나씩, 해당 개체의 특정 구성원들을 예시하여, 설명하고 있습니다. 다룰 수 있는 개체가 수백 개에 이르므로 이 문서에서 모두를 자세히 다루는 것은 불가능합니다. 그러나 개체 모델을 시작하기에는 충분한 내용이 설명될 것이며 이 내용을 숙지한다면 더 자세한 내용은 Excel의 온라인 도움말을 통해 스스로 파악할 수 있을 것입니다.

이 백서에서는 ExcelObjectModel.sln이라는 샘플 프로젝트를 참조하고 있습니다. 이 프로젝트에는 Excel 통합 문서 및 관련 Visual Basic .NET 코드를 포함하고 있습니다. 이 문서에 사용된 모든 예제가 샘플 프로젝트에 나와 있는 것은 아니지만 한 행 이상의 코드를 포함하고 모든 예제는 코드를 호출하도록 설정된 프로젝트 내부의 하이퍼링크와 함께 통합 문서에 들어 있습니다.

Application 개체

Excel Application 개체는 Excel 응용 프로그램 자체를 나타냅니다. 이것은 너무 뻔한 설명처럼 들릴 것입니다. 그러나 Application 개체는 실행 중인 응용 프로그램과 해당 인스턴스에 적용되는 옵션, 그리고 인스턴스에서 열려 있는 현재 사용자 개체에 관한 수많은 정보를 제공하고 있습니다. Application 개체는 수많은 구성원을 제공하는데 이들 중 다수는 일일이 살펴볼 필요가 없지만 나머지 다른 구성원들은 응용 프로그램의 정확한 동작에 핵심적으로 작용할 것입니다. 이러한 구성원들을 다음과 같이 분류할 수 있습니다.

  • Excel의 상태와 표시를 제어하는 구성원

  • 개체를 반환하는 구성원

  • 작업을 실행하는 구성원

  • 파일 조작을 처리하는 구성원

  • 기타 유용한 구성원

아래 섹션에는 위 그룹들 각각에 대해 설명되어 있으며 그 일부 구성원들을 보여주는 코드 샘플이 제시되어 있습니다.

Excel의 상태와 표시를 제어하는 구성원

Application 개체는 Excel의 일반적 상태를 제어하는 수많은 속성을 제공합니다. 1에는 상태 관련 Application 개체 속성들 중 일부가 나열되어 있습니다.

1. Excel   상태를   제어하는 Application 속성의   일부

속성 유형 설명
Cursor XlMousePointer (xlDefault, xlIBeam, xlNorthwestArrow, xlWait) 마우스 포인터의 모양을 가져오거나 설정합니다.
EditDirectlyInCell EditDirectlyInCell 셀을 직접 편집할 수 있도록 가져오거나 설정합니다. False로 설정되면 수식 입력줄에서만 셀을 편집할 수 있습니다.
FixedDecimal Boolean True로 설정되면 모든 수치 값이 FixedDecimalPlaces 속성을 이용하여 소수점 자릿수를 결정하고, True로 설정되지 않으면 FixedDecimalPlaces 속성은 무시됩니다(기본값은 False입니다).
FixedDecimalPlaces Long FixedDecimal 속성이 True인 경우 수치 데이터에 사용될 소수점 자리 수를 결정합니다.
Interactive Boolean 사용자가 키보드와 마우스를 통해 Excel을 다룰 수 있는 기능을 가져오거나 설정합니다. 이 속성을 False로 설정했다면 예외 처리기에서 반드시 True로 되돌려 놓아야 합니다. Excel에서 자동으로 재설정되지 않습니다.
MoveAfterReturn Boolean True로 설정된 경우 Enter를 누를 때 선택 영역이 다음 셀로 이동합니다. 기본값은 True입니다.
MoveAfterReturnDirection xlDirection (xlDown, xlToLeft, xlToRight, xlUp) MoveAfterReturn 속성이 True인 경우 Enter를 눌렀을 때 이동할 방향을 나타냅니다. 기본값은 xlDown입니다.
ScreenUpdating Boolean True로 설정되면 각 메서드 호출 이후 Excel에서 화면이 업데이트됩니다. 시간을 절약하고 응용 프로그램이 보다 전문적으로 보이게 하려면 코드가 실행되는 동안 표시를 끄는 것이 좋습니다. 작업이 완료되면 이 속성을 다시 True로 재설정하십시오. Excel에서 자동으로 재설정되지 않습니다.
SheetsInNewWorkbook Long Excel에서 새 통합 문서에 자동으로 배치하는 시트 수를 가져오거나 설정합니다.
StandardFont String Excel의 기본 글꼴 이름을 가져오거나 설정합니다. Excel을 다시 시작해야 적용됩니다.
StandardFontSize Long Excel의 기본 문서꼴 크기를 가져오거나 설정합니다. Excel을 다시 시작해야 적용됩니다.
StartupPath (read-only String Excel 시작 추가 기능이 들어 있는 폴더의 전체 경로를 반환합니다.
TemplatesPath (read-only) String 서식 파일이 들어 있는 폴더의 전체 경로를 반환합니다. 이 값은 Windows 특수 폴더 중 하나를 나타냅니다.

표 1에 제시된 속성 가운데 가장 많이 사용하게 될 속성은 ScreenUpdating 속성일 것입니다. 이 속성을 사용하면 Excel 응용 프로그램을 더 전문적으로 보이게 할 수 있을 뿐만 아니라 더 빨리 실행되도록 할 수 있습니다. 매번 수정할 때마다 표시를 업데이트하는 것은 특히 프로그래밍 방식으로 큰 범위를 채울 때 코드에 큰 부담을 줄 수 있습니다. 그러나 Excel에서 자동으로 이 속성을 재설정하지 않으므로 작업이 끝나면 항상 이 속성을 설정해야 합니다. 따라서 ScreenUpdating 속성을 사용할 때는 .NET 예외 처리 기능을 활용하여 화면 업데이트가 재수행될 수 있도록 항상 아래 코드와 유사한 코드를 사용해야 합니다.

' Visual Basic
Try
    ThisApplication.ScreenUpdating = False
    ' Do your work that updates the screen.
 
Finally
    ThisApplication.ScreenUpdating = True
End Try
 
// C#
try
{
    ThisApplication.ScreenUpdating = false;
    // Do your work that updates the screen.
}
 
finally
{
    ThisApplication.ScreenUpdating = true;
}

Application 개체는 또한 Excel의 표시를 제어하는 여러 속성을 제공합니다. 이 속성들을 수정하여 사용자들이 화면에서 보는 내용을 변경할 수 있습니다. 2에는 사용할 수 있는 표시 옵션의 일부가 나열되어 있습니다.

2. Excel   모양을   제어하는 Application 속성의   일부

속성 유형 설명
DisplayAlerts Boolean True(기본값)로 설정되면 필요한 경우(예: 시트를 삭제하는 경우) 코드가 실행되는 중에 경고 메시지가 표시됩니다. False로 설정하면 경고가 표시되지 않습니다. Excel은 각 경고에 기본값이 선택된 것처럼 동작합니다.
DisplayFormulaBar Boolean True(기본값)로 설정되면, 셀 편집을 위한 일반적인 수식 입력줄이 표시되고 False로 설정되면 수식 입력줄이 사라집니다.
DisplayFullScreen Boolean True로 설정되면 Excel은 전체 화면 모드(단순히 Excel 창을 극대화하는 것과는 다른 효과)로 실행됩니다. 기본값은 False입니다.

개체를 반환하는 구성원

많은 Application 개체의 속성들이 다른 개체를 반환합니다. Visual Studio .NET에서 제공하는 표준 Microsoft Office 프로젝트 서식 파일에는 ThisApplicationThisWorkbook 개체만 들어 있으므로 일반적으로 Application 클래스의 개체 구성원을 활용하여 Excel이 제공하는 다른 개체를 참조해야 할 것입니다. Chart와 같은 속성을 사용하는 개체의 컬렉션 또는 ActiveWindow와 같은 속성을 사용하는 특정 자식 개체에 대한 참조를 검색하는 데 이러한 구성원들을 이용할 수 있습니다. 3에는 Application 개체의 개체 반환 속성의 일부가 나열되어 있습니다.

3. Application 개체의   사용   가능한   개체   반환   속성   집합

속성 유형 설명
ActiveCell Range 활성 창(맨 위에 있는 창)의 현재 활성 셀에 대한 참조를 반환합니다. 활성 창이 없으면 이 속성은 오류를 일으킵니다.
ActiveChart Chart 현재 활성 차트에 대한 참조를 반환합니다. 포함된 차트는 선택되거나 활성화되는 경우에만 활성 차트로 간주됩니다.
ActiveSheet Object 활성 통합 문서의 활성 시트에 대한 참조를 반환합니다.
ActiveWindow Window 활성 창(맨 위에 있는 창)에 대한 참조를 반환하며 활성 창이 없는 경우에는 아무 것도 반환하지 않습니다.
Charts Sheets 활성 창의 각 차트에 대한 참조가 들어 있는 Sheet 개체(ChartWorksheet 개체의 부모 개체)의 컬렉션을 반환합니다.
Selection Object 응용 프로그램 내에서 선택된 개체를 반환합니다. 대체로 Range, Worksheet 또는 다른 개체가 되며 Window 클래스에도 적용됩니다. 이 경우에는 일반적으로 Range 개체가 됩니다. 현재 선택된 개체가 없으면 아무 것도 반환하지 않습니다.
Sheets Sheets 활성 통합 문서의 각 시트에 대한 참조가 들어 있는 Sheet 개체의 컬렉션을 반환합니다.
Workbooks Workbooks 열려 있는 모든 통합 문서에 대한 참조가 들어 있는 Workbook 개체의 컬렉션을 반환합니다.

실제 사용에서는, Application 클래스의 Workbooks 속성을 가장 자주 다루게 될 것입니다. 이 속성을 이용하면 열려 있는 문서를 여러 번 반복하거나 기존 통합 문서를 열거나 새로 만들 수 있습니다. 아래 섹션에는 이 속성의 동작이 설명되어 있습니다.

Workbooks 컬렉션

Workbooks 컬렉션은 열려 있는 모든 통합 문서를 다루고, 새 통합 문서를 만들고 새 통합 문서에 데이터를 가져올 수 있게 합니다. 아래 목록은 Workbooks 컬렉션의 주요 사용 방법 중 일부를 보여줍니다.

  •   통합   문서   만들기: 아래와 같은 코드를 이용합니다(Add 메서드에 대한 매개 변수로서 통합 문서 서식 파일의 이름을 지정할 수도 있습니다).
' Visual Basic
Dim wb As Excel.Workbook = ThisApplication.Workbooks.Add()
// C#
Excel.Workbook wb = ThisApplication.Workbooks.Add(Type.Missing);
  • 열려   있는   모든   통합   문서   닫기: 대부분의 컬렉션과 달리, 이 컬렉션을 이용하면 그 구성원을 모두 한 번에 닫을 수 있습니다. 아래의 메서드 호출은 열려 있는 모든 통합 문서를 닫습니다.
' Visual Basic
ThisApplication.Workbooks.Close()
// C#
ThisApplication.Workbooks.Close();
  • 기존   통합   문서   열기: Workbooks 컬렉션의 Open 메서드를 사용합니다. 가장 단순한 형태로는 아래 코드에서와 같이 Open 메서드를 사용합니다. Open 메서드는 특정 상황에서 그 동작에 영향을 미치는 수많은 선택적 매개 변수를 제공하지만 일반적으로는 선택적 매개 변수가 필요하지 않을 것입니다.
' Visual Basic
Dim wb As Excel.Workbook = _
  ThisApplication.Workbooks.Open("C:\YourPath\YourWorkbook.xls")
 
// C#
Excel.Workbook wb = ThisApplication.Workbooks.Open( 
    "C:\\YourPath\\Yourworkbook.xls", 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing);

:   C# 개발자라면 메서드 호출에서 Type.Missing 값에 대한 참조를 보는 데 익숙해져야 합니다. Excel 개체 모델은 VBA를 고려하여 작성되었으므로 그 메서드 중 다수가 최대 30개까지의 선택적 매개 변수를 허용합니다. C# 개발자는 Type.Missing 값의 인스턴스를 많이 사용하거나 각 개별 매개 변수에 특정 기본값을 제공해야 합니다.

  • 텍스트   파일,   데이터베이스   또는 XML 파일을   통합   문서로   열기: OpenText, OpenDatabase 또는 OpenXml 메서드를 사용합니다. 이 메서드들은 상당한 융통성을 제공하므로, 간단한 적용 예만 다루더라도 이 문서에서 할당할 수 있는 분량을 넘을 것입니다. 현재로서는 이러한 메서드들이 있다는 사실을 아는 것으로 충분합니다. 이러한 항목을 Excel에 로딩해야 하는 경우가 발생했을 때 더 자세히 알아 볼 수 있을 것입니다. 아래 코드에서는 텍스트 파일을 통합 문서로 로딩하면서 세 번째 행부터 쉼표를 구분자로 사용하고 있습니다.
' Visual Basic
Dim wb as Excel.Workbook = _
    ThisApplication.Workbooks.OpenText("C:\Test.txt", StartRow:=3, _
    DataType:=xlDelimited, Comma:=True)
 
// C#
Excel.Workbook wb = 
    ThisApplication.Workbooks.OpenText("C:\\Test.txt", 
    Type.Missing, 3, Excel.XlTextParsingType.xlDelimited, 
    Excel.XlTextQualifier.xlTextQualifierDoubleQuote, 
    Type.Missing, Type.Missing, Type.Missing, True, 
    Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing);
  • 개별   통합   문서   참조 : 정수(컬렉션 내부의 위치를 나타냄) 또는 통합 문서 이름을 사용하여 Workbooks 컬렉션에 인덱스를 넣을 수 있습니다. 그러나 이름을 기준으로 통합 문서를 참조하고자 한다면 참조 방법에 유의해야 합니다. 파일을 저장할 때까지는 반드시 제목 표시줄의 ".xls" 확장명을 포함하지 않는 이름을 사용해야 합니다.
' Visual Basic
Dim wb As Excel.Workbook = ThisApplication.Workbooks(1)
' Before Book1 is saved:
wb = ThisApplication.Workbooks("Book1")
' After Book1 is saved:
wb = ThisApplication.Workbooks("Book1.xls")
 
// C#
Excel.Workbook wb = ThisApplication.Workbooks[1];
// Before Book1 is saved:
wb = ThisApplication.Workbooks["Book1"];
// After Book1 is saved:
wb = ThisApplication.Workbooks["Book1.xls"];

:   특정 통합 문서를 참조할 때는 기본 인덱서인 Item 속성을 이용하게 됩니다. Item 속성 외에도 Workbooks 컬렉션은, Microsoft Office에서 제공되는 모든 컬렉션과 마찬가지로 컬렉션에 있는 항목(이 경우에는 Workbooks)의 수를 반환하는 Count 속성을 포함하고 있습니다.

작업을 실행하는 구성원

Application 개체는 현재 데이터 재계산에서부터 데이터에 대한 변경 취소에 이르는 작업을 수행할 수 있도록 해주는 여러 메서드를 제공합니다. 아래 목록에는 Application 개체의 메서드 중 일부를 각각 예제를 통해 설명하고 있습니다. 이 섹션의 예제는 샘플 통합 문서의 Application Object 시트에 나와 있습니다.

  • Calculate: 열려 있는 모든 통합 문서, 특정 통합 문서, 또는 특정 범위의 재계산을 강제합니다.
' Visual Basic
ThisApplication.Calculate
' Or...
ThisWorkbook.Calculate
' Or...
ThisApplication.Range("SomeNamedRange").Calculate
// C#
ThisApplication.Calculate();
// Or...
ThisWorkbook.Calculate();
// Or...
ThisApplication.get_Range("A1", "B12").Calculate();

참고: 샘플 코드에 나와 있는 것처럼 RangeWorksheet 개체도 Calculate 메서드를 제공합니다. 다시 계산하려는 가장 작은 수의 셀로 계산 범위를 제한하는 개체의 메서드를 사용하십시오. Excel의 재계산 엔진은 매우 빠르지만 포함되는 셀의 수를 제한하면 작업을 더욱 최적화할 수 있습니다. 열려 있는 모든 통합 문서에서 대기 중인 모든 변화를 다시 계산하려는 경우에만 Application.Calculate를 사용하십시오.

:   Visual Basic .NET과 C#에서 Excel 구성원을 처리하는 방식은 서로 약간 다른 점이 있습니다. 예를 들어 Excel, VBA 및 Visual Basic .NET의 Range 속성은 C#에서는 get_Range 메서드를 이용해야만 액세스할 수 있습니다. 이 문서에는 이에 대한 몇 개의 예제와 접근자 구성원에 대한 몇 개의 예제가 제시되어 있습니다.

  • CheckSpelling: 제공된 매개 변수의 맞춤법이 정확한지 나타내는 Boolean을 반환합니다. 대/소문자 무시 여부를 지시하는 Boolean과 사용자 지정 사전의 이름을 선택적으로 제공할 수도 있습니다. 아래 코드는 제공된 값의 맞춤법을 확인하고 그 결과를 시트에 나타냅니다.
' Visual Basic
Private Sub TestSpelling()
    Dim rng As Excel.Range = _
      ThisApplication.Range("CheckSpelling")
    Dim strOut As String
    If ThisApplication.CheckSpelling( _
      rng.Offset(0, 1).Value.ToString) Then
        strOut = "Spelled correctly"
    Else
        strOut = "Spelled incorrectly"
    End If
    rng.Offset(0, 2).Value = strOut
End Sub
 
// C#
private void TestSpelling()
{
    // If you specify only a named range in the call 
    // to get_Range, use Type.Missing for the second parameter.
    Excel.Range rng = ThisApplication.
    get_Range("CheckSpelling", Type.Missing);
 
    // 참고: that C# requires you to retrieve and set
    // the Value2 property of the Range, rather than 
    // the Value property, because the Value property 
    // is parameterized, making it unavailable to C# code:
    rng.get_Offset(0, 2).Value2 = 
        (ThisApplication.CheckSpelling(
    rng.get_Offset(0, 1).Value2.ToString(), 
        Type.Missing, Type.Missing) 
     "Spelled correctly" 
    : "Spelled incorrectly");
}

:   위 코드에서는 Range 개체의 Offset 메서드를 사용했는데, 둘 중 어느 것도 아직 실제로는 접해보지 못했을 것입니다. 이 둘 모두 이 문서의 후반부에 Range 개체를 설명한 섹션에 설명되어 있습니다. Range 클래스의 사용 방법은 이해하기 쉽습니다. Range 개체는 셀 또는 셀 그룹을 나타냅니다. 이 경우 Range 개체는 이름이 지정된 범위 CheckSpelling을 참조합니다. Offset 속성은 연결된 Range의 왼쪽 맨 위부터 지정된 수의 행과 열에 있는 Range 개체를 반환하며 알려진 위치와 관련된 셀을 작업할 수 있게 해줍니다.

  • Evaluate: Excel 이름을 실제 참조 또는 값으로 변환합니다. 이 메서드를 이용하면 문자열로 참조를 만든 다음 필요에 따라 이를 실제 개체 참조로 변환하거나 해당 표현식의 값을 계산합니다. 아래 샘플 코드에서는 셀 주소를 샘플 시트에 입력하고 지정한 주소의 셀에 텍스트를 입력합니다.
' Visual Basic
Private Sub TestEvaluate()
    Dim rng As Excel.Range = _
      ThisApplication.Range("Evaluate")
 
    Try
        Dim rngNew As Excel.Range = _
          ThisApplication.Evaluate( _
          DirectCast(rng.Offset(0, 1).Value), Excel.Range)
        rngNew.Value = "Hello, World!"
    Catch ex As Exception
        MessageBox.Show(ex.Message, ThisApplication.Name)
    End Try
End Sub
 
// C#
private void TestEvaluate()
{
    Excel.Range rng = ThisApplication.
        get_Range("Evaluate", Type.Missing);
 
    try 
    {
        Excel.Range rngNew = 
            (Excel.Range) ThisApplication.Evaluate(
            rng.get_Offset(0, 1).Value2);
        rngNew.Value2 = "Hello, World!";
    } 
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, ThisApplication.Name);
    }
}
  • MailSystem , MailSession , MailLogoff , MailLogon , SendMail: 이 구성원들을 이용하면 설치된 전자 메일 시스템에 로그온하여 현재 통합 문서를 첨부 파일로 전송하고 로그오프할 수 있습니다. MailSystem 속성은 설치된 전자 메일 시스템을 나타내며 MailSession 속성은 현재 전자 메일 세션에 대한 참조를 반환합니다(활성 세션이 있는 경우에는 로그온할 필요가 없습니다). 아래 예제는 샘플 통합 문서를 간단한 전자 메일 메시지의 파일로 첨부하여 전송합니다.
' Visual Basic
Private Sub TestEmail()
    If ThisApplication.MailSystem = Excel.XlMailSystem.xlMAPI Then
        If ThisApplication.MailSession Is Nothing Then
            Dim frm As New SendMail
            If frm.ShowDialog = DialogResult.OK Then
              ThisApplication.MailLogon( _
              frm.EmailName, frm.EmailPassword, frm.DownloadNewMail)
            End If
        End If
        Dim strEmail As String = _
         ThisApplication.Range("SendMail").Offset(0, 1). _
         Value.ToString
        ThisWorkbook.SendMail(strEmail, "Sample Excel Email")
        ThisApplication.MailLogoff()
    Else
        MessageBox.Show( _
         "This demonstration works only if MAPI is installed.")
    End If
End Sub
 
// C#
private void TestEmail()
{
    if (ThisApplication.MailSystem == 
        Excel.XlMailSystem.xlMAPI ) 
    {
        if ( ThisApplication.MailSession == null ) 
        {
            SendMail frm = new SendMail();
            if (frm.ShowDialog() == DialogResult.OK )
            {
                ThisApplication.MailLogon(frm.EmailName, 
                    frm.EmailPassword, frm.DownloadNewMail);
            }
        }
        string  strEmail = ThisApplication.
            get_Range("SendMail", Type.Missing).
            get_Offset(0, 1).Value2.ToString();
        ThisWorkbook.SendMail(strEmail, 
            "Sample Excel Email", Type.Missing);
        ThisApplication.MailLogoff();
    } 
    else 
    {
        MessageBox.Show("This demonstration works only if " + 
            "MAPI is installed.");
    }
}

참고:   Workbook 클래스는 SendMail 메서드를 제공합니다. 전자 메일로 보낼 수 있는 가장 세부적 단위의 개체가 통합 문서 자체이기 때문입니다. SendMail 메서드는 발송되는 메시지에 텍스트를 첨부할 수 있는 방법을 제공하지 않으며 주소 지정 방식에도 큰 유연성이 없다는 것을 알게 될 것입니다. 이 구성원들은 통합 문서를 전자 메일을 통해 간단히 전송하려는 목적으로만 제공됩니다. 모든 기능을 지원 받으려면 전자 메일을 다른 방식으로 이용할 수 있는 수단을 찾아야 합니다. 또한 현재 전자 메일 시스템에 온라인으로 연결되어 있지 않으면 위의 샘플 코드는 올바로 작동하지 않습니다. MailSession 속성이 '없음(Nothing)'을 반환하면 이러한 오류를 피해 메일을 발송하지 않도록 할 수 있습니다.

  • Quit: 프로그래밍 방식으로 Excel을 종료할 수 있습니다. DisplayAlerts 속성을 False로 설정했다면 저장되지 않은 데이터를 저장하라는 메시지가 표시되지 않습니다. 또한 WorkbookSaved 속성을 True로 설정하면 실제 변경 여부에 관계 없이, 변경 내용을 저장하라는 메시지가 표시되지 않습니다.
' Visual Basic
ThisApplication.Quit
 
// C#
ThisApplication.Quit();
  • Undo: 사용자 인터페이스에서 사용자가 수행한 마지막 작업을 취소합니다. 이 메서드는 코드에서 수행된 작업에는 아무 효과가 없으며 1회의 작업만 취소할 수 있습니다. 굉장히 기능적인 메서드는 아니지만 코드를 실행하기 전에 사용자가 수행한 마지막 작업을 취소할 수는 있습니다.
' Visual Basic
ThisApplication.Undo
 
// C#
ThisApplication.Undo();

파일 조작을 처리하는 구성원

Application 개체는 Excel 응용 프로그램의 맥락에서 파일 시스템을 다룰 수 있게 해주는 몇 가지 구성원을 제공합니다. 아래 섹션에는 자주 사용하게 될 구성원 일부가 설명되어 있습니다. (이 섹션에서 설명된 예제는 샘플 통합 문서의 Application File Handling 시트에 있습니다.) sheet of the sample workbook.)

DefaultFilePath 속성

아래의 간단한 속성은 Excel에서 파일 로딩 및 저장에 사용되는 경로를 가져오거나 설정합니다.

' Visual Basic
' When the workbook opens:
ThisApplication.Range("DefaultFilePath").Value = _
  ThisApplication.DefaultFilePath
 
' When you save the DefaultFilePath property:
ThisApplication.DefaultFilePath = _
  ThisApplication.Range("DefaultFilePath"). _
  Value.ToString
 
// C#
// When the workbook opens:
ThisApplication.get_Range("DefaultFilePath", Type.Missing).
    Value2 = ThisApplication.DefaultFilePath;
 
// When you save the DefaultFilePath property:
ThisApplication.DefaultFilePath = 
    ThisApplication.get_Range("DefaultFilePath", Type.Missing).
    Value2.ToString();

DefaultSaveFormat 속성

이 속성은 통합 문서를 저장하는 기본 서식을 가져오거나 설정합니다. Excel은 이 속성에 많은 옵션을 제공하는데 모두 XlFileFormat 열거의 구성원입니다. 이 샘플 통합 문서에서는 그림 1과 같이 제공된 항목들을 선택할 수 있습니다. 아래 코드는 해당 예제가 속성의 값을 어떻게 로딩하고 저장하는지 보여줍니다.

이 예제에서 샘플 시트의 열 E에는 XlFileFormat 열거에 가능한 모든 값의 이름 목록이 들어 있으며(이름이 "XlFileFormat"인 범위) 열 F에는 그에 해당하는 정수 값이 들어 있습니다. 그림 2에는 이 두 열의 일부가 나와 있습니다. DefaultSaveFormat이라고 이름이 지정된 범위(그림 1)에는 XlFileFormat 범위에 대한 참조가 들어 있어 목록에서 선택할 수 있습니다. 선택을 하고 그 값을 저장하기로 결정했으면 코드에서는 Range.Find 메서드를 사용하여 선택된 문자열을 찾은 다음, Range.Offset 메서드를 사용하여 찾은 값으로부터 지정된 오프셋의 값을 반환해야 합니다. (Range.Find 메서드에 대한 자세한 내용은 이 문서 뒤쪽의 "범위 내의 검색"이라는 섹션을 참조하십시오.) 마지막으로 이 코드에서는 정수 값(적절한 열거 유형으로 변환)을 다시 DefaultSaveFormat 속성으로 저장합니다.

DefaultSaveFormat의 현재 값은 쉽게 검색할 수 있습니다. 아래 코드는 그 값을 텍스트로 변환하고 샘플 시트의 정확한 Range에 표시합니다.

' Visual Basic
' When the workbook opens, convert the enumerated value 
' into a string:
ThisApplication.Range("DefaultSaveFormat").Value = _
  ThisApplication.DefaultSaveFormat.ToString
 
// C#
// When the workbook opens, convert the enumerated value 
// into a string:
ThisApplication.get_Range("DefaultSaveFormat", Type.Missing).
    Value2 = ThisApplication.DefaultSaveFormat.ToString();

선택된 값을 다시 할당하는 것은 좀 더 어렵습니다. 이 과정은 세 단계로 구성됩니다. 코드에서는 다음과 같은 작업을 처리해야 합니다.

시트의 DefaultSaveFormat 범위에서 선택된 저장 형식의 이름을 검색합니다.

' Visual Basic
' Retrieve the name of the new save format, as a string:
Dim strSaveFormat As String = _
  ThisApplication.Range("DefaultSaveFormat"). _
  Value.ToString()
 
// C#
// Retrieve the name of the new save format,
// as a string:
string strSaveFormat = ThisApplication.
  get_Range("DefaultSaveFormat", Type.Missing).
  Value2.ToString();

시트의 XlFileFormat 범위에 인접한 열에서 일치하는 정수 값을 찾아 Range 클래스의 Find 메서드를 호출합니다. 그런 다음 Range.Offset 속성을 사용하여 한 열 오른쪽에 있는 값을 조회합니다.

' Visual Basic
Dim intSaveFormat As Integer = _
  CType(ThisApplication.Range("XlFileFormat"). _
  Find(strSaveFormat).Offset(0, 1).Value, Integer)
 
// C#
Excel.Range rng = ThisApplication.
    get_Range("xlFileFormat", Type.Missing);
Excel.Range rngFind = rng.Find(strSaveFormat, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Excel.XlSearchDirection.xlNext, Type.Missing, Type.Missing, 
    Type.Missing);
// In C#, use the get_Offset method instead of the Offset property:
int intSaveFormat = 
    Convert.ToInt32(rngFind.get_Offset(0, 1).Value2);
정수 값을 DefaultSaveFormat 속성으로 다시 할당합니다.
' Visual Basic
ThisApplication.DefaultSaveFormat = _
  CType(intSaveFormat, Excel.XlFileFormat)
 
// C#
ThisApplication.DefaultSaveFormat = 
  Excel.XlFileFormat) intSaveFormat;

excelobj001.gif

그림 1. 제공된   유형   목록에서   파일   형식을   선택합니다.

excelobj002.gif

그림 2. 샘플   워크시트의 XlFileFormat 범위의   일부

RecentFiles 속성

RecentFiles 속성은 '파일' 메뉴의 최근 사용된 파일 목록에 표시되는 파일의 이름이 모두 들어 있는 문자열 컬렉션을 반환합니다. 사용자가 보유하기로 선택한 파일 수에 따라 목록 길이는 달라집니다. 샘플 통합 문서는 열릴 때 이 프로시저를 호출하여 샘플 통합 문서에 있는 RecentFiles라는 이름의 범위로 최근 파일 목록을 복사합니다.

' Visual Basic
Private Sub ListRecentFiles()
    Dim i As Integer
    Dim rng As Excel.Range = DirectCast( _
      ThisApplication.Range("RecentFiles"). _
      Cells(1, 1), Excel.Range)
    For i = 1 To ThisApplication.RecentFiles.Count
        rng.Offset(i - 1, 0).Value = _
          ThisApplication.RecentFiles(i).Name
    Next
End Sub
 
// C#
private void ListRecentFiles()
{
    Excel.Range rng = (Excel.Range)ThisApplication.
        get_Range("RecentFiles", Type.Missing).Cells[1, 1];
 
    for (int i = 1; i <= ThisApplication.RecentFiles.Count; i++)
    {
        rng.get_Offset(i - 1, 0).Value2 = 
            ThisApplication.RecentFiles[i].Name;
    } 
}

FileDialog 속성

FileDialog 속성은 4가지 유형으로 파일 조작을 다루는 FileDialog 개체를 반환합니다. 이 속성이 반환하는 FileDialog 개체를 이용하면 다음과 같은 작업을 할 수 있습니다.

  • 파일을 선택하고 엽니다.

  • 파일 위치를 선택하고 현재 통합 문서를 저장합니다.

  • 폴더를 선택합니다.

  • 파일 이름을 선택합니다.

이 대화 상자를 이용하면 Microsoft Office에서 제공되는 모든 파일 처리 기능을 사용할 수 있습니다. FileDialog 속성을 이용하려면 msoFileDialogType 열거값인 msoFileDialogFilePicker, msoFileDialogFolderPicker, msoFileDialogOpen 또는 msoFileDialogSaveAs 중 하나를 전달하여 이 대화 상자의 특정 용도를 선택해야 합니다. 그러면 이 속성이 반환하는 FileDialog 개체를 다룰 수 있습니다.

FileDialog 개체는 다른 많은 개체와 마찬가지로 Microsoft.Office.Core 네임스페이스에서 제공됩니다. 각 Office 개체마다 전체 경로를 입력하지 않도록, 샘플 프로젝트에서는 Imports 또는 using 문으로 이 네임스페이스를 가져옵니다. 이 문서의 코드에서는 파일에 적절한 네임스페이스 참조를 추가한 것으로 가정합니다.

' Visual Basic 
Imports Office = Microsoft.Office.Core
 
// C#
using Office = Microsoft.Office.Core;

FileDialog 개체의 Show 메서드는 대화 상자를 표시하며 '확인'을 누른 경우에는 -1을, '취소'를 누른 경우에는 0을 반환합니다. msoFileDialogOpen 또는 msoFileDialogSaveAs 열거값을 사용했다면 실제로 파일을 열거나 저장하기 위해 Execute 메서드를 사용할 수 있습니다. SelectedItems 속성에는 문자열 컬렉션이 들어 있는데 각각이 선택된 파일 이름을 나타냅니다.

예를 들어, 샘플 통합 문서에 있는 아래와 같은 코드에서는 새 통합 문서를 열라는 메시지를 표시합니다. 이 코드는 다중 선택을 허용하고, 제공되는 필터 목록을 지우며, 2개의 새로운 필터를 추가하고, 대화 상자를 표시합니다(그림 3 참조). 파일을 선택하면, FileDialog 개체의 Execute 메서드가 호출되어 요청된 파일을 엽니다.

' Visual Basic
With ThisApplication.FileDialog( _
  Office.MsoFileDialogType.msoFileDialogOpen)
    .AllowMultiSelect = True
    .Filters.Clear
    .Filters.Add "Excel Files", "*.xls;*.xlw"
    .Filters.Add "All Files", "*.*"
    If .Show <> 0 Then
        .Execute
    End If
End With
 
// C#
dlg = ThisApplication.get_FileDialog(
    Office.MsoFileDialogType.msoFileDialogOpen);
dlg.Filters.Clear();
dlg.Filters.Add("Excel Files", "*.xls;*.xlw", Type.Missing);
dlg.Filters.Add("All Files", "*.*", Type.Missing);
if(dlg.Show() != 0)
    dlg.Execute();

excelobj003.gif

그림 3. FileDialog 클래스를   이용하여   일반적인 ' 파일   열기 ' 대화   상자   표시하기

예제에 포함된 아래의 코드는 대화 상자를 이용하여 폴더를 선택하는 방법을 보여줍니다.

' Visual Basic
With ThisApplication.FileDialog( _
  Office.MsoFileDialogType.msoFileDialogFolderPicker)
    If .Show <> 0 Then
        ThisApplication.Range("FolderPickerResults"). _
          Value = .SelectedItems.Item(1)
    End If
End With
 
// C#
dlg = ThisApplication.get_FileDialog(
    Office.MsoFileDialogType.msoFileDialogFolderPicker);
if (dlg.Show() != 0)
{
    ThisApplication.get_Range("FolderPickerResults", Type.Missing).
        Value2 = dlg.SelectedItems.Item(1);
}

참고:   Application 개체는 열려는 파일 이름을 선택할 수 있는 GetOpenFileNameGetSaveAsFileName 메서드도 제공합니다. 이 메서드를 이용할 수도 있으나 Microsoft .NET Framework에서 제공되는 OpenFileDialogSaveFileDialog 컨트롤이 더 사용하기 쉽고 기능도 풍부합니다.

기타 유용한 구성원

Application 개체는 WorksheetFunction 속성, Names 컬렉션 및 Windows 컬렉션과 같이 다른 범주에 포함되지 않는 일부 구성원을 제공합니다. 다음 섹션은 이러한 구성원에 대한 설명입니다.

WorksheetFunction 클래스

Application 개체는 WorksheetFunction 클래스의 인스턴스를 반환하는 WorksheetFunction 속성을 포함합니다. 이 클래스는 각각 Excel 워크시트 함수를 래핑하는 여러 공유된/정적 메서드를 제공합니다. 이 각각의 메서드는 VBA에서는 따로 제공되지 않는 여러 Excel 스프레드시트 계산 함수 중 하나를 제공합니다. 일부 구성원은 Visual Basic .NET 및 C# 연산자 및 메서드에서 중복됩니다. 따라서 And 메서드와 같이 중복되는 구성원은 거의 사용되지 않습니다.

WorksheetFunction 클래스의 메서드에는 흥미롭고 유용한 기능이 많이 있습니다. 다음 목록의 요약 내용을 참조하십시오.

  • Acos, Acosh, Asin, Asinh, Cosh, Degrees, Ln, Log, Median, Max, Min, Mode, Radians 등의 수치 연산 함수

  • DAverage, DCount, DCountA, DGet, DMax, DMin, DProduct, DSum 등의 범위 계산을 수행하는 도메인 함수

  • IsErr, IsError, IsLogical, IsNA, IsNonText, IsNumber, IsText 등의 논리 함수

  • BetaDist, BinomDist, ChiTest, ChiInv, LogNormDist, NegBinomDist, Pearson, SumProduct, SumSq, TDist, TTest, Var, VarP 등의 통계 함수

  • And, Or, Choose와 같이 .NET Framework에서 거의 사용되지 않는 스프레드시트 함수

  • 태국어 관련 함수: BahtText, IsThaiDigit, ThaiDayOfWeek, ThaiDigit, ThaiMonthOfYear, ThaiNumSound, ThaiNumString, ThaiStringLength, ThaiYear, RoundBahtDown 및 RoundBahtUp과 같이 태국 숫자, 달력 및 통화를 조작하는 함수(일부 소문에는 Excel 팀이 태국 음식을 좋아하여 태국 음식점에서 음식 값을 계산하기 쉽도록 이런 함수를 추가했다는 소문이 있지만, 이는 사실이 아닙니다.)

Visual Studio .NET 프로젝트에서는 WorksheetFunction 클래스를 쉽게 활용할 수 있습니다. 프로젝트 서식 파일은 ThisApplication 개체를 제공하기 때문에 사용자는 해당 개체의 WorksheetFunction 속성을 쉽게 참조할 수 있습니다. 샘플 응용 프로그램에는 그림 4와 같이 클래스의 일부 구성원을 테스트하는 Other Application Members라는 시트가 있습니다.

참고:   WorksheetFunction 클래스 및 그 구성원은 대표적으로 Visual Basic에서 Excel 개체를 사용하는 것이 C#에서 동일한 코드를 사용하는 것보다 쉬운 이유를 설명해 줍니다. 여러 WorksheetFunction 클래스 메서드에서 C# 개발자는 30개의 매개 변수를 대부분 빈 값으로 전달해야 합니다. 여러 메서드 그룹에서 필요한 매개 변수 개수별로 각 메서드 그룹을 구분하는 래퍼를 작성하면 이러한 부담을 크게 줄일 수 있습니다. 이 문서의 코드에서는 래퍼 메서드 없이 "naked" 메서드를 호출합니다. 어찌되었건 간에 C# 코드는 확실히 효율이 떨어집니다.

Demonstrate WorksheetFunction 링크를 클릭하면 다음 코드가 실행됩니다. (Sort 메서드에 대한 자세한 내용은 "범위 내의 데이터 정렬" 섹션을 참조하십시오.)

' Visual Basic
Private Sub TestWorksheetFunction()
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisWorkbook.ActiveSheet, Excel.Worksheet)
    Dim rng As Excel.Range = ws.Range("RandomNumbers")
    Dim rnd As New System.Random
 
    Dim i As Integer
    For i = 1 To 20
        ws.Cells(i, 2) = rnd.Next(100)
    Next i
    rng.Sort(rng, _
      Orientation:=Excel.XlSortOrientation.xlSortColumns)
 
    With ThisApplication.WorksheetFunction
        ws.Range("Min").Value = .Min(rng)
        ws.Range("Max").Value = .Max(rng)
        ws.Range("Median").Value = .Median(rng)
        ws.Range("Average").Value = .Average(rng)
        ws.Range("StDev").Value = .StDev(rng)
    End With
End Sub
 
// C#
private void TestWorksheetFunction() 
{
    Excel.Worksheet ws = (Excel.Worksheet) ThisWorkbook.ActiveSheet;
    Excel.Range rng = ws.get_Range("RandomNumbers", Type.Missing);
    System.Random rnd = new System.Random();
 
    for ( int i = 1 ; i <= 20; i++)
        ws.Cells[i, 2] = rnd.Next(100);
 
    rng.Sort(rng, Excel.XlSortOrder.xlAscending, 
        Type.Missing, Type.Missing, Excel.XlSortOrder.xlAscending, 
        Type.Missing, Excel.XlSortOrder.xlAscending, 
        Excel.XlYesNoGuess.xlNo, Type.Missing,Type.Missing, 
        Excel.XlSortOrientation.xlSortColumns, 
        Excel.XlSortMethod.xlPinYin, 
        Excel.XlSortDataOption.xlSortNormal, 
        Excel.XlSortDataOption.xlSortNormal, 
        Excel.XlSortDataOption.xlSortNormal);
 
    Excel.WorksheetFunction wsf = ThisApplication.WorksheetFunction;
    ws.get_Range("Min", Type.Missing).Value2 = wsf.Min(rng, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
    ws.get_Range("Max", Type.Missing).Value2 = wsf.Max(rng, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
    ws.get_Range("Median", Type.Missing).Value2 = wsf.Median(rng,
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
    ws.get_Range("Average", Type.Missing).Value2 = wsf.Average(rng, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
    ws.get_Range("StDev", Type.Missing).Value2 = wsf.StDev(rng, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing);
}

excelobj004.gif

그림 4. WorksheetFunction 시트를   선택하여 WorksheetFunction 클래스       유용한   메서드를   테스트합니다.

샘플 코드에서와 같이 Range 개체를 매개 변수로 WorksheetFunction 메서드에 전달할 수 있습니다. 또한 단일 값이나 값 목록을 매개 변수로 전달할 수 있습니다. 이 메서드는 일반적으로 최대 32개의 매개 변수를 허용할 수 있습니다. 따라서 고정된 수 목록의 평균을 계산하려면 다음과 같이 코드를 사용할 수 있습니다.

' Visual Basic
dblAverage = ThisApplication.WorksheetFunction.Average( _
 12, 14, 13, 19, 21)
// C#
// 참고: the number of Type.Missing values--the method accepts
// 30 parameters.
dblAverage = ThisApplication.WorksheetFunction.Average(
    12, 14, 13, 19, 21, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing);

Window 클래스 및 Windows 컬렉션

일반적으로 Application 개체는 Excel 응용 프로그램 내에서 표시되는 창을 제어하며, 사용자는 Application 개체의 Windows 속성을 사용하여 Excel 개체 창을 열거나 닫고 배열할 수 있습니다.

Windows 속성은 Window 개체의 컬렉션을 반환하고, 사용자는 Arrange 메서드를 호출하여 열려 있는 모든 창(또는 볼 수 있는 창만)을 배열할 수 있습니다. XlArrangeStyle 열거값 중 하나를 지정하여 창 배열 방식을 지정하고, 선택적으로 볼 수 있는 창만 배열하고 창 스크롤을 동기화하는 방법을 지정할 수 있습니다. 예를 들어 Excel 작업 공간 내에서 창을 배열하려면 다음과 같은 코드를 사용합니다.

' Visual Basic
ThisApplication.Windows.Arrange( _
  Excel.XlArrangeStyle.xlArrangeStyleTiled)
// C#
ThisApplication.Windows.Arrange( 
  Excel.XlArrangeStyle.xlArrangeStyleTiled, 
  Type.Missing, Type.Missing, Type.Missing);

프로그래밍 방식으로 새 창을 만들려면 통합 문서의 NewWindow 메서드를 다음과 같이 호출할 수 있습니다.

' Visual Basic
ThisWorkbook.NewWindow()
// C#
ThisWorkbook.NewWindow();

Because the NewWindow method returns a NewWindow 메서드는 Window 개체를 반환하기 때문에, 사용자는 다음과 같이 새 창에 대한 캡션을 설정하고 이를 활성화하는 코드를 작성할 수 있습니다.

' Visual Basic
With ThisWorkbook.NewWindow()
    .Caption = "New Window"
    .Activate()
End With
// C#
Excel.Window wnd = ThisWorkbook.NewWindow();
wnd.Caption = "New Window";
wnd.Activate();

Windows 클래스는 색상, 캡션, 창 기능의 시각화 및 스크롤 동작과 같이 관련 창의 모양과 동작을 제어하는 속성 및 메서드를 제공합니다. 사용자는 특정 창의 속성을 사용하기 위해 다음과 같이 코드를 작성할 수 있습니다.

' Visual Basic
With ThisApplication.Windows(3)
    .GridlineColor = ColorTranslator.ToOle(Color.Red)
    .Caption = "A New Window"
    .DisplayHeadings = False
    .DisplayFormulas = False
    .DisplayWorkbookTabs = False
    .SplitColumn = 1
End With
// C#
wnd = ThisApplication.Windows[3];
wnd.GridlineColor = ColorTranslator.ToOle(Color.Red);
wnd.Caption = "A New Window";
wnd.DisplayHeadings = false;
wnd.DisplayFormulas = false;
wnd.DisplayWorkbookTabs = false;
wnd.SplitColumn = 1;

:   VBA 및 .NET은 비슷한 방식(각각은 32비트 정수의 하위 3바이트로 인코딩된 색의 구성 요소인 빨간색, 녹색 및 파란색을 포함하는 3바이트를 사용)으로 색상을 사용하지만 색상을 서로 다르게 처리합니다. 사용자는 System.Drawing.ColorTranslator.ToOle 메서드를 사용하여 .NET 색상을 VBA에서 필요한 OLE 색상으로 변환할 수 있습니다.

Other Application Members 시트에서 Work with Windows를 클릭하면 이 섹션에서 제공된 모든 코드가 포함된 TestWindows 샘플 프로시저를 실행합니다. 같은 시트에서 Reset Windows를 클릭하면 첫 번째 창을 제외한 모든 창을 닫고 첫 번째 창을 최대화하는 다음 프로시저가 실행됩니다.

' Visual Basic
Private Sub ResetWindows()
    Dim i As Integer
    For i = ThisApplication.Windows.Count To 2 Step -1
        ThisApplication.Windows(i).Close()
    Next
    ThisApplication.Windows(1).WindowState = _
      Excel.XlWindowState.xlMaximized
End Sub
// C#
private void ResetWindows()
{
    for (int i = ThisApplication.Windows.Count; i >= 2; i--)
        ThisApplication.Windows[i].Close(
          false, Type.Missing, Type.Missing);
    ThisApplication.Windows[1].WindowState = 
        Excel.XlWindowState.xlMaximized;
}

Name 클래스 및 Names 컬렉션

Application 개체는 Name 개체의 컬렉션을 반환하는 Names 속성을 제공합니다. 각 Name 개체는 Excel 응용 프로그램에서 이름이 지정된 범위에 해당합니다. 이름이 지정된 범위에 대한 참조를 검색하는 방법은 여러 가지입니다. 사용자는 WorkbookNames 속성을 사용하거나 Worksheet 개체의 Names 속성을 사용할 수 있습니다.

새로운 이름이 지정된 범위를 만들려면 Names 개체의 Add 메서드를 다음 코드에서와 같이 사용합니다. Add 메서드는 두 개의 필수 매개 변수 외에도 여러 가지 옵션 매개 변수를 허용합니다.

' Visual Basic
Dim nm As Excel.Name
nm = ThisApplication.Names.Add( _
  "NewName", "='Other Application Members'!$A$6")
 
// C#
Excel.Name nm;
 
nm = ThisApplication.Names.Add(
    "NewName", @"='Other Application Members'!$A$6", 
    Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing);
옵션 매개 변수와 함께 이름 및 위치를 지정한 다음 코드에서 범위를 참조할 수 있습니다.
' Visual Basic 
ThisApplication.Range("NewName").Value = "Hello, World!"
 
// C#
ThisApplication.get_Range(
    "NewName", Type.Missing).Value2 = "Hello, World!";

이름이 지정된 범위에 대한 정보를 검색하려면 Name 클래스의 여러 속성을 사용할 수 있습니다. 다음 목록은 가장 일반적으로 사용되는 몇 가지 구성원에 대한 설명입니다.

  • Name은 이름이 지정된 범위에 할당된 이름을 반환합니다.

  • RefersTo는 표준 형식("=SheetName!$B$25")으로 실제 대상 주소를 포함하는 문자열을 반환합니다.

  • RefersToR1C1은 "R1C1" 형식("=SheetName!R25C2")으로 대상 주소를 반환합니다.

  • Value는 해당 범위의 내용을 확인하는(resolve) 이름이 지정된 범위에 대한 참조를 반환합니다.

예제에서 Work with Names 링크를 클릭하면 시트의 한 영역에 모든 이름이 지정된 범위에 대한 정보를 채우는 다음 코드를 실행합니다.

' Visual Basic
Dim nm As Excel.Name
Dim rng As Excel.Range = ThisApplication.Range("Names")
Dim i As Integer
 
For i = 0 To ThisApplication.Names.Count  1
    nm = ThisApplication.Names.Item(i + 1)
    rng.Offset(i, 0).Value = nm.Name
    ' Without the leading "'", these references
    ' get evaluated, rather than displayed directly.
    rng.Offset(i, 1).Value = "'" & nm.RefersTo.ToString
    rng.Offset(i, 2).Value = "'" & nm.RefersToR1C1.ToString
    rng.Offset(i, 3).Value = nm.Value
Next i
 
// C#
Excel.Range rng = ThisApplication.get_Range("Names", Type.Missing);
for ( int i = 0 ; i <= ThisApplication.Names.Count - 1; i++)
{
    nm = ThisApplication.Names.Item(i + 1, 
        Type.Missing, Type.Missing);
    rng.get_Offset(i, 0).Value2 = nm.Name;
    // Without the leading "'", these references
    // get evaluated, rather than displayed directly.
    rng.get_Offset(i, 1).Value2 = "'" + nm.RefersTo.ToString();
    rng.get_Offset(i, 2).Value2 = "'" + nm.RefersToR1C1.ToString();
    rng.get_Offset(i, 3).Value2 = nm.Value;
}

Application 이벤트

Application 클래스에서 제공되는 다른 모든 메서드 외에도 사용할 수 있는 여러 이벤트가 있습니다. 이런 이벤트를 모두 설명할 수는 없지만, 이벤트의 이름만으로도 이벤트의 용도를 쉽게 확인할 수 있습니다. 다음 섹션에서는 응용 프로그램에서 사용할 가능성이 높은 일부 이벤트에 대해 설명합니다.

:   Office 응용 프로그램에서 이벤트 처리기로 전달되는 매개 변수는 네이티브 .NET 이벤트에서 사용되는 매개 변수와는 다르게 느껴질 수 있습니다. 일반적으로 .NET 이벤트 처리기는 항상 이벤트를 발생시킨 개체를 참조하는 Object 변수를 받고, 또한 이벤트에 대한 추가 정보를 포함하는 EventArgs 기본 클래스에서 상속된 두 번째 매개 변수를 받습니다. Office 응용 프로그램에는 잘 정의된 이벤트 디자인 패턴이 없습니다. 따라서 각 이벤트 처리기는 원래 개발자가 정의한 임의의 매개 변수 개수를 허용합니다.

시트 동작

Application 개체는 시트(차트 및 워크시트)와 관련된 일련의 이벤트를 제공합니다. 다음 목록은 이러한 이벤트에 대한 정보입니다.

  • SheetActivate는 시트가 활성화될 때 발생합니다. Excel은 이벤트 처리기에 활성화된 시트에 대한 참조를 포함하는 Object 변수를 전달합니다.

:   Excel에서 시트를 참조하는 Object를 전달하는 모든 경우, 사용자는 참조를 사용하기 전에 참조를 올바른 유형의 변수(상황에 따라 Worksheet 또는 Chart)로 캐스트해야 합니다. 하지만 Visual Basic .NET에서 Option Strict 설정을 비활성화한 경우에는 늦은 바인딩을 사용할 수 있습니다. 이 경우에는 여전히 입력 시 IntelliSense를 사용할 수 없어 코드 작성이 더 어려워집니다. Sheets 컬렉션 내의 항목을 사용하는 이 문서의 모든 예제는 결과를 Worksheet 또는 Chart와 같은 필요한 시트 유형으로 명시적으로 캐스트합니다.

  • SheetBeforeDoubleClick Excel이 기본 두 번 클릭 처리를 제공하기 전에 시트를 두 번 클릭할 때 발생합니다. Excel은 이벤트 처리기에 시트에 대한 참조를 포함하는 Object 변수와 두 번 클릭의 위치와 가장 가까운 셀을 포함하는 Range 개체 및 사용자가 기본 이벤트 처리를 취소할 수 있도록 허용하는 Boolean 값(기본값은 False)을 전달합니다. (이 이벤트는 차트 시트에서는 발생하지 않습니다.)

:   이름에 "Before"가 있는 모든 이벤트는 기본 이벤트 처리를 취소할 수 있게 해줍니다. 이벤트 처리기에 전달되는 매개 변수의 이름은 일반적으로 Cancel로 지정되고 기본값은 False가 사용됩니다. 이 매개 변수를 True로 설정하면 Excel이 이벤트에 대한 기본 처리를 실행하지 않습니다.

  • SheetBeforeRightClick은 Excel이 기본 오른쪽 클릭 처리를 제공하기 전에 시트를 마우스 오른쪽 단추로 클릭할 때 발생합니다. Excel은 이벤트 처리기에 시트에 대한 참조를 포함하는 Object 변수와 마우스 오른쪽 단추 클릭의 위치와 가장 가까운 셀을 포함하는 Range 개체 및 사용자가 기본 이벤트 처리를 취소할 수 있도록 허용하는 Boolean 값(기본값은 False)을 전달합니다. (이 이벤트는 차트 시트에서는 발생하지 않습니다.)

  • SheetCalculate는 시트가 다시 계산될 때 발생합니다. Excel은 이벤트 처리기에 다시 계산된 시트에 대한 참조를 포함하는 Object를 전달합니다.

  • SheetChange는 사용자 또는 실행 코드에 의해 워크시트의 셀이 변경될 때 발생합니다. Excel은 이벤트 처리기에 시트에 대한 참조를 포함하는 Object 변수와 변경된 범위를 참조하는 Range 변수를 전달합니다.

  • SheetDeactivate는 시트가 비활성화될 때(즉, 더 이상 포커스를 가지고 있지 않을 때) 발생합니다. 이 이벤트 처리기는 포커스가 같은 통합 문서 내의 다른 시트로 이동할 때에만 실행됩니다. Excel은 이벤트 처리기에 비활성화된 시트에 대한 참조를 포함하는 Object 변수를 전달합니다.

  • SheetFollowHyperlink는 통합 문서 내의 하이퍼링크를 클릭할 때 발생합니다. Excel은 이벤트 처리기에 링크가 포함된 시트를 참조하는 Object 변수와 사용자가 클릭한 링크에 대한 참조를 포함하는 Hyperlink 개체를 전달합니다. (샘플 프로젝트는 이 이벤트를 사용하여 예제 내의 탐색을 제공합니다.)

  • SheetSelectionChange는 워크시트에서 선택이 변경될 때 발생합니다. (이 이벤트는 차트 시트에서는 발생하지 않습니다.) Excel은 이벤트 처리기에 선택이 변경된 시트를 참조하는 Object 변수와 새로운 선택을 참조하는 Range 변수를 전달합니다. (Excel은 변경되기 전의 원래 선택에 대한 정보는 전달하지 않음을 유의하십시오.)

참고:   이 섹션의 각 이벤트는 Workbook 클래스에서 제공되는 이벤트로도 사용할 수 있습니다. Application 개체에서 이벤트가 제공될 때, 이 이벤트는 Excel 내에 현재 열린 시트에 대해서 발생합니다. 이 이벤트가 Workbook 개체에서 제공될 때 이 이벤트는 특정 통합 문서 내의 시트에 영향을 줄 경우에만 발생합니다. 또한 Worksheet 클래스에서 제공되는 동일 이벤트를 찾을 수 있습니다. 이 경우 이벤트 이름에는 "Sheet"가 포함되지 않으며(예: SheetFollowHyperlink 대신 FollowHyperlink), 이벤트 처리기에는 이벤트를 받은 개체에 포함된 정보인 시트에 대한 참조가 전달되지 않습니다. 그렇지 않으면 이벤트, 사용 용도 및 매개 변수는 여기에 설명된 이벤트와 동일합니다.

Window 동작

Application 개체(및 대응하는 Workbook 개체)는 Window 개체의 동작을 처리하는 일련의 이벤트를 제공합니다. 다음 목록은 이러한 이벤트에 대한 설명입니다.

  • WindowActivate는 창이 활성화될 때 발생합니다. Excel은 이벤트 처리기에 창을 제공한 통합 문서를 참조하는 Workbook 개체와 선택된 창을 참조하는 Window 개체를 전달합니다. 다른 활성화 이벤트와 마찬가지로, 이 이벤트는 포커스가 Excel 내에서 이동할 때만 발생합니다. 다른 응용 프로그램으로 전환한 다음 다시 Excel로 돌아오면 이 이벤트는 발생하지 않습니다.

  • WindowDeactivate는 창이 비활성화될 때 발생합니다. 자세한 내용은 WindowActivate 이벤트 설명을 참조하십시오.

  • WindowResize는 통합 문서 창의 크기를 조정할 때 발생합니다. Excel은 이벤트 처리기에 창을 제공한 통합 문서를 참조하는 Workbook 개체와 크기가 조정된 창을 참조하는 Window 개체를 전달합니다.

Workbook 관리

Application 개체는 Workbook 개체와 상호 작용할 때 발생하는 일련의 이벤트를 제공합니다. 이러한 각 이벤트 프로시저는 이벤트에 포함된 특정 통합 문서를 가리키는 Workbook 변수를 받습니다. 다음 목록은 사용 가능한 일부 이벤트에 대한 설명입니다.

  • NewWorkbook은 새 통합 문서를 만들 때 발생합니다. Excel은 이벤트 처리기에 새 통합 문서를 참조하는 Workbook 변수를 전달합니다. (이 이벤트는 Application 클래스에서만 제공됩니다.)

  • WorkbookActivate는 통합 문서가 활성화될 때 발생합니다. Excel은 이벤트 처리기에 활성화된 통합 문서를 참조하는 Workbook 변수를 전달합니다. (다른 "활성화" 이벤트와 같이 이 이벤트는 한 통합 문서에서 다른 통합 문서로 전환할 경우에만 발생합니다.)

  • WorkbookBeforeClose는 열린 통합 문서를 닫을 때 기본 이벤트 처리 전에 발생합니다. Excel은 이벤트 처리기에 닫으려는 통합 문서를 참조하는 Workbook 변수와 함께 이벤트 처리기가 기본 이벤트 처리(즉, 통합 문서를 열린 상태로 유지)를 취소할 수 있도록 허용하는 Boolean 값(기본값은 False)을 전달합니다.

경고:   다른 경우를 고려하지 않고 Cancel 매개 변수를 총체적으로 True로 설정한 경우 통합 문서를 닫을 수 없게 됩니다.

  • WorkbookBeforePrint는 통합 문서 내에서 인쇄가 시작될 때 기본 이벤트 처리 전에 발생합니다. Excel은 이벤트 처리기에 인쇄된 콘텐츠를 포함하는 통합 문서를 참조하는 Workbook 변수와 함께 이벤트 처리기가 기본 이벤트 처리(즉, 요청된 인쇄 건너뜀)를 취소할 수 있도록 허용하는 Boolean 값(기본값은 False)을 전달합니다.

  • WorkbookBeforeSave는 통합 문서가 저장될 때 기본 이벤트 처리 전에 발생합니다. Excel은 이벤트 처리기에 저장되는 통합 문서를 참조하는 Workbook 변수와 함께 이벤트 처리기가 기본 이벤트 처리(즉, 저장 취소)를 취소할 수 있도록 허용하는 Boolean 값(기본값은 False)을 전달합니다.

  • WorkbookDeactivate는 통합 문서가 비활성화될 때 발생합니다. Excel은 이벤트 처리기에 비활성화된 통합 문서를 참조하는 Workbook 변수를 전달합니다. (다른 "활성화" 이벤트와 같이 이 이벤트는 한 통합 문서에서 다른 통합 문서로 전환할 경우에만 발생합니다.)

  • WorkbookNewSheet는 통합 문서에 새 시트를 추가할 때 발생합니다. Excel은 이벤트 처리기에 통합 문서를 참조하는 Workbook 변수와 새로운 시트를 참조하는 Object 변수를 전달합니다.

  • WorkbookOpen은 통합 문서가 열릴 때 발생합니다. Excel은 이벤트 처리기에 새로 열린 통합 문서를 참조하는 Workbook 변수를 전달합니다.

참고:   Workbook 클래스는 여기에 설명된 이벤트들과 매우 유사한 자체 이벤트 집합을 제공합니다. "Workbook"으로 시작하는 모든 이벤트는 "WorkbookActivate" 대신 "Activate"와 같이 대상 지정 없이 Workbook 클래스의 이벤트 목록에 표시되어 있습니다. Workbook 클래스 이벤트 처리기는 Workbook 변수를 매개 변수로 수신하지 않고 해당 정보는 이벤트를 발생시킨 개체에 의해 의미가 지정됩니다. 또한 Workbook 클래스는 다른 Application 개체 이벤트의 미러를 제공하지만, 모든 통합 문서에 트래핑하는 것과는 대조적으로 단일 통합 문서에 대해서만 트래핑합니다. 지금까지 사용할 가능성이 높은 이벤트는 모두 설명되었으므로, 본 문서의 남은 부분에서는 이벤트에 대한 설명이 제공되지 않습니다.

Workbook 클래스

일반적으로 Workbook 클래스는 Excel 응용 프로그램 내의 단일 통합 문서를 나타냅니다. 이 섹션에서는 이 클래스의 일부 구성원에 대해 확인하고, 가장 자주 사용되는 속성 및 메서드에 대해 설명합니다.

:   Application 클래스의 구성원 중 상당 부분이 Workbook 클래스의 구성원과 일치합니다. 이 경우, 속성은 활성 통합 문서에 적용되는 것과는 대조적으로 특정 통합 문서에만 적용됩니다. 이들 구성원에 대해서는 이미 여러 곳에서 언급되고 있기 때문에 이 섹션에서는 이전 섹션보다 훨씬 적은 구성원에 대해서만 설명합니다.

Workbook 클래스의 속성

Workbook 클래스는 90개 정도의 여러 속성을 제공하고, 대부분의 개발자가 생각해 보지 못한 특별한 경우의 해결 방법을 제공합니다. 예를 들어 AutoUpdateFrequency 속성은 공유된 통합 문서에 대한 자동 업데이트 사이의 분 수를 반환합니다. Date1904 속성은 통합 문서가 1904 날짜 시스템(1904년 1월 2일을 값 1에 해당하는 날짜로 사용하는 날짜 연속화 체계, Macintosh 컴퓨터에서 일반적으로 사용됨)을 사용하는 경우 True를 반환합니다. PasswordEncryptionAlgorithm 속성을 사용하면 암호 암호화에 사용되는 정확한 알고리즘을 설정할 수 있습니다.

Workbook 개체의 여러 속성을 다루는 포괄적인 설명을 제공하는 대신, 이 섹션에서는 가장 자주 사용되는 속성에 대해서만 설명합니다. 통합 문서의 특정 동작이 필요한 경우에는 이미 다른 누군가가 이를 요청하였고, 이 동작을 가능하게 하는 속성이 있으며, 이 동작을 제공하는 메서드가 있을 가능성이 높습니다. 그러므로 통합 문서에 자신의 코드를 추가하기 전에 먼저 설명서를 자세히 확인해 보십시오.

다음 목록은 일반적으로 자주 사용되는 Workbook 속성 중 일부에 대해 설명합니다. Workbook properties:

  • Name, FullName, Path(String, 읽기 전용): 이들 각 속성은 통합 문서 이름의 서로 다른 버전을 반환합니다. FullName은 통합 문서 파일 이름을 포함한 전체 경로를 반환합니다. Name은 이름 부분만 반환하고 Path는 경로 부분만 반환합니다. 샘플 통합 문서에서 Name Information 링크를 클릭하면 다음 코드가 실행되고 그림 5와 같은 정보가 반환됩니다.
' Visual Basic
ThisApplication.Range("WorkbookName").Value = _
  ThisWorkbook.Name
ThisApplication.Range("WorkbookPath").Value = _
  ThisWorkbook.Path
ThisApplication.Range("WorkbookFullName").Value = _
  ThisWorkbook.FullName
 
// C#
ThisApplication.get_Range("WorkbookName", Type.Missing).
    Value2 = ThisWorkbook.Name;
ThisApplication.get_Range("WorkbookPath", Type.Missing).
    Value2 = ThisWorkbook.Path;
ThisApplication.get_Range("WorkbookFullName", Type.Missing).
    Value2 = ThisWorkbook.FullName;

excelobj005.gif

그림 5. 통합 문서 속성을 사용하여 이름에 대한 정보를 검색

  • Password(String): 통합 문서와 관련된 암호를 가져오거나 설정합니다. 비어 있지 않은 암호를 지정한 경우 통합 문서의 HasPassword 속성은 True를 반환합니다. Password 속성을 검색할 수는 있지만 값이 항상 "********"로 표시됩니다. 샘플 통합 문서에서 Set Password 링크를 클릭하면 다음 코드가 실행되어, 텍스트를 제공했는지 빈 문자열을 제공했는지 여부에 따라 통합 문서의 암호를 설정하거나 지웁니다. 이 예제에서는 샘플 프로젝트에서 단일 입력란과 Password 속성을 제공하는 Passoword라는 이름의 양식을 사용합니다. property:
' Visual Basic
Private Sub SetPassword()
    Dim frm As New Password
 
    If frm.ShowDialog = DialogResult.OK Then
        ThisWorkbook.Password = frm.Password
    End If
    frm.Dispose()
End Sub
 
// C#
private void SetPassword()
{
    Password frm = new Password();
 
    if (frm.ShowDialog() == DialogResult.OK)
        ThisWorkbook.Password = frm.Value;
    frm.Dispose();
}
  • PrecisionAsDisplayed(Boolean): True로 설정된 경우 Excel은 표시된 소수 자릿수를 사용하여 계산을 수행합니다. False(기본값)로 설정된 경우 계산은 표시가 되어 있지 않더라도 사용 가능한 모든 소수점 기호를 사용하여 수행됩니다. 그림 6은 속성이 True로 설정된 샘플 통합 문서를 보여줍니다. C 열에 있는 각 값은 B 열에 있는 값의 복사본이지만, 숫자 형식은 C 열에서 소숫점 이하 두 자리까지만 표시되도록 설정됩니다. PrecisionAsDisplayed 속성을 True로 설정한 경우 반올림에 따라 실제 값이 달라져서 합계가 다르게 표시됩니다. PrecisionAsDisplayed = False 링크를 클릭하면 합계는 동일하게 표시됩니다. 클릭하면 다음 프로시저를 호출하고 클릭한 링크에 따라 True 또는 False를 전달합니다.
' Visual Basic
Private Sub TestPrecisionAsDisplayed( _
  ByVal IsPrecisionAsDisplayedOn As Boolean)
    ThisWorkbook.PrecisionAsDisplayed = IsPrecisionAsDisplayedOn
End Sub
 
// C#
private void TestPrecisionAsDisplayed(
    bool IsPrecisionAsDisplayedOn)
{
    ThisWorkbook.PrecisionAsDisplayed = 
        IsPrecisionAsDisplayedOn;
}

excelobj006.gif

그림 6. PrecisionAsDisplayed 속성을 True로 설정한 경우 Excel은 표시된 소수 자릿수만 사용하여 계산을 수행합니다.

  • ReadOnly(Boolean, 읽기 전용): 통합 문서가 읽기 전용으로 열린 경우 True를 반환합니다. 통합 문서에 데이터를 저장할 수 없는 경우 응용 프로그램에서 다른 작업을 수행하도록 할 수 있습니다.

  • Saved(Boolean): 통합 문서의 저장된 상태를 가져오거나 설정합니다. 사용자가 통합 문서의 내용이나 구조를 변경한 경우 Saved 속성은 True입니다. 통합 문서를 닫거나 Excel을 종료하려고 시도하면 Application.DisplayAlerts 속성을 False로 설정하지 않은 한 통합 문서를 저장하라는 경고 메시지가 표시됩니다. 코드에서 Saved 속성 값을 False로 설정한 경우 Excel은 통합 문서가 이미 저장된 것과 같이 취급하고 저장하라는 메시지를 표시하지 않습니다.

Document 속성 사용

다른 Office 응용 프로그램과 마찬가지로 Excel을 사용하면 통합 문서와 함께 문서의 속성을 저장할 수 있습니다. Excel은 여러 가지 기본 제공된 속성을 제공하며 사용자만의 고유한 속성을 추가할 수도 있습니다. 파일|속성을 선택하면 그림 7과 같은 대화 상자가 표시되고, 사용자는 사용자 지정 탭을 선택하여 사용자 지정 속성을 만들고 수정할 수 있습니다.

excelobj007.gif

그림 7.   대화   상자를   사용하여   문서의   속성을   설정합니다.

Workbook 클래스 BuiltInDocumentProperties 속성으로는 기본 제공된 속성을 사용하고, CustomDocumentProperties 속성으로는 사용자 지정 속성을 사용합니다. 이들 각 속성은 DocumentProperty 개체의 컬렉션인 DocumentProperties 개체를 반환합니다. 컬렉션의 Item 속성을 사용하여 컬렉션 내의 이름 또는 인덱스별로 특정 속성을 검색할 수 있습니다. 속성 이름의 전체 목록은 Excel 설명서에서 찾을 수 있지만, 목록을 쉽게 검색할 수 있는 방법이 있습니다. 샘플 통합 문서의 Document Properties 링크를 클릭하면 다음 프로시저가 실행됩니다(그림 8 참조). 이 프로시저는 기본 제공된 모든 속성과 현재 값을 나열하는 DumpPropertyCollection 메서드를 호출하고 사용자 지정 속성에 대해서도 같은 과정을 반복합니다. 또한 이 프로시저는 Revision Number 속성을 개별적으로 수정하고 새로운 사용자 지정 속성을 만듭니다.

' Visual Basic
Private Sub DisplayDocumentProperties()
    Dim prp As Office.DocumentProperty
    Dim prps As Office.DocumentProperties
 
    Dim rng As Excel.Range = _
      ThisApplication.Range("DocumentProperties")
    Dim i As Integer
 
    Try
        ThisApplication.ScreenUpdating = False
 
        Try
            prps = DirectCast( _
              ThisWorkbook.BuiltinDocumentProperties, _
              Office.DocumentProperties)
 
            ' Set the Revision Number property:
            prp = prps.Item("Revision Number")
            prp.Value = CType(prp.Value, Integer) + 1
 
            ' Dump contents of the collection:
            DumpPropertyCollection(prps, rng, i)
 
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
 
        ' Work with custom properties:
        Try
            prps = DirectCast( _
              ThisWorkbook.CustomDocumentProperties, _
             Office.DocumentProperties)
            DumpPropertyCollection(prps, rng, i)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
 
        ' Add a custom property:
        Try
            ' Delete the property, if it exists.
            prp = prps.Item("Project Name")
            prp.Delete()
        Catch
            ' Do nothing if you get an exception.
        End Try
 
        Try
            ' Add a new property.
            prp = prps.Add("Project Name", False, _
             Office.MsoDocProperties.msoPropertyTypeString, _
              "White Papers")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    Finally
        ThisApplication.ScreenUpdating = True
    End Try
End Sub
 
Private Sub DumpPropertyCollection( _
  ByVal prps As Office.DocumentProperties, _
  ByVal rng As Excel.Range, ByRef i As Integer)
    Dim prp As Office.DocumentProperty
 
    For Each prp In prps
        rng.Offset(i, 0).Value = prp.Name
        Try
            If Not prp.Value Is Nothing Then
                rng.Offset(i, 1).Value = _
                   prp.Value.ToString
            End If
        Catch
            ' Do nothing at all.
        End Try
        i += 1
    Next
End Sub
 
// C#
private void DisplayDocumentProperties()
{
    Office.DocumentProperty prp = null;
    Office.DocumentProperties prps = 
        (Office.DocumentProperties) 
        ThisWorkbook.BuiltinDocumentProperties;
 
    Excel.Range rng = ThisApplication.
        get_Range("DocumentProperties", Type.Missing);
    int i = 0;
 
    try 
    {
        ThisApplication.ScreenUpdating = false;
 
        try 
        {
            // Set the Revision Number property:
            prp = prps["Revision Number"];
      prp.Value = Convert.ToInt32(prp.Value) + 1;
 
            // Dump contents of the collection:
            i = DumpPropertyCollection(prps, rng, i);
        } 
        catch (Exception ex) 
        {
            MessageBox.Show(ex.Message, ThisApplication.Name);
        }
 
        // Work with custom properties:
        try 
        {
      prps = (Office.DocumentProperties)
        ThisWorkbook.CustomDocumentProperties;
            DumpPropertyCollection(prps, rng, i);
        } 
        catch (Exception ex) 
        {
            MessageBox.Show(ex.Message, ThisApplication.Name);
        }
 
        // Add a custom property:
        try 
        {
            // Delete the property, if it exists.
            prp = prps["Project Name"];
            prp.Delete();
        } 
        catch
        {
            // Do nothing if you get an exception.
        }
        try 
        {
            // Add a new property.
            prp = prps.Add("Project Name", false, 
                Office.MsoDocProperties.msoPropertyTypeString,         
                "White Papers", Type.Missing);
        } 
        catch (Exception ex) 
        {
            MessageBox.Show(ex.Message, ThisApplication.Name);
        }
    } 
    finally 
    {
        ThisApplication.ScreenUpdating = true;
    }
}
 
private int DumpPropertyCollection(
    Office.DocumentProperties prps, Excel.Range rng, int i) 
{
    foreach (Office.DocumentProperty prp in prps)
    {
        rng.get_Offset(i, 0).Value2 = prp.Name;
        try 
        {
            if (prp.Value != null ) 
            {
                rng.get_Offset(i, 1).Value2 = 
                    prp.Value.ToString();
            }
        } 
        catch
        {
            // Do nothing at all.
        }
        i += 1;
    }
    return i;
}

:   이전 코드 샘플 DisplayDocumentProperties에서는 Microsoft.Office.Core 어셈블리에서 일부 열거 및 유형을 사용했습니다. 샘플 코드에는 "Excel" 축약에 사용되는 것과 같이 이 네임스페이스에 대한 축약으로 "Office" 텍스트를 설정한 Imports/using 문이 포함됩니다. 이 프로젝트 서식 파일은 "Excel" 축약을 자동으로 설정합니다. "Office" 문은 사용자가 직접 추가해야 합니다.

excelobj008.gif

그림 8. 기본   제공된   문서   속성

참고:   여기에서는 Excel과 관련 개체를 사용하지만, 기본 제공된 문서 속성 목록은 Office에서 제공되며, Excel에서는 예외에서 정의되지 않은 속성 트리거에 대한 Value 속성에 액세스하기 위해 모든 속성을 반드시 구현할 필요는 없습니다. 샘플 프로시저에는 이러한 상황을 처리하기 위해 반드시 발생해야 하는 간단한 예외가 포함됩니다.

스타일 사용

Word 문서와 마찬가지로 Excel 통합 문서에서도 통합 문서 내의 영역에 이름이 지정된 스타일을 적용할 수 있으며, Excel은 다양한 미리 정의된 스타일을 제공합니다. 사용자는 서식|스타일 메뉴 항목을 사용하여 그림 9와 같이 사용자가 스타일을 수정할 수 있는 대화 상자를 표시할 수 있습니다.

excelobj009.gif

그림 9.   대화   상자를   사용하여   대화식으로   스타일을   수정합니다 .

스타일 대화 상자에서 수정을 클릭하면 그림 10과 같이 셀 서식 대화 상자가 표시됩니다.

excelobj010.gif

그림 10.   서식   대화   상자를   사용하여   스타일을   수정합니다.

셀 서식 대화 상자에는 셀 서식에 사용할 수 있는 모든 옵션이 표시되며, 이 대화 상자에서 사용할 수 있는 모든 옵션은 코드에서도 사용할 수 있습니다. Workbook 개체의 Styles 속성을 사용하면 통합 문서 내의 영역에 스타일을 사용하고 지정할 수 있습니다.

Workbook 개체의 Styles 속성을 사용하여 스타일을 만들고, 삭제하고, 수정할 수 있습니다. 샘플 통합 문서에서 스타일 적용을 클릭하면 다음 프로시저가 실행되어 새 스타일을 만들고(코드를 이미 실행한 경우 기존 스타일 사용), 스타일에 대한 다양한 값을 설정하고, 이를 영역에 적용합니다.

' Visual Basic
Private Sub ApplyStyle()
    Const STYLE_NAME As String = "PropertyBorder"
    Dim rng As Excel.Range
    ' Get the range containing all the document properties.
    rng = GetDocPropRange()
 
    Dim sty As Excel.Style
    Try
        sty = ThisWorkbook.Styles(STYLE_NAME)
    Catch
        sty = ThisWorkbook.Styles.Add(STYLE_NAME)
    End Try
 
    sty.Font.Name = "Verdana"
    sty.Font.Size = 12
    sty.Font.Color = ColorTranslator.ToOle(Color.Blue)
    sty.Interior.Color = ColorTranslator.ToOle(Color.LightGray)
    sty.Interior.Pattern = XlPattern.xlPatternSolid
    rng.Style = STYLE_NAME
 
    rng.Columns.AutoFit()
End Sub
// C#
private void ApplyStyle()
{
    const String STYLE_NAME = "PropertyBorder";
    // Get the range containing all the document properties.
    Excel.Range rng = GetDocPropRange();
    Excel.Style sty;
    try
    {
        sty = ThisWorkbook.Styles[STYLE_NAME];
    }
    catch
    {
        sty = ThisWorkbook.Styles.Add(STYLE_NAME, Type.Missing);
    }
 
    sty.Font.Name = "Verdana";
    sty.Font.Size = 12;
    sty.Font.Color = ColorTranslator.ToOle(Color.Blue);
    sty.Interior.Color = ColorTranslator.ToOle(Color.LightGray);
    sty.Interior.Pattern = Excel.XlPattern.xlPatternSolid;
    rng.Style = STYLE_NAME;
    rng.Columns.AutoFit();
}

GetDocPropRange 메서드는 문서 속성에 의해 채워진 범위를 반환합니다. 이 프로시저는 Range.End 메서드를 사용하여 문서 속성으로 채워진 범위의 끝을 검색한 다음 해당 범위의 왼쪽 위와 오른쪽 아래 모서리에 맞춰 새로운 범위를 만듭니다.

' Visual Basic
Private Function GetDocPropRange() As Excel.Range
    Dim rng As Excel.Range = _
      ThisApplication.Range("DocumentProperties")
 
    Dim rngStart As Excel.Range = _
      DirectCast(rng.Cells(1, 1), Excel.Range)
    Dim rngEnd As Excel.Range = _
      rng.End(Excel.XlDirection.xlDown).Offset(0, 1)
 
    Return ThisApplication.Range(rngStart, rngEnd)
End Function
 
// C#
private Excel.Range GetDocPropRange()
{
    Excel.Range rng = 
        ThisApplication.get_Range("DocumentProperties", Type.Missing);
    Excel.Range rngStart = 
        (Excel.Range) rng.Cells[1, 1];
    Excel.Range rngEnd = 
        rng.get_End(Excel.XlDirection.xlDown).get_Offset(0, 1);
    return ThisApplication.get_Range(rngStart, rngEnd);
}

:   Range 개체의 검색 및 사용 방법은 이 문서의 "범위 사용" 섹션을 참조하십시오.

코드를 실행한 다음 샘플 통합 문서에서 문서 속성이 포함된 영역은 그림 11과 같이 음영 및 글꼴이 변경됩니다.

excelobj011.gif

그림 11. 사용자   지정   스타일   적용   이후

스타일   지우기를 클릭하면 동일 영역에 대한 스타일을 해제하는 다음 프로시저가 실행됩니다.

' Visual Basic
Private Sub ClearStyle()
    ' Get the range containing all the document properties, and
    ' clear the style.
    GetDocPropRange().Style = "Normal"
End Sub
 
// C#
private void ClearStyle()
{
    // Get the range containing all the document properties, and
    // clear the style.
    GetDocPropRange().Style = "Normal";
}

시트 사용

Workbook 클래스는 Sheets 개체를 반환하는 Sheets 속성을 제공합니다. 이 개체에는 각각 Worksheet 또는 Chart 개체일 수 있는 Sheet 개체의 컬렉션이 포함됩니다. 샘플 통합 문서에서 List Sheets를 클릭하면 다음 프로시저가 실행되고 통합 문서에 모든 기존 시트가 나열됩니다.

' Visual Basic
Private Sub ListSheets()
    Dim sh As Excel.Worksheet
    Dim rng As Excel.Range
    Dim i As Integer
 
    rng = ThisApplication.Range("Sheets")
    For Each sh In ThisWorkbook.Sheets
        rng.Offset(i, 0).Value = sh.Name
        i = i + 1
    Next sh
End Sub
 
// C#
private void ListSheets()
{
    int i = 0;
 
    Excel.Range rng = 
        ThisApplication.get_Range("Sheets", Type.Missing);
    foreach (Excel.Worksheet sh in ThisWorkbook.Sheets)
    {
        rng.get_Offset(i, 0).Value2 = sh.Name;
        i = i + 1;
    }
}

또한 Sheets 클래스의 다음 구성원들을 유용하게 사용할 수 있습니다.

  • Visible 속성을 사용하면 시트를 삭제하고 다시 만들지 않고 기존 시트를 표시하거나 숨길 수 있습니다. Visibility 속성을 XlSheetVisibility 열거값(XlSheetHidden, XlSheetVeryHidden, xlSheetVisible) 중 하나로 설정합니다. XlSheetHidden을 사용하면 사용자가 Excel 인터페이스를 통해 시트의 숨김을 해제할 수 있습니다. XlSheetVeryHidden을 사용하려면 사용자가 시트의 숨김을 해제하는 코드를 실행해야 합니다.
' Visual Basic
DirectCast(ThisWorkbook.Sheets(1), Excel.Worksheet).Visible = _
  Excel.XlSheetVisibility.xlSheetVeryHidden
 
// C#
((Excel.Worksheet) ThisWorkbook.Sheets[1]).Visible = 
    Excel.XlSheetVisibility.xlSheetVeryHidden;
  • Add 메서드를 사용하면 통합 문서의 시트 컬렉션에 새 시트를 추가할 수 있으며, 시트 위치, 추가할 시트 번호 및 시트 유형(워크시트, 차트 등)을 나타내는 4개의 옵션 매개 변수를 허용합니다.
' Visual Basic
Dim sh As Excel.Sheet = ThisWorkbook.Sheets.Add()
 
// C#
Excel.Sheet sh = ThisWorkbook.Sheets.Add(
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);
  • Copy 메서드는 시트의 복사본을 만들고 지정한 위치에 시트를 삽입합니다. 필요에 따라 기존 시트의 앞이나 뒤에 새 시트를 삽입하도록 지정할 수 있습니다. 위치를 지정하지 않으면 Excel은 새 시트가 들어 있는 새로운 통합 문서를 만듭니다. 다음 코드는 현재 통합 문서에서 첫 번째 시트를 복사하여 이를 세 번째 시트 다음에 둡니다.
' Visual Basic
DirectCast(ThisWorkbook.Sheets(1), Excel.Worksheet). _
  Copy(After:=ThisWorkbook.Sheets((3)))
 
// C#
((Excel.Worksheet) ThisWorkbook.Sheets[1]).
    Copy(Type.Missing, ThisWorkbook.Sheets[3]);.
  • Delete 메서드는 지정된 시트를 삭제합니다.
' Visual Basic
DirectCast(ThisWorkbook.Sheets(1), Excel.Worksheet).Delete
 
// C#
((Excel.Worksheet) ThisWorkbook.Sheets[1]).Delete();
  • FillAcrossSheets 메서드는 한 시트의 임의의 영역에서 데이터를 복사하여 통합 문서 내의 다른 모든 시트로 붙여 넣습니다. 사용자는 영역을 지정하고, 데이터, 서식 또는 둘 다 모두 복사할지 지정하며, 그 외 나머지 작업은 Excel이 수행합니다. 다음 코드는 한 시트의 Data라는 이름의 영역에서 데이터와 서식을 복사하여 통합 문서 내의 다른 모든 시트에 있는 동일 영역에 붙여 넣습니다.
' Visual Basic
ThisWorkbook.Sheets.FillAcrossSheets( _
  ThisApplication.Range("Data"), Excel.XlFillWith.xlFillWithAll)
 
// C#
ThisWorkbook.Sheets.FillAcrossSheets(
    ThisApplication.get_Range("Data", Type.Missing), 
    Excel.XlFillWith.xlFillWithAll);
  • Move 메서드는 시트의 인스턴스 하나만 남게 되는 점을 제외하고는 Copy 메서드와 거의 비슷합니다. 사용자는 시트를 다른 시트의 앞이나 뒤에 두도록 지정할 수 있습니다. 여기에서도 시트의 이동 위치를 지정하지 않으면, Excel은 시트가 포함된 새 통합 문서를 만듭니다. 다음 코드는 첫 번째 워크시트를 마지막 워크시트 위치로 이동합니다.
' Visual Basic
Dim shts As Excel.Sheets = ThisWorkbook.Sheets
DirectCast(shts(1), Excel.Worksheet).Move(After:=shts(shts.Count))
 
// C#
Excel.Sheets shts = ThisWorkbook.Sheets;
((Excel.Worksheet)shts[1]).Move(Type.Missing, shts[shts.Count]);

:   통합 문서 내에 있는 시트 목록을 정렬할 필요가 있는 경우에는 Move 메서드를 사용하여 비효율적인 글머리 정렬을 수행할 수 있습니다. 물론 시트 수가 그렇게 많을 경우는 별로 없기 때문에 정렬 속도는 문제가 되지 않을 것입니다.

  • PrintOut 메서드를 사용하면 선택된 개체를 인쇄할 수 있습니다. 이 메서드는 여러 다른 개체에 적용됩니다. 사용자는 인쇄할 페이지, 인쇄 매수, 인쇄 전 미리 보기, 사용할 프린터 이름, 파일로 인쇄 여부, 순서대로 인쇄 여부, 인쇄하려는 파일 이름 등과 같은 다양한 옵션 매개 변수를 지정할 수 있습니다. 다음 예제는 인쇄하기 전에 문서를 미리 본 다음 기본 프린터를 사용하여 지정한 시트에서 첫 번째 페이지의 두 복사본만 인쇄합니다.
' Visual Basic
DirectCast(ThisWorkbook.Sheets(1), Excel.Worksheet). _
  PrintOut(From:=1, To:=1, Copies:=2, Preview:=True)
 
// C#
((Excel.Worksheet)ThisApplication.Sheets[1]).
    PrintOut(1, 1, 2, true, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing);
  • PrintPreview 메서드를 사용하면 PrintPreview 창에서 지정된 개체를 표시하고 페이지 레이아웃 변경 허용을 선택적으로 해제할 수 있습니다.
' Visual Basic
DirectCast(ThisWorkbook.Sheets(1), Excel.Worksheet). _
  PrintPreview(False)
 
// C#
((Excel.Worksheet)ThisApplication.Sheets[1]).PrintPreview(false);
  • Select 메서드는 지정된 개체를 선택하여 사용자의 선택 대상을 이동합니다. 사용자의 선택 대상을 변경하지 않고 개체에 포커스를 두려면 Activate 메서드를 사용하십시오. 사용자는 현재 선택 대상에 대체될 개체에 대한 참조를 선택적으로 제공할 수 있습니다. 다음 코드는 첫 번째 워크시트를 선택합니다.
' Visual Basic
ActiveWorkbook.Sheets(1).Select()
 
// C#
((Excel.Worksheet)ThisApplication.Sheets[1]).Select(Type.Missing);

:   이 섹션에 나열된 여러 메서드는 다른 클래스에도 적용됩니다. 예를 들어 PrintOut 메서드는 Chart, Charts, Range, Sheets, Window, Workbook, WorksheetWorksheets 클래스에서도 제공됩니다. 이러한 메서드는 각 경우에 동일하게 작동되며, 다른 개체에 대해서도 사용됩니다. Select 메서드는 선택할 수 있는 모든 개체에 적용됩니다.

Workbook 클래스의 메서드

Workbook 클래스는 매우 특정한 상황을 처리하는 매우 다양한 메서드를 제공합니다. 이 섹션에서는 자세한 세부 내용을 모두 설명하는 대신 모든 응용 프로그램에서 가장 자주 사용되는 일부 메서드에 대해서만 설명합니다. 특정 메서드에 대한 내용은 이후에 살펴보도록 하십시오. 다음 목록은 일반적으로 사용해야 하는 일부 메서드에 대한 설명입니다.

  • Activate 메서드는 통합 문서를 활성화하고 해당 통합 문서에서 첫 번째 시트를 선택합니다.
' Visual Basic
ThisApplication.Workbooks(1).Activate
 
// C#
ThisApplication.Workbooks[1].Activate;
  • Close 메서드는 지정된 통합 문서를 닫고 선택적으로 변경 내용을 저장할지 여부를 지정합니다. 통합 문서를 처음으로 저장하는 경우에는 파일 이름을 지정할 수 있습니다. 또한 통합 문서가 다른 사용자에게 게시되는 경우, 통합 문서를 다음 사용자에게 전송할지 여부를 지정할 수 있습니다. 다음 코드는 통합 문서를 닫고 변경 내용은 무시합니다.
' Visual Basic
ThisApplication.Workbooks(1).Close(SaveChanges:=False)
 
// C#
ThisApplication.Workbooks(1).Close(false, 
  Type.Missing, Type.Missing);
  • ProtectUnprotect 메서드를 사용하면 워크시트를 추가하거나 삭제할 수 없도록 통합 문서를 보호하며, 통합 문서의 보호를 다시 해제할 수도 있습니다. 선택적으로 암호를 지정하건, 다른 사용자가 시트를 이동할 수 없도록 구조를 보호하거나 통합 문서의 창을 보호하도록 설정할지 여부를 선택적으로 표시할 수 있습니다. 통합 문서를 보호하면 다른 사용자가 셀을 편집할 수 없습니다. 데이터를 보호하려면 워크시트를 보호해야 합니다. 통합 문서의 보호를 해제하려면 필요한 경우 암호를 전달하여 Unprotect 메서드를 호출합니다. 다음 예제는 사용자에게 암호를 입력하도록 요청하는 GetPasswordFromUser라는 프로시저를 가정하고 입력된 값을 반환합니다.
' Visual Basic
ThisApplication.Workbooks(1).Protect(GetPasswordFromUser())
 
// C#
ThisApplication.Workbooks[1].Protect(
  GetPasswordFromUser(), Type.Missing, Type.Missing);
  • Save 메서드는 일반적인 방식으로 통합 문서를 저장합니다. 통합 문서를 처음으로 저장하는 경우에는 SaveAs 메서드를 대신 호출하여 경로를 지정해야 합니다. 통합 문서를 처음으로 저장하는 경우 Excel은 문서를 생성할 때 지정한 이름과 현재 폴더를 사용하여 문서를 저장합니다.
' Visual Basic
' Save all open workbooks.
Dim wb As Excel.Workbook
For Each wb in ThisApplication.Workbooks
    wb.Save
Next wb
 
// C#
// Save all open workbooks.
foreach (Excel.Workbook wb in ThisApplication.Workbooks)
{
    wb.Save();
} 
  • SaveAs 메서드는 Save 메서드보다 좀 더 복잡합니다. 이 메서드를 사용하면 지정된 통합 문서를 저장하고, 이름, 파일 형식, 암호, 액세스 모드 등을 선택적으로 지정할 수 있습니다. 모든 옵션에 대한 목록은 온라인 도움말을 참조하십시오. 다음 코드는 현재 통합 문서를 지정된 위치에 XML 형식을 사용하여 저장합니다.
' Visual Basic
ThisApplication.ActiveWorkbook.SaveAs("C:\MyWorkbook.xml"
 FileFormat:=Excel.XlFileFormat.xlXMLSpreadsheet)
 
// C#
ThisApplication.ActiveWorkbook.SaveAs("C:\\MyWorkbook.xml, 
    Excel.XlFileFormat.xlXMLSpreadsheet, Type.Missing, 
  Type.Missing, Type.Missing, Type.Missing, 
  Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);

:   일부 형식의 경우 파일을 저장하려면 사용자 입력이 필요하기 때문에 SaveAs 메서드를 호출하기 전에 Application.DisplayAlerts 속성을 False로 설정해야 할 수 있습니다. 예를 들어 워크시트를 XML 형식으로 저장하려면 Excel은 VBA 프로젝트를 통합 문서에 저장할 수 없다는 메시지를 표시합니다. DisplayAlerts 속성을 False로 설정하면 이러한 경고 메시지가 표시되지 않습니다.

  • SaveCopyAs 메서드는 통합 문서의 사본을 파일로 저장하지만, 메모리에 열려 있는 통합 문서를 수정하지 않습니다. 이 메서드는 통합 문서의 위치를 수정하지 않으면서 백업 사본을 만들고자 할 때 유용합니다.
' Visual Basic
ThisApplication.ActiveWorkbook.SaveCopyAs("C:\Test.xls")
 
// C#
ThisApplication.ActiveWorkbook.SaveCopyAs("C:\\Test.xls");

경고:   통합 문서를 저장하거나 복사하는 메서드를 대화식으로 취소하면 코드에서 런타임 오류가 발생합니다. 예를 들어 프로시저에서 SaveAs 메서드를 호출했지만, Excel에서 프롬프트를 비활성화한 경우 사용자가 프롬프트 메시지에서 취소를 클릭하면 Excel은 코드에 런타임 오류를 발생시킵니다.

Worksheet 클래스

지금까지 개별 워크시트를 사용하는 데 필요한 개념은 대부분 설명되었습니다. Worksheet 클래스는 매우 많은 구성원을 제공하지만, 이들 대부분의 속성, 메서드 및 이벤트는 Application 및/또는 Workbook 클래스에서 제공되는 구성원과 동일하거나 유사합니다. 이 섹션에서는 지금까지 설명되지 않은 Worksheet 클래스와 관련하여 중요한 구성원과 문제에 대해서만 설명합니다. Worksheet Object 시트에 대한 샘플 통합 문서에서 이 섹션에 대한 예제를 찾을 수 있습니다.

Sheet 클래스 없음

Excel은 Workbook 개체의 속성으로 Sheets 컬렉션을 제공하지만 사용자는 Excel에서 Sheet 클래스를 찾을 수 없습니다. 대신에 Sheets 컬렉션의 각 구성원은 Worksheet 또는 Chart 개체입니다. WorksheetChart 클래스는 내부 Sheet 클래스가 각각 특수화된 인스턴스입니다. 소스 코드에 대한 액세스 권한이 없으면 이것이 실제 구현과 일치하는지 알 수 있는 방법이 없습니다. 하지만 Sheet 클래스는 공개적으로 사용할 수 없습니다.

보호 작업

일반적으로 Excel에서 보호 기능은 사용자 및/또는 코드가 워크시트 내의 개체를 수정할 수 없도록 보호합니다. 워크시트에 대해 보호 기능을 설정한 다음에 다른 방식의 준비를 하지 않으면 사용자는 시트를 편집하거나 수정할 수 없습니다. 사용자 인터페이스 내에서 도구|보호|시트 보호 메뉴 항목을 사용하여 보호 기능을 설정할 수 있습니다. 이 항목을 선택하면 그림 12와 같이 시트 보호 대화 상자가 표시됩니다. 여기에서 암호를 설정하거나 사용자가 특정 작업을 수행하도록 허용할 수 있습니다. 보호 기능을 설정하면 기본적으로 모든 셀이 잠깁니다. 또한 그림 13과 같은 대화 상자를 표시하는 도구|보호|범위 편집 허용 메뉴 항목을 사용하여 사용자가 특정 범위를 편집하도록 허용할 수 있습니다. 이러한 두 대화 상자를 사용하여 시트를 잠근 다음 사용자가 특정 기능 또는 범위를 편집하도록 허용할 수 있습니다.

excelobj012.gif

그림 12. 사용자   인터페이스에서     대화   상자를   사용하여   보호   기능을   제어합니다.

excelobj013.gif

그림 13.   대화   상자를   사용하여   사용자가   특정   영역을   편집하도록   허용할     있습니다.

워크시트의 Protect 메서드를 사용하여 프로그래밍 방식으로 시트 보호를 제어할 수 있습니다. 이 메서드의 구문은 다음과 같이 보입니다. 여기에서 각 매개 변수는 옵션 매개 변수입니다.

' Visual Basic
WorksheetObject.Protect(Password, DrawingObjects, Contents, _
  Scenarios, UserInterfaceOnly, AllowFormattingCells, _
  AllowFormattingColumns, AllowFormattingRows, _
  AllowInsertingColumns, AllowInsertingRows, _
  AllowInsertingHyperlinks, AllowDeletingColumns, _
  AllowDeletingRows, AllowSorting, AllowFiltering, _
  AllowUsingPivotTables)
 
// C#
WorksheetObject.Protect(Password, DrawingObjects, Contents, 
  Scenarios, UserInterfaceOnly, AllowFormattingCells, 
  AllowFormattingColumns, AllowFormattingRows, 
  AllowInsertingColumns, AllowInsertingRows, 
  AllowInsertingHyperlinks, AllowDeletingColumns, 
  AllowDeletingRows, AllowSorting, AllowFiltering, 
  AllowUsingPivotTables);

다음 목록은 Protect 메서드의 매개 변수를 설명합니다.

  • Password 매개 변수를 설정하여 워크시트의 보호를 해제하기 위해 입력해야 하는 대소문자로 구분되는 문자열을 지정합니다. 이 매개 변수를 지정하지 않으면 누구나 시트의 보호를 해제할 수 있습니다.

  • DrawingObjects 매개 변수를 True로 설정하여 워크시트의 모양을 보호합니다. 기본값은 False입니다.

  • Contents 매개 변수를 True로 설정하여 워크시트의 콘텐츠(셀)를 보호합니다. 기본값은 True이며, 이 값은 변경할 필요가 없습니다.

  • Scenarios 매개 변수를 True로 설정하여 워크시트의 시나리오를 보호합니다. 기본값은 True입니다.

  • UserInterfaceOnly 매개 변수를 True로 설정하여 코드로부터의 변경은 허용하고 사용자 인터페이스로부터의 변경은 허용하지 않습니다. 기본값은 False로서, 코드 또는 사용자 인터페이스 모두에서 보호되는 워크시트를 변경할 수 없습니다. 이 속성 설정은 현재 세션에만 적용됩니다. 코드에서 모든 세션의 워크시트를 조작할 수 있도록 하려면 통합 문서를 열 때마다 이 속성을 설정하는 코드를 포함시켜야 합니다.

  • AllowFormattingCells 매개 변수, AllowFormattingColumns 매개 변수 및 이전 전체 메서드 구문 목록에 있는 매개 변수들을 사용하면 그림 12에 표시된 대화 상자의 옵션에 따라 특정 서식 기능을 사용할 수 있습니다. 기본적으로 모든 속성은 False입니다.

워크시트를 보호하려면 다음 코드에서 시트의 Protect 메서드를 호출하여 암호를 설정하고 정렬만 허용합니다.

' Visual Basic
DirectCast(ThisApplication.Sheets(1), Excel.Worksheet). _
  Protect("MyPassword", AllowSorting:=True)
 
// C#
((Excel.Worksheet)ThisApplication.Sheets[1]).Protect(
    "MyPassword", Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, true, Type.Missing, Type.Missing);

:   코드 내에 암호를 직접 코딩하는 것은 좋은 방법이 아닙니다. 일반적으로 사용자에게 암호를 요청하고 이를 저장하지 않고 통합 문서에 적용해야 합니다. 소스 코드에는 암호를 직접 입력하지 않습니다.

워크시트의 보호를 해제하려면 다음과 같이 코드를 사용할 수 있습니다. 다음 코드는 사용자에게 암호를 입력하도록 요청하는 GetPasswordFromUser라는 프로시저를 가정하고 입력된 값을 반환합니다.

' Visual Basic
DirectCast(ThisApplication.Sheets(1), Excel.Worksheet). _
  Unprotect(GetPasswordFromUser())
// C#
((Excel.Worksheet)ThisApplication.Sheets[1]).
  Unprotect(GetPasswordFromUser());

Unprotect 메서드는 워크시트에서 보호를 제거하고 사용자가 추가 암호를 제공할 수 있도록 허용합니다.

Excel은 또한 보호를 사용할 때 유용하게 사용할 수 있는 ProtectionAllowEditRange 개체를 제공합니다. Protection 개체는 보호되지 않는 범위에 대한 정보뿐만 아니라 Protect 메서드를 호출할 때 지정하는 모든 정보를 캡슐화합니다. Protect 메서드를 호출하면 다음 Boolean 속성을 제공하고 Protect 메서드의 매개 변수를 따르는 공유 Protection 개체의 속성을 설정합니다.

  • AllowDeletingColumns, AllowDeletingRows

  • AllowFiltering

  • AllowFormattingCells, AllowFormattingColumns, AllowFormattingRows

  • AllowInsertingColumns, AllowInsertingHyperlinks, AllowInsertingRows

  • AllowSorting

  • AllowUsingPivotTables

또한 Protection 클래스는 사용자가 그림 13에 표시된 대화 상자에서 지정되는 정보에 따라 워크시트의 편집 가능한 범위를 지정할 수 있도록 허용하는 AllowEditRanges 속성을 제공합니다. AllowEditRanges 속성에는 각각 다음과 같은 유용한 속성을 제공하는 AllowEditRange 개체의 컬렉션이 포함됩니다.

  • Range: 편집 가능한 영역에 따라 범위를 가져오거나 설정합니다.

  • Title: 그림 13과 같은 대화 상자에 표시할 편집 가능한 범위에 대한 제목을 가져오거나 설정합니다.

  • Users: UserAccess 개체의 컬렉션을 가져오거나 설정합니다. UserAccess 개체에 대한 자세한 내용은 온라인 설명서를 참조하십시오.

샘플 통합 문서의 Worksheet Object 시트에서 프로그래밍 방식의 보호 기능을 실험할 수 있습니다(그림 14 참조). 음영으로 표시된 범위 내에서만 편집할 수 있도록 보호를 클릭하여 시트를 보호합니다(Information 및 Date 범위). 시트 보호를 해제하려면 보호 해제를 클릭합니다.

excelobj014.gif

그림 14. 워크시트의   보호   기능을   테스트합니다.

샘플 시트의 링크는 다음 프로시저를 실행합니다.

' Visual Basic
Private Sub ProtectSheet()
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisApplication.ActiveSheet, Excel.Worksheet)
 
    With ws.Protection.AllowEditRanges
        .Add("Information", ThisApplication.Range("Information"))
        .Add("Date", ThisApplication.Range("Date"))
    End With
    ws.Protect()
End Sub
 
Private Sub UnprotectSheet()
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisApplication.Sheets("Worksheet Class"), _
      Excel.Worksheet)
 
    ' Unprotect the sheet.
    ws.Unprotect()
 
    ' Delete all protection ranges, just to clean up.
    ' You must loop through this using the index, 
    ' backwards. This collection doesn't provide 
    ' an enumeration method, and it doesn't handle
    ' being resized as you're looping in a nice way.
    Dim i As Integer
    With ws.Protection.AllowEditRanges
        For i = .Count To 1 Step -1
            .Item(i).Delete()
        Next i
    End With
End Sub
 
// C#
private void ProtectSheet()
{     
    Excel.Worksheet ws =
      (Excel.Worksheet)ThisApplication.ActiveSheet;
 
    Excel.AllowEditRanges ranges = ws.Protection.AllowEditRanges;
    ranges.Add("Information", 
        ThisApplication.get_Range("Information", Type.Missing), 
        Type.Missing);
    ranges.Add("Date", 
        ThisApplication.get_Range("Date", Type.Missing), Type.Missing);
 
    ws.Protect(Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing,Type.Missing, Type.Missing, 
        Type.Missing,Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing,Type.Missing,Type.Missing,
        Type.Missing,Type.Missing);
}
private void UnprotectSheet()
{
    Excel.Worksheet ws = 
        (Excel.Worksheet) ThisApplication.Sheets["Worksheet Class"];
    ws.Unprotect(Type.Missing);
 
    // Delete all protection ranges, just to clean up.
    // You must loop through this using the index, 
    // backwards. This collection doesn't provide 
    // an enumeration method, and it doesn't handle
    // being resized as you're looping in a nice way.
    Excel.AllowEditRanges ranges = ws.Protection.AllowEditRanges;
    for (int i = ranges.Count; i >= 1; i--)
    {
        ranges[i].Delete();
    }
}

개체 속성

Worksheet 클래스는 개체를 반환하는 일부 속성을 제공합니다. 다음 섹션은 이러한 개체에 대해 소개하고 개체 사용 예제를 제공합니다.

메모

삽입 | 메모 메뉴 항목을 사용하면 워크시트의 일정 범위에 연결된 텍스트 설명을 삽입할 수 있습니다(그림 15 참조). 코드에서는 Range 개체의 AddComment 메서드를 사용하여 동일한 결과를 얻을 수 있습니다. 다음 코드는 Date라는 이름의 범위에 연결된 메모가 있는 경우 해당 메모를 삭제하고 새로운 메모를 만듭니다. 마지막으로 코드는 다음 코드 샘플에서 설명되는 ShowOrHideComments 메서드를 호출하여 시트의 모든 메모를 표시합니다(그림 16 참조).

' Visual Basic
Dim rng As Excel.Range = ThisApplication.Range("Date")
If Not rng.Comment Is Nothing Then
    rng.Comment.Delete()
End If
rng.AddComment("Comment added " & DateTime.Now)
 
' Display all the comments:
ShowOrHideComments(Show:=True)
 
// C#
Excel.Range rng = ThisApplication.get_Range("Date", Type.Missing);
if (rng.Comment != null ) 
{
    rng.Comment.Delete();
}
rng.AddComment("Comment added " + DateTime.Now);
 
// Display all the comments:
ShowOrHideComments(true);

excelobj015.gif

그림 15. 사용자   인터페이스를   사용하여   워크시트에   새로운   메모를   쉽게   삽입할     있습니다.

excelobj016.gif

그림 16. 샘플   시트에   모든   메모를   표시한   다음

Worksheet 클래스는 Comments 개체를 반환하는 Comments 속성을 제공합니다. 이 Comment 개체 컬렉션을 사용하면 Worksheet와 연결된 모든 Comment 개체를 반복해서 실행할 수 있습니다. Comment 클래스는 여러 구성원을 제공하지 않습니다. 대부분의 경우 사용자는 Comment 클래스의 Visible 속성을 사용하여 메모를 표시하거나 숨기고, Delete 메서드를 사용하여 메모를 삭제합니다. 또한 Text 메서드도 유용하게 사용할 수 있습니다. 이 메서드를 사용하면 메모에 텍스트를 첨부하거나 기존 텍스트를 덮어쓰는 등 텍스트를 추가할 수 있습니다.

메모를 추가한 다음에는 워크시트에서 메모를 표시할 수 있습니다. 샘플 프로젝트에는 활성 시트의 모든 메모를 표시하거나 숨기는 ShowOrHideComments 프로시저가 포함됩니다.

' Visual Basic
Private Sub ShowOrHideComments(ByVal Show As Boolean)
    ' Show or hide all the comments:
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisApplication.Sheets("Worksheet Class"), _
      Excel.Worksheet)
 
    Dim i As Integer
    For i = 1 To ws.Comments.Count
        ws.Comments(i).Visible = Show
    Next
End Sub
 
// C#
private void ShowOrHideComments(bool show)
{
    // Show or hide all the comments:
    Excel.Worksheet ws = 
        (Excel.Worksheet) ThisApplication.Sheets["Worksheet Class"];
 
    for (int i = 1; i <= ws.Comments.Count; i++)
    {
        ws.Comments[i].Visible = show;
    }
}

참고:   Comments 컬렉션은 Excel의 여러 하위 컬렉션과 같이 기본 표시기를 제공하지 않습니다. 다시 말해서 For Each 루프를 사용하여 컬렉션의 모든 요소를 방문할 수 없습니다. Comment 컬렉션과 같은 컬렉션의 경우에는 컬렉션을 반복 실행하기 위해 인덱싱된 루프를 사용해야 합니다.

윤곽선

Excel은 윤곽선 기능을 사용하여 데이터 행을 그룹화하는 기능 지원을 제공합니다. 코드 내에서도 동일한 기능을 활용할 수 있습니다. 예를 들어 그림 17에 표시된 행 집합에 대해 사용자는 이미 그림에 표시된 것과 같이 윤곽선을 추가하여 그림 18과 같이 행을 축소하거나 그림 19와 같이 그룹을 축소할 수 있습니다.

excelobj017.gif

그림 17. 그룹   생성

excelobj018.gif

그림 18. 축소된   그룹

excelobj019.gif

그림 19. 완전하게   축소된   그룹

Worksheet 클래스는 그 자체가 Outline 개체인 Outline 속성을 제공합니다. Outline 클래스는 여러 구성원을 제공하지 않으며 다음 목록은 자주 사용되는 구성원들에 대한 설명입니다.

  • AutomaticStyles(Boolean)는 윤곽선에 자동 스타일을 적용할지 여부를 Excel에 알려줍니다.

  • SummaryColumn(XlSummaryColumn)은 요약 열의 위치를 가져오거나 설정합니다. XlSummaryColumn 열거는 xlSummaryOnLeftxlSummaryOnRight의 두 가지 가능한 값을 갖고 있습니다.

  • SummaryRow(XlSummaryRow)는 요약 행의 위치를 가져오거나 설정합니다. XlSummaryRow 열거는 xlSummaryAbovexlSummaryBelow의 두 가지 가능한 값을 갖고 있습니다.

  • ShowLevels를 사용하면 윤곽선 그룹을 행 수준 및/또는 열 수준으로 필요에 따라 축소하거나 확장할 수 있습니다. 이 메서드에는 다음과 같이 두 매개 변수를 전달할 수 있습니다.

' Visual Basic
Dim ws As Excel.Worksheet = _
  DirectCast(ThisApplication.ActiveSheet, Excel.Worksheet)
' Specify RowLevels and/or ColumnLevels parameters:
ws.Outline.ShowLevels(RowLevels:=3)
 
// C#
Excel.Worksheet ws = 
    (Excel.Worksheet) ThisApplication.ActiveSheet;
 
// Specify RowLevels and/or ColumnLevels parameters:
ws.Outline.ShowLevels(3, Type.Missing);

샘플 워크시트에는 years 2001(Data2001) 및 2002(Data2002)에 대한 날짜 및 전체 행 집합(AllData)에 대한 날짜에 따라 이름이 지정된 범위가 포함됩니다. 이러한 이름이 지정된 범위에는 워크시트의 전체 폭이 포함됩니다. 그룹화를 사용하려면 전체 행으로 구성되는 범위를 사용해야 합니다. 2003에 대한 데이터에는 이와 관련된 이름이 지정된 범위가 없습니다. 따라서 샘플 코드에서는 전체 행 범위로 사용할 수 있는 방법을 설명합니다.

그룹은 간단하게 만들 수 있습니다. 그룹을 만들려는 하나 이상의 행에 맞는 범위에 대해 Group 메서드를 호출하면 됩니다. 그룹화 매개 변수로는 그룹화할 시작 및 종료 값, 값별 그룹, 그룹화 기간을 나타내는 Boolean 배열 값의 네 가지 옵션 매개 변수가 있습니다. 이러한 매개 변수는 거의 필요하지 않기 때문에 예제에서는 이러한 매개 변수를 사용하지 않습니다. 그룹을 제거하려면 Ungroup 메서드를 호출합니다. 예를 들어 샘플 시트에서 Work with Groups 링크를 클릭하면 다음 코드가 실행됩니다.

' Visual Basic
Private Sub WorkWithGroups()
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisApplication.ActiveSheet, Excel.Worksheet)
 
    ' Set worksheet-level features for the outline.
    ' In this case, summary rows are below
    ' the data rows (so Excel knows where to put
    ' the summary rows), and we don't want Excel
    ' to format the summary rows--that's already been done.
    ws.Outline.SummaryRow = Excel.XlSummaryRow.xlSummaryBelow
    ws.Outline.AutomaticStyles = False
 
    ' Group the two named ranges. Each of these
    ' ranges extends across entire rows.
    ThisApplication.Range("Data2001").Group()
    ThisApplication.Range("Data2002").Group()
    ThisApplication.Range("AllData").Group()
 
    ' The range of rows from 24 to 27 doesn't have 
    ' a named range, so you can work with that 
    ' range directly.
    Dim rng As Excel.Range = _
      DirectCast(ws.Rows("24:27"), Excel.Range)
    rng.Group()
 
    ' Collapse to the second group level.
    ws.Outline.ShowLevels(RowLevels:=2)
End Sub
 
// C#
private void WorkWithGroups()
{
    Excel.Worksheet ws = 
        (Excel.Worksheet) ThisApplication.ActiveSheet;
 
    // Set worksheet-level features for the outline.
    // In this case, summary rows are below
    // the data rows (so Excel knows where to put
    // the summary rows), and we don't want Excel
    // to format the summary rows--that's already been done.
    ws.Outline.SummaryRow = Excel.XlSummaryRow.xlSummaryBelow;
    ws.Outline.AutomaticStyles = false;
 
    // Group the two named ranges. Each of these
    // ranges extends across entire rows.
    ThisApplication.get_Range("Data2001", Type.Missing).
        Group(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    ThisApplication.get_Range("Data2002", Type.Missing).
        Group(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    ThisApplication.get_Range("AllData", Type.Missing).
        Group(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
 
    // The range of rows from 24 to 27 doesn't have 
    // a named range, so you can work with that 
    // range directly.
    Excel.Range rng = (Excel.Range)ws.Rows["24:27", Type.Missing];
    rng.Group(Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing);
 
    // Collapse to the second group level.
    ws.Outline.ShowLevels(2, Type.Missing);
}

세 개의 이름이 지정된 범위를 그룹화하기 위해 이 코드는 해당 범위의 Group 메서드를 호출합니다.

' Visual Basic
ThisApplication.Range("Data2001").Group()
 
// C#
ThisApplication.get_Range("Data2001", Type.Missing).
    Group(Type.Missing, Type.Missing, Type.Missing, Type.Missing);

이름이 지정되지 않은 범위를 그룹화하기 위해 코드에서는 일정 행 범위에 대해 워크시트의 Rows 속성을 사용합니다. 이 속성은 요청된 행에 따른 범위를 반환합니다.

' Visual Basic
Dim rng As Excel.Range = _
  DirectCast(ws.Rows("24:27"), Excel.Range)
rng.Group()
 
// C#
Excel.Range rng = (Excel.Range)ws.Rows["24:27", Type.Missing];
rng.Group(Type.Missing, Type.Missing, Type.Missing, Type.Missing);

샘플 워크시트에서 Clear Groups 링크를 클릭하면 유사한 코드가 실행되어 그룹을 해제합니다.

' Visual Basic
Private Sub ClearGroups()
    Dim ws As Excel.Worksheet = _
      DirectCast(ThisApplication.ActiveSheet, Excel.Worksheet)
 
    ' Specify RowLevels and/or ColumnLevels parameters:
    ws.Outline.ShowLevels(RowLevels:=3)
 
    Dim rng As Excel.Range = _
      DirectCast(ws.Rows("24:27"), Excel.Range)
    rng.Ungroup()
    ThisApplication.Range("Data2001").Ungroup()
    ThisApplication.Range("Data2002").Ungroup()
    ThisApplication.Range("AllData").Ungroup()
End Sub
 
// C#
private void ClearGroups()
{
    Excel.Worksheet ws = 
        (Excel.Worksheet) ThisWorkbook.Sheets["Worksheet Class"];
 
    // Specify RowLevels and/or ColumnLevels parameters:
    ws.Outline.ShowLevels(3, Type.Missing);
 
    Excel.Range rng = (Excel.Range) ws.Rows["24:27", Type.Missing];
    rng.Ungroup();
 
    ThisApplication.get_Range("Data2001", Type.Missing).Ungroup();
    ThisApplication.get_Range("Data2002", Type.Missing).Ungroup();
    ThisApplication.get_Range("AllData", Type.Missing).Ungroup();
}

이러한 기술을 사용하여 그룹을 생성 및 제거하고 워크시트에 표시되는 그룹화 수준을 제어할 수 있습니다.

Range 개체

Range 개체는 Excel 응용 프로그램 내에서 가장 자주 사용되는 개체입니다. Excel 내의 범위를 조작하려면 먼저 해당 범위를 Range 개체로 표현하고 해당 Range의 메서드 및 속성을 사용해야 합니다. Range 클래스는 매우 중요합니다. 이 문서의 앞에서 보여진 모든 예제에도 Range 개체가 각각 다른 방식으로 사용되었습니다. 기본적으로 Range 개체는 셀, 행, 열, 하나 이상의 셀을 포함하는 셀 선택 범위(연속 또는 비연속적인 셀 집합) 또는 여러 시트에 있는 셀의 그룹을 나타냅니다.

Range 클래스에 포함된 구성원은 너무 많아서 모두 설명할 수 없기 때문에 이 섹션에서는 다음과 같이 3개의 중요한 문제에 대해서만 설명하도록 하겠습니다.

  • 코드에서 범위 참조

  • 코드에 범위 조작

  • Range 개체를 사용한 특정 목표 달성

다시 말해, Range 개체는 매우 다양한 상황에서 매우 다양한 용도를 포함하기 때문에 이 섹션에서는 구성원에 대한 전체 목록을 제공하는 대신 "사용 방법" 관련 질문에 대한 답변을 제공하는 데에 중점을 둘 것입니다.

선택 대상 관리

범위의 속성 및 동작을 수정하는 방법으로 현재 선택 대상을 사용하는 것이 편하기는 하지만, 이러한 방식은 가급적 사용하지 않는 것이 좋습니다. 다른 공유 리소스와 마찬가지로 Excel 내의 선택 대상은 사용자의 선택 대상을 나타냅니다. 이를 코드에서 수정하려는 경우에는 사용자가 현재 선택 대상에 대한 제어를 잃어버리도록 만듭니다. 가장 중요한 원칙은 사용자의 선택 대상을 변경하려는 경우에만 개체의 Select 메서드를 호출해야 한다는 것입니다. 개발자는 단순히 사용하기 편하다는 이유만으로 Select 메서드를 호출해서는 안 됩니다. 단순히 범위에 대한 속성을 설정하는 것이 목표라면 다른 방법을 사용할 수 있습니다. Select 메서드를 사용하지 않는다고 해서 코드 실행 속도가 더 빨라지지는 않지만, 사용자에게 더 나은 환경을 제공할 수는 있습니다.

사용자의 현재 셀에 인접한 영역을 해제하기 위해 다음과 같이 코드를 작성하는 것은 항상 너무 쉬운 방식입니다.

' Visual Basic
ThisApplication.ActiveCell.CurrentRegion.Select
DirectCast(ThisApplication.Selection, Excel.Range).ClearContents
 
// C#
ThisApplication.ActiveCell.CurrentRegion.Select();
((Excel.Range)ThisApplication.Selection).ClearContents();

하지만 이렇게 할 경우 사용자의 선택 대상을 잃게 됩니다. 원래는 한 개의 셀만 선택되어 있는 상태에서 앞의 코드를 실행하면 연속된 전체 셀 블록이 선택되는 결과가 발생할 것입니다. 원래 프로그램 의도가 전체 셀 범위를 선택하는 것이 아닌 경우에는 다음과 같이 코드를 작성하는 것이 더 나은 방법입니다.

' Visual Basic
ThisApplication.ActiveCell.CurrentRegion.ClearContents
 
// C#
ThisApplication.ActiveCell.CurrentRegion.ClearContents();

하지만 왜 모든 사람들이 첫 번째 코드를 사용하려고 할까요 이런 종류의 코드가 자주 작성되는 이유는 처음 시작하는 Excel 개발자의 경우 여러 개체 및 메서드를 Excel에서 실험해 볼 때 Excel 매크로 기록을 사용하는 경향이 크기 때문입니다. 이 방식은 훌륭한 방법이기는 하지만, 매크로 기록에서 작성되는 코드는 실제로는 거의 쓸모가 없습니다. 일반적으로 매크로 기록은 선택 대상을 사용하고 작업을 기록할 때 해당 선택 대상을 수정합니다.

:   셀이나 셀 그룹을 사용할 경우에는 가능한 모든 경우에 선택 대상을 수정하는 대신 사용하려는 셀을 설명하는 범위를 사용하십시오. 개발자의 의도가 사용자의 선택 대상을 수정하는 경우에는 Range.Select 메서드를 사용하십시오.

코드에서 범위 참조

Range 클래스는 유연성이 매우 뛰어나기 때문에 프로그래밍 방식으로 범위를 사용할 때 매우 다양한 옵션을 사용할 수 있습니다. 일부 경우에 Range 개체는 단일 개체이고 다른 경우에는 개체의 컬렉션을 나타냅니다. Range 개체는 주로 단일 개체를 참조하지만, 여기에는 ItemCount 구성원이 있어서 일부 경우에는 Range 개체의 사용 방법이 혼동될 수도 있습니다.

:   다음 예제 중 일부는 범위의 Address 속성을 검색합니다. 이 속성은 "$A$1"(A1 위치의 셀), "$1"(워크시트의 첫 번째 행) 및 "$A$1:$C$5"(A1과 C5를 경계로 사각형 안에 포함된 모든 셀로 구성되는 범위)와 같은 여러 형식 중 하나로 범위의 좌표를 나타내는 문자열을 반환합니다. "$"는 상대 좌표와는 반대 의미인 절대 좌표를 나타냅니다. Address 속성을 사용하면 검색한 범위의 정확한 위치를 가장 간단하게 찾을 수 있습니다. 범위를 참조하는 다양한 방법들에 대한 자세한 내용은 Excel 온라인 도움말을 참조하십시오.

Range 개체가 단일 셀 또는 셀 그룹을 참조하도록 하는 코드를 작성하는 가장 간단한 방법은 아래 목록에 설명되어 있습니다. 각 예제는 다음의 설정 코드를 기본으로 사용합니다.

' Visual Basic
Dim ws As Excel.Worksheet = _
  DirectCast(ThisWorkbook.Worksheets(1), Excel.Worksheet)
Dim rng, rng1, rng2 As Excel.Range
 
// C#
Excel.Worksheet ws = (Excel.Worksheet)ThisWorkbook.Worksheets[1];
Excel.Range rng, rng1, rng2;

다음 기술 중 하나를 사용하여 특정 범위를 참조할 수 있습니다. Range 개체에 대한 참조를 얻기 위한 방법은 이외에도 많이 있습니다.

  • Application 개체의 ActiveCell 속성을 참조합니다.
' Visual Basic
rng = ThisApplication.ActiveCell
 
// C#
rng = ThisApplication.ActiveCell;

  • 한 개체의 Range 속성을 사용하여 범위를 지정합니다. C#은 매개 변수가 있는 비인덱스형 속성을 지원하지 않기 때문에 그 대신 두 개의 매개 변수를 필요로 하는 get_Range 메서드를 호출해야 합니다. ```
' Visual Basic
rng = ws.Range("A1")
rng = ws.Range("A1:B12")
 
// C#
rng = ws.get_Range("A1", Type.Missing);
rng = ws.get_Range("A1:B12", Type.Missing);
  • 워크시트의 Cells 속성을 사용하여 단일 행 및 열 값을 지정합니다.
' Visual Basic
' The Cells collection returns an Object--
' Convert it to a Range object explicitly:
rng = DirectCast(ws.Cells(1, 1), Excel.Range)
 
// C#
rng = (Excel.Range)ws.Cells[1, 1];
  • 범위의 "모서리"를 지정합니다. 또한 범위에 대한 Cells, Rows 또는 Columns 속성을 직접 참조할 수도 있습니다. 모든 경우에 속성은 범위를 반환합니다.
' Visual Basic
rng = ws.Range("A1", "C5")
rng = ws.Range("A1", "C5").Cells
rng = ws.Range("A1", "C5").Rows
rng = ws.Range("A1", "C5").Columns
 
// C#
rng = ws.get_Range("A1", "C5");
rng = ws.get_Range("A1", "C5").Cells;
rng = ws.get_Range("A1", "C5").Rows;
rng = ws.get_Range("A1", "C5").Columns;
  • 이름이 지정된 범위를 참조합니다. 이 기술은 본 문서 전체에서 찾아볼 수 있습니다. C# get_Range 메서드는 두 개의 매개 변수가 필요하고 범위 이름에는 이들 매개 변수 중 하나만 필요하기 때문에 사용자는 두 번째 매개 변수에 대해 Type.Missing을 지정해야 합니다.
' Visual Basic
rng = ThisApplication.Range("SomeRangeName")
 
// C#
rng = ThisApplication.Range("SomeRangeName", Type.Missing);
  • 특정 행이나 열 또는 행 및 열 범위를 참조하십시오. RowsColumns 속성Option StrictOn으로 설정한 경우 변환이 필요한 Object를 각각 반환합니다.
' Visual Basic
rng = DirectCast(ws.Rows(1), Excel.Range)
rng = DirectCast(ws.Rows("1:3"), Excel.Range)
rng = DirectCast(ws.Columns(3), Excel.Range)
 
// C#
rng = (Excel.Range)ws.Rows[1, Type.Missing];
rng = (Excel.Range)ws.Rows["1:3", Type.Missing];
rng = (Excel.Range)ws.Columns[3, Type.Missing];

경고:   Columns 속성의 IntelliSense에 대한 설명이 잘못되었습니다. 설명에 따르면 이 속성에서는 사용자가 행을 지정한 다음 열 값을 지정해야 합니다. 하지만 실제로는 Columns 속성의 값 순서가 반대로 되어 있습니다. RowsColumns 속성 모두의 경우 두 번째 매개 변수는 사용되지 않습니다.

  • Application 개체의 Selection 속성을 사용하여 선택한 셀에 따른 범위를 반환합니다. 그림 20에 표시된 상황의 경우, 다음 코드는 문자열 "$C$3"(절대 좌표를 나타내려면 "$"를 사용)을 반환합니다.
' Visual Basic
Debug.WriteLine( _
  DirectCast(ThisApplication.Selection, Excel.Range).Address)
 
// C#
System.Diagnostics.Debug.WriteLine(
    ((Excel.Range)ThisApplication.Selection).
    get_Address(Type.Missing, Type.Missing, 
    Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing));

:   Address 속성은 C#에서 직접 처리할 수 없는 이러한 매개 변수가 있는 속성 중 하나입니다. get_Address 메서드를 호출하여 Range 개체에 해당하는 주소를 검색합니다. Address 속성의 모든 매개 변수는 옵션이지만 get_Address 메서드는 5개의 매개 변수를 검색합니다. 사용자는 이 중에서 주소 서식을 지정하는 세 번째 매개 변수만 사용하면 됩니다.

  • Create a range that contains the union of two other ranges (specify two ranges within the quotes, separated with a comma):
' Visual Basic
rng = ThisApplication.Range("A1:D4, F2:G5")
' You can also use the Application object's Union
' method to retrieve the intersection of two ranges:
rng1 = ThisApplication.Range("A1:D4")
rng2 = ThisApplication.Range("F2:G5")
rng = ThisApplication.Union(rng1, rng2)
 
// C#
rng = ThisApplication.get_Range("A1:D4, F2:G5", Type.Missing);
// You can also use the Application object's Union
// method to retrieve the intersection of two ranges, but this
// is far more effort in C#:
rng1 = ThisApplication.get_Range("A1", "D4");
rng2 = ThisApplication.get_Range("F2", "G5");
// 참고: that the Union method requires you to supply thirty
// parameters: 
rng = ThisApplication.Union(rng1, rng2, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);
  • 다른 두 범위의 통합을 포함하는 범위를 만듭니다. 큰따옴표 내의 두 범위를 쉼표로 구분하여 지정합니다.
' Visual Basic
rng = ThisApplication.Range("A1:D16 B2:F14")
' You can also use the Application object's Intersect
' method to retrieve the intersection of two ranges:
rng1 = ThisApplication.Range("A1:D16")
rng2 = ThisApplication.Range("B2:F14")
rng = ThisApplication.Intersect(rng1, rng2)
 
// C#
rng = ThisApplication.get_Range("A1:D16 B2:F14", Type.Missing);
// You can also use the Application object's Intersect
// method to retrieve the intersection of two ranges. 참고:
// that the Intersect method requires you to pass 30 parameters:
rng1 = ThisApplication.get_Range("A1", "D16");
rng2 = ThisApplication.get_Range("B2", "F14");
rng = ThisApplication.Intersect(rng1, rng2, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);
  • 한 범위의 Offset 속성을 사용하여 원래 범위에 상대적인 범위를 검색합니다. 다음 예제는 행 1, 열 1의 범위에 콘텐츠를 추가합니다.
' Visual Basic
rng = DirectCast(ws.Cells(1, 1), Excel.Range)
 
Dim i As Integer
For i = 1 To 5
    rng.Offset(i, 0).Value = i.ToString
Next
 
// C#
rng = (Excel.Range) ws.Cells[1, 1];
for (int i = 1; i <= 5; i++)
{
    rng.get_Offset(i, 0).Value2 = i.ToString();
}

:   Range.Offset 속성은 매개 변수가 있는 속성입니다. 따라서 C# 코드는 해당 값을 직접 검색할 수 없습니다. C# 개발자는 대신에 get_Offset 메서드를 호출해야 합니다.

  • 한 범위의 CurrentRegion 속성을 사용하여 가장 가까운 빈 행과 열의 경계 안에 있는 현재 영역을 나타내는 범위를 검색합니다. 예를 들어 그림 20에서 다음 표현식은 현재 영역의 글꼴을 굵게 설정합니다.
' Visual Basic
ThisApplication.Range("C3").CurrentRegion.Font.Bold = True
 
// C#
ThisApplication.get_Range("C3", Type.Missing).
    CurrentRegion.Font.Bold = True;

excelobj020.gif

그림 20. C3 셀의 CurrentRegion 속성을 요청하면 A1:E5 범위를 반환합니다.

  • 한 범위의 Areas 속성을 사용하여 범위의 콘텐츠 중 한 영역에 해당하는 범위 컬렉션을 검색합니다. 예를 들어 다음 코드는 그림 21에 표시된 이름이 지정된 범위 Test 내의 두 영역 모두에 대한 주소를 "$B$1:$E$5" 및 "$C$7:$G$11"로 표시합니다. "$"는 절대 좌표를 나타냅니다.
' Visual Basic
rng = ThisApplication.Range("Test")
Dim i As Integer
For i = 1 To rng.Areas.Count
  Debug.WriteLine(rng.Areas(i).Address)
Next
 
// C#
rng = ThisApplication.get_Range("Test", Type.Missing);
for (int i = 1; i <= rng.Areas.Count; i++)
{ 
    System.Diagnostics.Debug.WriteLine(
        rng.Areas[i].get_Address(Type.Missing, Type.Missing, 
        Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing));
}

excelobj021.gif

그림 21. 범위에는 연속되지 않은 영역이 포함될 수 있으며, 사용자는 Areas 속성을 사용하여 각각을 개별적으로 검색할 수 있습니다.

  • XlDirection 열거(xlUp, xlToRight, xlToLeft, xlDown)의 값과 함께 End 속성을 사용하여 사용자가 열거값으로 기술되는 키를 누른 것과 같이 영역의 끝에 있는 셀을 나타내는 범위를 검색합니다. 그림 22에서 표시된 선택된 셀을 사용하여 다음 코드는 코드의 주석에 표시된 대로 정의된 네 개의 범위로 종료됩니다.
' Visual Basic
Dim rngLeft, rngRight, rngUp, rngDown as Excel.Range
rng = DirectCast(ThisApplication.Selection, Excel.Range)
' E3
rngRight = rng.End(Excel.XlDirection.xlToRight)
' A3
rngLeft = rng.End(Excel.XlDirection.xlToLeft)
' C1
rngUp = rng.End(Excel.XlDirection.xlUp)
' C5
rngDown = rng.End(Excel.XlDirection.xlDown)
 
// C#
Excel.Range rngLeft, rngRight, rngUp, rngDown;
rng = (Excel.Range) ThisApplication.Selection;
// 참고: that the Range.End property is parameterized, so 
// C# developers cannot retrieve it. You must call the 
// get_End method, instead:
// E3
rngRight = rng.get_End(Excel.XlDirection.xlToRight);
// A3
rngLeft = rng.get_End(Excel.XlDirection.xlToLeft);
// C1
rngUp = rng.get_End(Excel.XlDirection.xlUp);
// C5
rngDown = rng.get_Down(Excel.XlDirection.xlDown);

excelobj022.gif

그림 22. End 속성을 사용하여 범위에 해당하는 여러 범위를 반환합니다.

  • EntireRow 또는 EntireColumn 속성을 사용하여 지정된 범위를 포함하는 행 또는 열을 참조합니다. 예를 들어 다음 코드는 행 7에서 11까지를 그림 21에 표시된 예제를 사용하여 글꼴을 굵게 설정합니다.
' Visual Basic
rng = ThisApplication.Range("Test")
rng.Areas(2).EntireRow.Font.Bold = True
 
// C#
rng = ThisApplication.get_Range("Test", Type.Missing);
rng.Areas[2].EntireRow.Font.Bold = true;

기술 사용

개발자는 텍스트를 굵게 표시하도록 선택된 셀을 포함하는 전체 행의 글꼴을 변경하는 기능을 공통적으로 요청합니다. Excel에는 이 기능이 포함되어 있지 않지만, 새로 기능을 추가하는 것이 그리 어렵지는 않습니다. 샘플 통합 문서의 Range 클래스에는 특별히 처리되는 범위가 포함되어 있습니다. 이 항목을 선택하면 해당 행이 굵게 표시됩니다. 그림 23은 작업으로 이 동작을 표시합니다.

excelobj023.gif

그림 23. 항목을   선택하면   전체   행을   굵게   표시합니다.

샘플 통합 문서에는 서식을 처리하는 다음 프로시저가 포함됩니다.

' Visual Basic
Private Sub BoldCurrentRow(ByVal ws As Excel.Worksheet)
    ' Keep track of the previously bolded row.
    Static intRow As Integer
 
    ' Work with the current active cell.
    Dim rngCell As Excel.Range = _
      ThisApplication.ActiveCell
 
    ' Bold the current row.
    rngCell.EntireRow.Font.Bold = True
 
    ' Make sure intRow isn't 0 (meaning that 
    ' this is your first pass through here).
    If intRow <> 0 Then
        ' If you're on a different
        ' row than the last time through here,
        ' make the old row not bold.
        If rngCell.Row <> intRow Then
            Dim rng As Excel.Range = _
              DirectCast(ws.Rows(intRow), Excel.Range)
            rng.EntireRow.Font.Bold = False
        End If
    End If
    ' Store away the new row number 
    ' for next time.
    intRow = rngCell.Row
End Sub
 
// C#
private int LastBoldedRow = 0;
private void BoldCurrentRow(Excel.Worksheet ws) 
{
    // Keep track of the previously bolded row.
 
    // Work with the current active cell.
    Excel.Range rngCell = ThisApplication.ActiveCell;
 
    // Bold the current row.
    rngCell.EntireRow.Font.Bold = true;
 
    // Make sure intRow isn't 0 (meaning that 
    // this is your first pass through here).
    if (LastBoldedRow != 0) 
    {
        // If you're on a different
        // row than the last time through here,
        // make the old row not bold.
        if (rngCell.Row != LastBoldedRow) 
        {
            Excel.Range rng = 
                (Excel.Range)ws.Rows[LastBoldedRow, Type.Missing];
            rng.Font.Bold = false;
        }
    }
    // Store away the new row number 
    // for next time.
    LastBoldedRow = rngCell.Row;
}

이 예제는 다음 작업을 수행하여 현재 행을 굵게 표시하고 이전에 굵게 표시된 행은 정상으로 표시합니다.

  • 이전에 선택한 행을 추적할 수 있도록 변수(Visual Basic의 경우 static)를 선언합니다.
' Visual Basic
Static intRow As Integer
 
// C#
private int LastBoldedRow = 0;
  • Application.ActiveCell 속성을 사용하여 현재 셀에 대한 참조를 검색합니다.
' Visual Basic
private int LastBoldedRow = 0;
Dim rngCell As Excel.Range = ThisApplication.ActiveCell
 
// C#
Excel.Range rngCell = ThisApplication.ActiveCell;
  • 활성 셀의 EntireRow 속성을 사용하여 현재 행을 굵게 표시합니다.
' Visual Basic
rngCell.EntireRow.Font.Bold = True
 
// C#
rngCell.EntireRow.Font.Bold = true;
  • intRow의 현재 값이 0이 아닌지 확인하십시오. 이 코드를 처음 실행한 경우 값이 0입니다.
' Visual Basic
If intRow <> 0 Then
    ' Code removed here...
End If
 
// C#
if (LastBoldedRow != 0)
{
    // Code removed here...
}
  • 현재 행이 이전 행과 다른지 확인하십시오. 행이 이전 행과 다른 경우에만 코드에서 행의 상태를 수정해야 합니다. Row 속성은 범위에 따라 행을 표시하는 정수를 반환합니다.
' Visual Basic
If rngCell.Row <> intRow Then
    ' Code removed here...
End If
 
// C#
if (rngCell.Row != LastBoldedRow)
{
    // Code removed here...
}
  • 이전에 선택한 행을 나타내는 범위에 대한 참조를 검색하고 해당 행을 굵게 표시되지 않도록 설정합니다.
' Visual Basic
Dim rng As Excel.Range = _
  DirectCast(ws.Rows(intRow), Excel.Range)
rng.Font.Bold = False
 
// C#
Excel.Range rng = 
    (Excel.Range)ws.Rows[LastBoldedRow, Type.Missing];
rng.Font.Bold = false;

샘플 통합 문서는 SheetSelectionChange 이벤트 처리기에서 BoldCurrentRow 프로시저를 호출합니다. 이 프로시저에서 코드는 Application 개체의 Intersect 메서드를 사용하여 새로운 선택 대상이 올바른 범위 내에 있는지 확인하고 범위가 올바르면 BoldCurrentRow 프로시저를 호출합니다.

' Visual Basic
Private Sub ThisWorkbook_SheetSelectionChange( _
  ByVal Sh As Object, ByVal Target As Excel.Range) _
  Handles ThisWorkbook.SheetSelectionChange
 
    If Not ThisApplication.Intersect(Target, _
      ThisApplication.Range("BoldSelectedRow")) Is Nothing Then
        ' The selection is within the range where you're making
        ' the selected row bold.
        BoldCurrentRow(DirectCast(Sh, Excel.Worksheet))
    End If
End Sub
// C#
protected void ThisWorkbook_SheetSelectionChange(
  System.Object sh, Excel.Range Target)
{
    // Don't forget that the Intersect method requires
    // thirty parameters.
    if (ThisApplication.Intersect(Target, 
        ThisApplication.get_Range("BoldSelectedRow", Type.Missing), 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
        Type.Missing, Type.Missing, Type.Missing, Type.Missing) 
        != null)
    {
        // The selection is within the range where you're making
        //the selected row bold.
        BoldCurrentRow((Excel.Worksheet) sh);
    }
}

범위 사용

범위에 대한 참조를 얻은 다음 이를 사용하는 방법에 대해 설명하도록 하겠습니다. 범위를 사용하여 할 수 있는 작업은 무제한적입니다. 이 섹션에서는 Range 개체를 사용하기 위한 일부 기술을 설명하고 각 기술에 대한 간단한 예제를 제공합니다. 이 섹션에서 사용되는 모든 예제는 샘플 통합 문서의 Range Class 시트에 있습니다.

범위 자동 채우기

Range 클래스의 AutoFill 메서드를 사용하면 범위를 특정 값으로 자동으로 채울 수 있습니다. 대부분의 경우 AutoFill 메서드는 범위에 점차적으로 증가하는 값이나 감소하는 값을 저장할 때 사용됩니다. 사용자는 XlAutoFillType 열거값(xlFillDays, xlFillFormats, xlFillSeries, xlFillWeekdays, xlGrowthTrend, xlFillCopy, xlFillDefault, xlFillMonths, xlFillValues, xlFillYears 또는 xlLinearTrend)에서 상수(옵션)를 제공하여 이러한 동작을 지정할 수 있습니다. 채우기 유형을 지정하지 않을 경우 Excel은 기본 채우기 유형(xlFillDefault)을 사용할 것으로 가정하고 적합한 경우 지정된 범위를 채웁니다.

그림 24와 같이 샘플 워크시트에는 자동 채우기를 수행할 네 개의 범위가 있습니다. B열에는 5개의 평일이 있고 C열에는 5개의 월이 있으며, D열에는 5년 동안 해마다 증가하는 날짜가 있고, E열에는 행별로 2씩 증가하는 일련의 숫자가 있습니다. 그림 25는 샘플 코드를 실행한 후의 동일 영역을 나타냅니다.

excelobj024.gif

그림 24. 4 개의   샘플   범위에   대해 AutoFill 메서드를   호출하기   .

excelobj025.gif

그림 25. 범위에   대해   자동   채우기를   실행한  

AutoFill 링크를 클릭하면 다음 프로시저가 실행됩니다.

' Visual Basic
Private Sub AutoFill()
    Dim rng As Excel.Range = ThisApplication.Range("B1")
    rng.AutoFill(ThisApplication.Range("B1:B5"), _
      Excel.XlAutoFillType.xlFillDays)
 
    rng = ThisApplication.Range("C1")
    rng.AutoFill(ThisApplication.Range("C1:C5"), _
      Excel.XlAutoFillType.xlFillMonths)
 
    rng = ThisApplication.Range("D1")
    rng.AutoFill(ThisApplication.Range("D1:D5"), _
      Excel.XlAutoFillType.xlFillYears)
 
    rng = ThisApplication.Range("E1:E2")
    rng.AutoFill(ThisApplication.Range("E1:E5"), _
      Excel.XlAutoFillType.xlFillSeries)
End Sub
 
// C#
private void AutoFill()
{
    Excel.Range rng = ThisApplication.get_Range("B1", Type.Missing);
    rng.AutoFill(ThisApplication.get_Range("B1:B5", Type.Missing), 
        Excel.XlAutoFillType.xlFillDays);
 
    rng = ThisApplication.get_Range("C1", Type.Missing);
    rng.AutoFill(ThisApplication.get_Range("C1:C5", Type.Missing), 
        Excel.XlAutoFillType.xlFillMonths);
 
    rng = ThisApplication.get_Range("D1", Type.Missing);
    rng.AutoFill(ThisApplication.get_Range("D1:D5", Type.Missing), 
        Excel.XlAutoFillType.xlFillYears);
 
    rng = ThisApplication.get_Range("E1:E2", Type.Missing);
    rng.AutoFill(ThisApplication.get_Range("E1:E5", Type.Missing), 
        Excel.XlAutoFillType.xlFillSeries);
}

각 경우에 사용자는 다음 두 범위를 지정해야 합니다.

  • 채우기의 "시작 지점"을 지정하는 AutoFill 메서드를 호출하는 범위

  • AutoFill 메서드의 매개 변수로 전달된 채우기를 수행할 범위. 이 대상 범위에는 소스 범위가 포함되어야 합니다.

AutoFill 메서드에 대한 두 번째 매개 변수인 XlAutoFillType 열거값은 옵션입니다. 일반적으로 필요한 동작을 얻으려면 이 값을 제공해야 합니다. 예를 들어 다음 코드를 변경해 보십시오.

' Visual Basic
rng.AutoFill(ThisApplication.Range("D1:D5"), _
  Excel.XlAutoFillType.xlFillYears)
// C#
rng.AutoFill(ThisApplication.get_Range("D1:D5", Type.Missing), 
    Excel.XlAutoFillType.xlFillYears);

위 코드를 다음과 같이 변경하십시오. FakePre-088fce8adf0e452583d21b661495adf0-3c7e79b4c9f6499186d8f3dae28deb02

연도별로 증가하는 날짜 대신 일자별로 증가하는 날짜를 얻게 됩니다.

범위 내의 검색

Range 클래스의 Find 메서드를 사용하면 범위 내에서 텍스트를 검색할 수 있습니다. 이 유용한 메서드는 그림 26에 표시된 Excel의 찾기 및 바꾸기 대화 상자의 동작을 모방합니다. 실제로 이 메서드는 이 대화 상자와 직접 상호 작용합니다. 즉, Range.Find 메서드는 사용자가 전달하는 매개 변수를 사용하여 검색 동작을 결정하거나, 사용자가 매개 변수를 전달하지 않은 경우 찾기 및 바꾸기 대화 상자에서 찾은 값을 사용합니다. 4Range.Find 메서드의 매개 변수를 보여주며, 이 중 첫 번째를 제외한 모든 매개 변수는 옵션입니다.

excelobj026.gif

그림 26. Find 메서드의 동작에 영향을 주는  대화 상자의 선택 항목들

경고:   Range.Find의 거의 대부분의 매개 변수는 옵션이고, 사용자는 찾기 및 바꾸기 대화 상자에서 값을 변경할 수 있기 때문에, 사용자의 선택 항목을 고려해야 하는 경우가 아니라면 Find 메서드에 모든 값을 제대로 전달했는지 직접 확인해야 합니다. 물론 C# 개발자는 각 메서드 호출에 대해 모든 매개 변수를 제공해야 하기 때문에 이 문제를 걱정할 필요가 없습니다.

4. Range.Find 메서드의 매개 변수

매개 변수 유형 설명
What (필수) Object 검색할 데이터입니다. 문자열이나 모든 Excel 데이터 형식일 수 있습니다.
After Range 검색을 시작하려는 범위(이 셀은 검색 대상에 포함되지 않음)입니다. 이 셀을 지정하지 않으면 검색은 해당 범위의 왼쪽 위 모서리에서부터 시작됩니다.
LookIn XlFindLookin (xlValue, xlComments, xlFormulas) 검색할 정보의 유형입니다. 이 정보는 Or 연산자를 사용하여 조합될 수 없습니다.
LookAt XlLookAt (xlWhole, xlPart) 검색이 전체 셀 또는 부분 셀에 해당하는지 여부를 결정합니다.
SearchOrder XlSearchOrder (xlByRows, xlByColumns) 검색 순서를 결정합니다. xlByRows(기본값)를 사용하면 검색이 수평 방향으로 진행된 다음 수직 방향으로 진행됩니다. xlByColumns를 사용하면 검색이 수직 방향으로 진행된 다음 수평 방향으로 진행됩니다.
SearchDirection XlSearchDirection (xlNext, xlPrevious) 검색의 방향을 결정합니다. 기본값은 xlNext입니다.
MatchCase Boolean 검색의 대소문자 구분 여부를 결정합니다.
MatchByte Boolean 2바이트 문자끼리 일치하도록 하거나(True), 상응하는 1바이트 문자와도 일치하도록 할지(False) 여부를 결정합니다. 2바이트 지원을 설치한 경우에만 적용됩니다.

샘플 통합 문서의 다음 예제는 "Fruits"라는 범위를 검색하고 "apples" 단어가 포함된 셀의 글꼴을 수정합니다. 그림 27은 검색 결과를 보여줍니다. 이 프로시저는 또한 이전에 설정된 검색 설정을 사용하여 검색을 반복하는 FindNext 메서드를 사용합니다. Range.FindPrevious 메서드는 Range.FindNext 메서드와 거의 동일하게 작동하지만, 이 예제에서는 사용되지 않습니다. 검색을 수행할 셀을 지정하면 나머지는 FindNext 메서드가 처리합니다.

excelobj027.gif

그림 27. "apples" 단어가 포함된 셀의 검색 결과

:   FindNextFindPrevious 메서드는 범위 끝까지 검색을 한 다음에는 다시 검색 범위의 시작 부분으로 돌아갑니다. 무한 루프로 계속해서 검색이 반복 수행되지 않도록 코드를 작성해야 합니다. 샘플 프로시저는 이를 처리하기 위한 한 가지 방법을 보여줍니다. 이러한 무한 반복이 이뤄지지 않도록 하거나 Find/FindNext/FindPrevious 메서드로는 너무 복잡한 검색을 수행하려는 경우 For Each 루프를 사용하여 범위 내의 모든 셀을 반복적으로 검색할 수 있습니다.

샘플 통합 문서의 Range Class 시트에 있는 Find 링크를 클릭하면 다음 프로시저가 실행됩니다.

' Visual Basic
Private Sub DemoFind()
    Dim rng As Excel.Range = ThisApplication.Range("Fruits")
    Dim rngFound As Excel.Range
 
    ' Keep track of the first range you find.
    Dim rngFoundFirst As Excel.Range
 
    ' You should specify all these parameters
    ' every time you call this method, since they
    ' can be overriden in the user interface.
    rngFound = rng.Find( _
      "apples", , _
      Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, _
      Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, 
      False)
    While Not rngFound Is Nothing
        If rngFoundFirst Is Nothing Then
            rngFoundFirst = rngFound
        ElseIf rngFound.Address = rngFoundFirst.Address Then
            Exit While
        End If
        With rngFound.Font
            .Color = ColorTranslator.ToOle(Color.Red)
            .Bold = True
        End With
        rngFound = rng.FindNext(rngFound)
    End While
End Sub
 
// C#
private void DemoFind()
{
    Excel.Range rng = ThisApplication.
        get_Range("Fruits", Type.Missing);
    Excel.Range rngFound;
 
    // Keep track of the first range you find.
    Excel.Range rngFoundFirst = null;
 
    // You should specify all these parameters
    // every time you call this method, since they
    // can be overriden in the user interface.
    rngFound = rng.Find("apples", Type.Missing, 
        Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, 
        Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, 
        false, Type.Missing, Type.Missing);
    while (rngFound != null)
    {
        if (rngFoundFirst == null ) 
        {
            rngFoundFirst = rngFound;
        }
        else if (GetAddress(rngFound) == GetAddress(rngFoundFirst))
        {
            break;
        }
        rngFound.Font.Color = ColorTranslator.ToOle(Color.Red);
        rngFound.Font.Bold = true;
        rngFound = rng.FindNext(rngFound);
    }
}

코드는 목적을 달성하기 위해 다음 작업을 수행합니다.

  • 전체 범위, 첫 번째 찾은 범위 및 현재 찾은 범위를 추적하기 위한 Excel.Range 변수를 선언합니다.
' Visual Basic
Dim rng As Excel.Range = ThisApplication.Range("Fruits")
Dim rngFound As Excel.Range
Dim rngFoundFirst As Excel.Range
 
// C#
Excel.Range rng = ThisApplication.
    get_Range("Fruits", Type.Missing);
Excel.Range rngFound;
Excel.Range rngFoundFirst = null;
  • 다음에 찾을 셀을 제외한 모든 매개 변수를 지정하여 첫 번째 일치되는 범위를 찾은 다음(기본적으로 검색은 범위의 왼쪽 위에 있는 셀부터 시작됨) 부분 값을 찾으면서 셀 값에서 "apples"를 찾습니다. 이 때 검색은 대소문자를 구분하지 않으며 진행 방향으로 열 순서대로 진행됩니다.
' Visual Basic
rngFound = rng.Find( _
  "apples", , _
  Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, _
  Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, _
  False)
 
// C#
rngFound = rng.Find("apples", Type.Missing, 
    Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, 
    Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, 
    false, Type.Missing, Type.Missing);
  • 일치 대상을 찾는 동안 검색이 계속됩니다.
' Visual Basic
While Not rngFound Is Nothing
    ' Code removed here...
End While
 
// C#
while (rngFound != null)
{
    // Code removed here...
}
  • 첫 번째 찾은 범위(rngFoundFirst)를 Nothing과 비교합니다. 이는 코드에서 첫 번째 일치 대상을 찾은 경우에만 가능합니다. 이 경우 코드는 찾은 범위를 저장합니다. 그렇지 않으면 찾은 범위의 주소가 첫 번째 찾은 범위의 주소와 일치하는 경우 코드에서 루프가 종료됩니다.
' Visual Basic
If rngFoundFirst Is Nothing Then
    rngFoundFirst = rngFound
ElseIf rngFound.Address = rngFoundFirst.Address Then
    Exit While
End If
 
// C#
if (rngFoundFirst == null ) 
{
    rngFoundFirst = rngFound;
}
else if (GetAddress(rngFound) == GetAddress(rngFoundFirst))
{
    break;
}
  • 찾은 범위의 모양을 설정합니다.
' Visual Basic
With rngFound.Font
    .Color = ColorTranslator.ToOle(Color.Red)
    .Bold = True
End With
 
// C#
rngFound.Font.Color = ColorTranslator.ToOle(Color.Red);
rngFound.Font.Bold = true;
  • 다른 검색을 수행합니다.
' Visual Basic
rngFound = rng.FindNext(rngFound)
 
// C#
rngFound = rng.FindNext(rngFound);

샘플 시트에서 Reset Find 링크를 클릭하면 범위를 시작 상태로 되돌리는 아래와 같은 간단한 프로시저가 실행됩니다.

' Visual Basic
Private Sub ResetFind()
    Dim rng As Excel.Range = ThisApplication.Range("Fruits")
    With rng.Font
        .Color = ColorTranslator.ToOle(Color.Black)
        .Bold = False
    End With
End Sub
// C#
private void ResetFind()
{
    Excel.Range rng = ThisApplication.
        get_Range("Fruits", Type.Missing);
    rng.Font.Color = ColorTranslator.ToOle(Color.Black);
    rng.Font.Bold = false;
}

:   범위 내에서 찾기와 바꾸기를 모두 수행하려는 경우 Range.Replace 메서드를 확인하십시오. 이 메서드는 Find 메서드와 거의 비슷하게 작동하지만 바꿀 값을 지정할 수 있습니다. Replace 메서드는 바꾸기를 수행했는지 여부를 나타내는 Boolean 값을 반환합니다. 한 개의 값이라도 바뀐 경우 결과는 True로 반환됩니다.

범위 내의 데이터 정렬

Excel 사용자 인터페이스에서 범위 내의 데이터를 정렬할 수 있는 것과 동일하게 프로그래밍 방식으로도 Range.Sort 메서드를 사용하여 데이터를 정렬할 수 있습니다. 정렬할 범위를 나타내고, 선택적으로 최대 3개의 행 또는 열을 정렬하도록 지정한 다음 일부 옵션 매개 변수를 지정하면 나머지 작업은 Excel이 처리합니다. 5Sort 메서드의 모든 매개 변수를 보여줍니다. Visual Basic .NET 개발자는 이들 매개 변수 중에서 일부만 사용할 수 있지만, C# 개발자는 각 매개 변수에 대한 값을 제공해야 합니다.

5. Sort 메서드의 매개 변수

매개 변수 유형 설명
Key1 Object (String 또는 Range) 범위 이름(String) 또는 Range 개체의 첫 번째 정렬 필드로, 정렬할 값을 결정합니다.
Order1 XlSortOrder (xlAscending, xlDescending) Key1에서 지정한 값에 대한 정렬 순서를 결정합니다.
Key2 Object (String or Range) 두 번째 정렬 필드로서 피벗 테이블을 정렬할 때는 사용할 수 없습니다.
Type Object 피벗 테이블을 정렬할 때 정렬될 요소를 지정하며 일반 범위에는 영향을 주지 않습니다.
Order2 XlSortOrder Key2에서 지정한 값에 대한 정렬 순서를 결정합니다.
Key3 Object (String or Range) 세 번째 정렬 필드로서 피벗 테이블을 정렬할 때는 사용할 수 없습니다.
Order3 XlSortOrder Key3에서 지정한 값에 대한 정렬 순서를 결정합니다.
Header XlYesNoGuess (xlGuess, xlNo, xlYes) 첫 번째 행에 헤더 정보가 포함되는지 여부를 지정합니다. 기본값은 xlNo입니다. Excel이 무작위로 선택하도록 하려면 xlGuess를 선택합니다.
OrderCustom Integer 사용자 지정 정렬 목록으로 1기준 인덱스를 지정합니다. 이 매개 변수를 빈 값으로 두면 기본 정렬 순서를 사용합니다. 그림 28은 사용자 지정 정렬 순서 생성을 위한 기술을 보여줍니다. 이 예제의 경우 이 매개 변수에 6을 지정하면 "fruits" 사용자 지정 순서에 따라 정렬을 수행합니다.
MatchCase Boolean 정렬 시 대소문자를 구분하려면 True로 설정하고 구분하지 않으려면 False로 설정합니다. 피벗 테이블에는 사용할 수 없습니다.
Orientation XlSortOrientation (xlSortRows, xlSortColumns) 정렬 방향입니다.
SortMethod XlSortMethod (xlStroke, xlPinYin) 정렬 방법을 지정합니다. 현재 값은 중국어 정렬에 사용되기 때문에 다른 언어에는 아무런 영향을 주지 않습니다. 이 매개 변수는 일부 언어에 대해서는 적용되지 않습니다.
DataOption1 XlSortDataOption (xlSortTextAsNumbers, xlSortNormal) Key1에서 지정된 범위에서 텍스트를 정렬하는 방법을 지정합니다. 피벗 테이블 정렬에는 적용되지 않습니다.
DataOption2 XlSortDataOption Key2에서 지정된 범위에서 텍스트를 정렬하는 방법을 지정합니다. 피벗 테이블 정렬에는 적용되지 않습니다.
DataOption3 XlSortDataOption Key3에서 지정된 범위에서 텍스트를 정렬하는 방법을 지정합니다. 피벗 테이블 정렬에는 적용되지 않습니다.

excelobj028.gif

그림 28. 사용자는 자신의 사용자 지정 정렬 목록을 만든 다음 코드에서 특정 정렬 순서를 참조할  있습니다.

Range Class 샘플 시트에서 Sort 링크를 클릭하면 다음과 같은 프로시저가 실행되어 첫 번째 열의 데이터에 따라 Fruits 범위를 정렬하고 그 다음에는 두 번째 열의 데이터에 따라 정렬을 수행합니다.

' Visual Basic
Private Sub DemoSort()
    Dim rng As Excel.Range = ThisApplication.Range("Fruits")
    rng.Sort( _
      Key1:=rng.Columns(1), Order1:=Excel.XlSortOrder.xlAscending, _
      Key2:=rng.Columns(2), Order2:=Excel.XlSortOrder.xlAscending, _
      Orientation:=Excel.XlSortOrientation.xlSortColumns, _
      Header:=Excel.XlYesNoGuess.xlNo)
End Sub
 
// C#
private void DemoSort()
{
        Excel.Range rng = ThisApplication.
            get_Range("Fruits", Type.Missing);
 
        rng.Sort(rng.Columns[1, Type.Missing], 
            Excel.XlSortOrder.xlAscending, 
            rng.Columns[2, Type.Missing],Type.Missing, 
            Excel.XlSortOrder.xlAscending,
            Type.Missing, Excel.XlSortOrder.xlAscending,
            Excel.XlYesNoGuess.xlNo, Type.Missing, Type.Missing,
            Excel.XlSortOrientation.xlSortColumns, 
            Excel.XlSortMethod.xlPinYin,
            Excel.XlSortDataOption.xlSortNormal, 
            Excel.XlSortDataOption.xlSortNormal,
            Excel.XlSortDataOption.xlSortNormal);
}

같은 시트에서 Reset Sort 링크를 클릭하면 다음 프로시저가 실행되어 그림 28에 표시된 사용자 지정 정렬에 따라 두 번째 행을 정렬합니다.

' Visual Basic
Private Sub ResetSort()
    Dim rng As Excel.Range = ThisApplication.Range("Fruits")
    rng.Sort(rng.Columns(2), OrderCustom:=6, _
    Orientation:=Excel.XlSortOrientation.xlSortColumns, _
    Header:=Excel.XlYesNoGuess.xlNo)
End Sub
 
// C#
private void ResetSort()
{
    Excel.Range rng = ThisApplication.
        get_Range("Fruits", Type.Missing);
        rng.Sort(rng.Columns[2, Type.Missing],
            Excel.XlSortOrder.xlAscending, 
            Type.Missing, Type.Missing, Excel.XlSortOrder.xlAscending,
            Type.Missing, Excel.XlSortOrder.xlAscending,
            Excel.XlYesNoGuess.xlNo, 6, Type.Missing,
            Excel.XlSortOrientation.xlSortColumns, 
            Excel.XlSortMethod.xlPinYin,
            Excel.XlSortDataOption.xlSortNormal, 
            Excel.XlSortDataOption.xlSortNormal,
            Excel.XlSortDataOption.xlSortNormal);
}

다음 단계

이 문서의 내용이 길게 느껴질 수도 있지만, 본 문서의 내용은 Excel 개체 모델에서 제공되는 매우 다양한 기능을 간략하게 다룬 것에 지나지 않습니다. 본 문서에서는 Application, Workbook, WorksheetRange와 같은 가장 중요한 클래스들에 대해 소개했지만, 그 외 유용한 많은 클래스들에 대해서는 다루지 않았습니다. 예를 들어 PivotTableChart와 같이 Excel 개체 모델에서 제공되는 두 번째 클래스 "층"에 대한 자세한 조사가 더 필요할 수도 있습니다. Excel 개체 모델을 완벽하게 이해하면 자신에게 필요한 클래스를 찾기 위해 노력한다면 어떠한 자동화된 작업이든 쉽게 수행할 수 있을 것입니다. 본 문서의 내용과 개체 찾아보기 및 Excel VBA 온라인 도움말을 참조하여 Excel에서 수행할 수 있는 모든 작업들을 찾아 보시기 바랍니다.