수색…


자격 기준

worksheet , range 또는 개별 cells 참조 할 때는 참조를 완전히 한정하는 것이 중요합니다.

예 :

ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 2), Cells(2, 3)).Copy

완전하지 않음 : Cells 참조에 워크 북과 워크 시트가 없습니다. 명시 적 참조없이 셀은 기본적으로 ActiveSheet 를 참조합니다. Sheet1 이외의 워크 시트를 현재 ActiveSheet 경우이 코드는 실패합니다 (잘못된 결과를 생성합니다).

이 문제를 해결하는 가장 쉬운 방법은 With 문을 다음과 같이 사용하는 것입니다.

With ThisWorkbook.Worksheets("Sheet1")
    .Range(.Cells(1, 2), .Cells(2, 3)).Copy
End With

또는 워크 시트 변수를 사용할 수 있습니다. (한 시트에서 다른 시트로 데이터를 복사하는 것과 같이 코드가 여러 워크 시트를 참조해야하는 경우 가장 선호되는 방법입니다.)

Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
ws1.Range(ws1.Cells(1, 2), ws1.Cells(2, 3)).Copy

다른 자주 발생하는 문제는 통합 문서를 한정하지 않고 Worksheets 컬렉션을 참조하는 것입니다. 예 :

Worksheets("Sheet1").Copy

워크 시트 Sheet1 완전하지 않으며 통합 문서가 부족합니다. 여러 통합 문서가 코드에서 참조되는 경우이 작업이 실패 할 수 있습니다. 대신 다음 중 하나를 사용하십시오.

ThisWorkbook.Worksheets("Sheet1")       '<--ThisWorkbook refers to the workbook containing 
                                        'the running VBA code
Workbooks("Book1").Worksheets("Sheet1") '<--Where Book1 is the workbook containing Sheet1

그러나 다음을 사용하지 마십시오.

ActiveWorkbook.Worksheets("Sheet1")     '<--Valid, but if another workbook is activated
                                        'the reference will be changed

마찬가지로 range 객체의 경우 명시 적으로 정규화되지 않으면 range 는 현재 활성 시트를 참조합니다.

Range("a1")

와 같다:

ActiveSheet.Range("a1")

루프에서 행 또는 열 삭제

루프에서 행 (또는 열)을 삭제하려면 범위 끝에 끝나고 항상 루프를 반복해야합니다. 코드를 사용하는 경우 :

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 1 To 4
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

당신은 몇 줄을 놓칠 것입니다. 예를 들어, 코드가 행 3을 삭제하면 행 4는 행 3이됩니다. 그러나 변수 i 는 4로 변경됩니다. 따라서이 경우 코드는 한 행을 놓치고 이전에 범위에 없었던 다른 행을 검사합니다.

올바른 코드는

Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 4 To 1 Step -1
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With

ActiveWorkbook 대 ThisWorkbook

ActiveWorkbookThisWorkbook 은 각 개체가 어떤 개체와 관련되는지 완전히 이해하지 않으면 서 VBA의 새로운 사용자가 상호 교환하여 사용할 수있는 경우가 있으며 이로 인해 런타임에 바람직하지 않은 동작이 발생할 수 있습니다. 이 두 개체는 Application 개체에 속합니다.


ActiveWorkbook 개체는 현재 실행시 Excel 응용 프로그램 개체의 최상위보기에있는 통합 문서를 참조합니다. (예 :이 객체를 참조 할 때 볼 수 있고 상호 작용할 수있는 통합 문서)

Sub ActiveWorkbookExample()

'// Let's assume that 'Other Workbook.xlsx' has "Bar" written in A1.

    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Foo"
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Foo"

    Workbooks.Open("C:\Users\BloggsJ\Other Workbook.xlsx")
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"

    Workbooks.Add 1
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints nothing

End Sub

ThisWorkbook 개체는 코드가 실행될 때 코드가 속한 통합 문서를 나타냅니다.

Sub ThisWorkbookExample()

'// Let's assume to begin that this code is in the same workbook that is currently active

    ActiveWorkbook.Sheet1.Range("A1").Value = "Foo"
    Workbooks.Add 1
    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Bar"

    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"
    Debug.Print ThisWorkbook.Sheet1.Range("A1").Value '// Prints "Foo"

End Sub

단일 문서 인터페이스 대 다중 문서 인터페이스

Microsoft Excel 2013 (이상)은 SDI (Single Document Interface)를 사용하고 Excel 2010 (및 그 이하)은 MDI (Multiple Document Interfaces)를 사용합니다.

즉, Excel 2013 (SDI)의 경우 Excel의 단일 인스턴스에있는 각 통합 문서에는 자체 리본 UI가 포함됩니다.

여기에 이미지 설명을 입력하십시오.

반대로 Excel 2010의 경우 Excel의 단일 인스턴스에있는 각 통합 문서는 공통 리본 UI (MDI)를 사용했습니다. 여기에 이미지 설명을 입력하십시오.

이렇게하면 리본과 상호 작용하는 VBA 코드 (2010 <-> 2013)를 마이그레이션하려는 경우 몇 가지 중요한 문제가 발생합니다.

Excel 2013 이상의 모든 통합 문서에서 동일한 상태의 리본 UI 컨트롤을 업데이트하려면 프로 시저를 만들어야합니다.

참고 사항 :

  1. 모든 Excel 응용 프로그램 수준 창 메서드, 이벤트 및 속성은 영향을받지 않습니다. ( Application.ActiveWindow , Application.Windows ...)
  2. Excel 2013 이상 (SDI)에서는 모든 통합 문서 수준 창 메서드, 이벤트 및 속성이 최상위 창에서 작동합니다. Application.Hwnd 를 사용하여이 최상위 레벨 창 핸들을 검색 할 수 있습니다.

자세한 내용은 MSDN 의이 예제 소스를 참조하십시오.

이것은 또한 모덜리스 사용자 폼에 몇 가지 문제를 일으 킵니다. 해결책을 보려면 여기 를 참조하십시오.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow