수색…
자격 기준
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
ActiveWorkbook
및 ThisWorkbook
은 각 개체가 어떤 개체와 관련되는지 완전히 이해하지 않으면 서 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 컨트롤을 업데이트하려면 프로 시저를 만들어야합니다.
참고 사항 :
- 모든 Excel 응용 프로그램 수준 창 메서드, 이벤트 및 속성은 영향을받지 않습니다. (
Application.ActiveWindow
,Application.Windows
...) - Excel 2013 이상 (SDI)에서는 모든 통합 문서 수준 창 메서드, 이벤트 및 속성이 최상위 창에서 작동합니다.
Application.Hwnd
를 사용하여이 최상위 레벨 창 핸들을 검색 할 수 있습니다.
자세한 내용은 MSDN 의이 예제 소스를 참조하십시오.
이것은 또한 모덜리스 사용자 폼에 몇 가지 문제를 일으 킵니다. 해결책을 보려면 여기 를 참조하십시오.