시트가 있는지 테스트 또는 확인


115
Dim wkbkdestination As Workbook
Dim destsheet As Worksheet

For Each ThisWorkSheet In wkbkorigin.Worksheets 
    'this throws subscript out of range if there is not a sheet in the destination 
    'workbook that has the same name as the current sheet in the origin workbook.
    Set destsheet = wkbkdestination.Worksheets(ThisWorkSheet.Name) 
Next

기본적으로 원본 통합 문서의 모든 시트를 반복 한 다음 destsheet대상 통합 문서에서 원본 통합 문서 의 현재 반복 된 시트와 동일한 이름을 가진 시트로 설정합니다.

해당 시트가 있는지 어떻게 테스트 할 수 있습니까? 다음과 같은 것 :

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 

답변:


173

일부 사람들은 오류 처리의 "부적절한"사용으로 인해이 접근 방식을 싫어하지만 VBA에서는 허용되는 것으로 간주됩니다. 대체 접근 방식은 일치하는 항목을 찾을 때까지 모든 시트를 반복하는 것입니다.

Function WorksheetExists(shtName As String, Optional wb As Workbook) As Boolean
    Dim sht As Worksheet

    If wb Is Nothing Then Set wb = ThisWorkbook
    On Error Resume Next
    Set sht = wb.Sheets(shtName)
    On Error GoTo 0
    WorksheetExists = Not sht Is Nothing
End Function

5
IMO를 완전히 적절하게 사용하십시오. 그것은 존재하는 것으로 상정하지 않는 긴 역사를 가지고하는 일에 대한 함정 - CF 펄 엄격한, STAE 등 Upvoted
우당

13
하나는 아마 사용해야합니다 ActiveWorkbook대신 ThisWorkbook. 후자는 테스트하려는 통합 문서와는 다를 수있는 매크로 코드가 포함 된 통합 문서를 나타냅니다. 나는 ActiveWorkbook대부분의 경우에 유용 할 것이라고 생각한다 (하지만 인위적인 상황은 항상 이용 가능하다).
sancho.s ReinstateMonicaCellio 2014 년

3
sht Is Nothing될 것입니다 True거기 이름을 가진 시트 없다, 그러나 우리는 반환 할 경우 True이 경우 이다 따라서 아니, 그 이름의 시트. 좀 더 쉽게 (하지만 유효하지 않음) 조금 재조정하면SheetExists = sht Is Not Nothing
Tim Williams

3
참고로 좋은 당신이 당신의 개인용 매크로 통합 문서에이 코드를 실행하면, 변화와 If wb Is Nothing Then Set wb = ThisWorkbookIf wb Is Nothing Then Set wb = ActiveWorkbook
헨릭 K

2
이것은 매우 효율적인 접근 방식입니다 (아래 Rory의 답변 아래 벤치 마크에 대한 내 의견 참조). (지금 현재) 당신은 0 개의 반대표를 가지고 있습니다.
rory.ap

107

특별히 워크 시트에만 관심이있는 경우 간단한 Evaluate 호출을 사용할 수 있습니다.

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function

14
@Rory 나는이 대 Tim Williams의 답변에 대한 벤치 마크 테스트를 실행했습니다. 500,000 개가 넘는 루프에서 22 초가 걸렸고 Tim은 1 번 미만이었습니다.
rory.ap

17
@roryap-이 500,000 번 실행해야한다면 전체 접근 방식을 재고해야합니다. ;)
Rory

9
@roryap-그러나 몇 가지 느린 방법을 사용하면 몇 초가 쌓이기 시작합니다. Excel "응용 프로그램"이 다양한 Range 메서드 등을 사용하여 매우 쉽게 몇 초 동안
쌓이기

4
@roryap-그 정보는 어떤면에서 대화에 가치가 있습니까? 단순히 코드 주위에 비효율적 인 메서드를 분산 시키면 애플리케이션 전체가 느려질 것이라고 말씀 드리고 싶습니다. 이 50 만 번 테스트 해주셔서 감사합니다. 22 초는 좋지 않습니다. (나는 당신과 동의)
tedcurrent

6
느리더라도 받아 들여지는 대답보다 훨씬 깨끗한 솔루션처럼 보입니다. 나에게서 +1.
Sascha L.

49

이를 수행하기 위해 오류 처리가 필요하지 않습니다. 모든 워크 시트를 반복하고 지정된 이름이 있는지 확인하기 만하면됩니다.

For i = 1 To Worksheets.Count
    If Worksheets(i).Name = "MySheet" Then
        exists = True
    End If
Next i

If Not exists Then
    Worksheets.Add.Name = "MySheet"
End If

21

컬렉션의 구성원을 확인하는 것이 일반적인 문제이므로 다음은 Tim의 답변을 추상화 한 버전입니다.

함수 Contains (objCollection As Object, strName as String) As Boolean
    개체로 Dim o
    오류시 다음 재개
    o = objCollection (strName) 설정
    포함 = (Err.Number = 0)
    Err. Clear
 끝 기능

이 기능 (오브젝트와 같은 모음으로 사용될 수있는 Shapes, Range, Names, Workbooks, 등).

시트의 존재를 확인하려면 If Contains(Sheets, "SheetName") ...


5
Set키워드에 의해 오류가 발생하므로 컬렉션에서 기본 유형을 포착하지 못합니다 . 내가 사용하는 대신 그 발견 Set요구, TypeName모든 경우, 즉의 수집 작품의 회원의TypeName objCollection(strName)
citizenkong

2
@Peter : 기능이 종료되기 전에 존재하지 않는 경우에 발생하는 오류를 제거하기 위해 err.clear 또는 On Error Resume Next 중 하나를 추가하는 것이 가장 좋습니다. 그렇지 않으면 다음과 같은 경우 호출 프로 시저의 오류 처리가 실수로 트리거 될 수 있습니다. Sub Test() On Error GoTo errhandler Debug.Print Contains(Workbooks, "SomeBookThatIsNotOpen") errhandler: If Err.Number <> 0 Then Stop End Sub
jeffreyweir

16

수정 됨 : 오류 처리 없음 :

Function CheckIfSheetExists(SheetName As String) As Boolean
      CheckIfSheetExists = False
      For Each WS In Worksheets
        If SheetName = WS.name Then
          CheckIfSheetExists = True
          Exit Function
        End If
      Next WS
End Function

14

누구나 VBA를 피하고 워크 시트가 순수하게 셀 수식 내에 존재하는지 테스트하려는 경우 ISREFINDIRECT함수를 사용할 수 있습니다.

=ISREF(INDIRECT("SheetName!A1"))

이 반환됩니다 TRUE통합 문서라는 시트가 포함되어있는 경우 SheetNameFALSE그렇지.


12

나는 이것을 썼다.

Function sheetExist(sSheet As String) As Boolean
On Error Resume Next
sheetExist = (ActiveWorkbook.Sheets(sSheet).Index > 0)
End Function

1
훌륭한 기능! 빠를뿐만 아니라 가장 간결합니다.
ChrisB

나는이 대답은 믿습니다 그 질문에 해당하는 대부분의
후안 호야

난이게 좋아. 부울 함수이기 때문에 sheetExist의 기본값이 False가된다는 사실에 의존합니다. 할당 문은 시트가 존재하지 않으면 실제로 False 값을 sheetExist에 할당하지 않고 오류가 발생하고 기본값을 그대로 둡니다. 원하는 경우 부울 변수에 할당 된 0이 아닌 값이 True 결과를 제공하고> 0 비교를 생략한다는 사실을 신뢰할 수 있습니다. sheetExist = ActiveWorkbook.Sheets(sSheet).Index
oddacorn

5

내 솔루션은 Tims와 비슷하지만 워크 시트 시트가 아닌 경우에도 작동합니다.

Public Function SheetExists(strSheetName As String, Optional wbWorkbook As Workbook) As Boolean
    If wbWorkbook Is Nothing Then Set wbWorkbook = ActiveWorkbook 'or ThisWorkbook - whichever appropriate
    Dim obj As Object
    On Error GoTo HandleError
    Set obj = wbWorkbook.Sheets(strSheetName)
    SheetExists = True
    Exit Function
HandleError:
    SheetExists = False
End Function

.


3

테스트를 함수에 넣으면 다시 사용할 수 있고 코드 가독성이 향상됩니다.

"On Error Resume Next"는 코드의 다른 부분과 충돌 할 수 있으므로 사용하지 마십시오.

Sub DoesTheSheetExists()
    If SheetExist("SheetName") Then
        Debug.Print "The Sheet Exists"
    Else
        Debug.Print "The Sheet Does NOT Exists"
    End If
End Sub

Function SheetExist(strSheetName As String) As Boolean
    Dim i As Integer

    For i = 1 To Worksheets.Count
        If Worksheets(i).Name = strSheetName Then
            SheetExist = True
            Exit Function
        End If
    Next i
End Function

3

수년이 늦었지만 저는이 작업을 수행해야했고 게시 된 솔루션이 마음에 들지 않았습니다 ... 그래서 (SpongeBob 무지개 손 제스처) "Evaluate ()"의 마법 덕분에 하나를 만들었습니다!

Evaluate("IsError(" & vSheetName & "!1:1)")

Sheet가 없으면 TRUE를 반환합니다. 시트가 있으면 FALSE입니다. "1 : 1"을 원하는 범위로 대체 할 수 있지만 단일 셀을 사용하지 않는 것이 좋습니다. 오류 (예 : # N / A)가 포함 된 경우 True를 반환합니다.


3

컴팩트 wsExists기능 ( 오류 처리에 의존 하지 않음 !)

여기에 워크 시트가 존재하는지 여부를 결정하는 오류 처리에 의존하지 않는 짧은 및 간단한 함수이다 ( 그리고 제대로 직장에 선언 어떤 상황!)

Function wsExists(wsName As String) As Boolean
    Dim ws: For Each ws In Sheets
    wsExists = (wsName = ws.Name): If wsExists Then Exit Function
    Next ws
End Function

사용 예 :

다음 예제에서는라는 새 워크 시트 myNewSheet가 아직없는 경우 추가 합니다.

If Not wsExists("myNewSheet") Then Sheets.Add.Name = "myNewSheet"

추가 정보:


2

명명 된 워크 시트가 있는지 확인하기 위해 작은 루프를 사용하지 않는 이유는 무엇입니까? 현재 열려있는 통합 문서에서 "Sheet1"이라는 이름의 워크 시트를 찾고 있다고 가정합니다.

Dim wb as Workbook
Dim ws as Worksheet

Set wb = ActiveWorkbook

For Each ws in wb.Worksheets

    if ws.Name = "Sheet1" then
        'Do something here
    End if

Next

2

WorksheetFunction.영어가 아닌 Excel을 사용 하는 팬 이거나 영어가 아닌 국가에서 일하는 경우 다음과 같은 좋은 솔루션입니다.

WorksheetFunction.IsErr(Evaluate("'" & wsName & "'!A1"))

또는 다음과 같은 함수에서 :

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Not WorksheetFunction.IsErr(Evaluate("'" & sName & "'!A1"))
End Function

1
Public Function WorkSheetExists(ByVal strName As String) As Boolean
   On Error Resume Next
   WorkSheetExists = Not Worksheets(strName) Is Nothing
End Function

sub test_sheet()

 If Not WorkSheetExists("SheetName") Then
 MsgBox "Not available"
Else MsgBox "Available"
End If

End Sub

1
    For Each Sheet In Worksheets
    If UCase(Sheet.Name) = "TEMP" Then
    'Your Code when the match is True
        Application.DisplayAlerts = False
        Sheet.Delete
        Application.DisplayAlerts = True
    '-----------------------------------
    End If
Next Sheet

1

"데이터"를 테스트하려는 시트 이름으로 변경하십시오.

On Error Resume Next 

Set DataSheet = Sheets("Data")

If DataSheet Is Nothing Then

     Sheets.Add(after:=ActiveSheet).Name = "Data"
     ''or whatever alternate code you want to execute''
End If

On Error GoTo 0

1

위의 함수가 작동 할 수 있다는 의심의 여지없이, 다음 코드로 끝났습니다.

Sub Sheet_exist ()
On Error Resume Next
If Sheets("" & Range("Sheet_Name") & "") Is Nothing Then
    MsgBox "doesnt exist"
Else
    MsgBox "exist"
End if
End sub

참고 : Sheets_Name사용자에게 이름을 입력하도록 요청하는 곳이므로 귀하에게는 동일하지 않을 수 있습니다.


0

나는 또 다른 일을했다 : 존재하는 경우에만 시트를 삭제하고 그렇지 않은 경우 오류가 발생하지 않습니다.

Excel.DisplayAlerts = False 
Dim WS
For Each WS In Excel.Worksheets
    If WS.name = "Sheet2" Then
        Excel.sheets("Sheet2").Delete
        Exit For
    End If
Next
Excel.DisplayAlerts = True

0

쉽게 할 수있는 방법을 생각해 냈지만 새로운 서브를 만들지는 않았습니다. 대신, 나는 내가 작업하고있는 잠수함 안에서 단지 "수표를했다". 찾고있는 시트 이름이 "Sheet_Exist"라고 가정하고 찾은 경우 활성화하려고합니다.

Dim SheetCounter As Integer

SheetCounter = 1

Do Until Sheets(SheetCounter).Name = "Sheet_Exist" Or SheetCounter = Sheets.Count + 1
 SheetCounter = SheetCounter +1
Loop
If SheetCounter < Sheets.Count + 1 Then
 Sheets("Sheet_Exist").Activate
Else
 MsgBox("Worksheet ""Sheet_Exist"" was NOT found")
End If

시트가 존재하지 않는 경우에도 팝업을 추가했습니다.


0

나는 그것이 오래된 게시물이라는 것을 알고 있지만 여기에 빠른 또 다른 간단한 해결책이 있습니다.

Public Function worksheetExists(ByVal wb As Workbook, ByVal sheetNameStr As String) As Boolean

On Error Resume Next
worksheetExists = (wb.Worksheets(sheetNameStr).Name <> "")
Err.Clear: On Error GoTo 0

End Function

0

짧고 깨끗한 :

Function IsSheet(n$) As Boolean
    IsSheet = Not IsError(Evaluate(n & "!a1"))
End Function

-4

실제로 시트가 있는지 확인한 다음 몇 가지 명령을 실행하는 간단한 방법이 있습니다.

제 경우에는 시트를 삭제하고 같은 이름의 동일한 시트를 다시 만들고 싶었지만 프로그램이 이미 삭제되어 시트를 삭제할 수 없으면 코드가 중단되었습니다.

Sub Foo ()

    Application.DisplayAlerts = False

    On Error GoTo instructions
    Sheets("NAME OF THE SHEET").Delete

    instructions:

    Sheets.Add After:=Sheets(Sheets.Count)
    ActiveSheet.Name = "NAME OF THE SHEET"

End Sub

이 답변의 문제는 시트가 실제로 존재한다고 판단하면 삭제되어 더 이상 존재하지 않는다는 것입니다. 이것이 함수로 작성된 경우 SheetExistsAfterDeletion과 같은 이름을 가질 수 있으며 항상 FALSE를 반환합니다.
ChrisB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.