Teste ou verifique se a folha existe


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

Basicamente, eu faço um loop por todas as planilhas na pasta de trabalho de origem e, destsheetem seguida, configuro na pasta de destino para a planilha com o mesmo nome da atualmente iterada na pasta de trabalho de origem.

Como posso testar se essa folha existe? Algo como:

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 

Respostas:


173

Algumas pessoas não gostam dessa abordagem por causa de um uso "inadequado" de tratamento de erros, mas acho que é considerado aceitável no VBA ... Uma abordagem alternativa é percorrer todas as folhas até encontrar uma correspondência.

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
Use IMO totalmente apropriado. É uma armadilha para algo que é postulado como existente e não existe e tem uma longa história - cf perl strict, STAE etc. Aprovado
Wudang

13
Provavelmente deve-se usar em ActiveWorkbookvez de ThisWorkbook. O último se refere à pasta de trabalho que contém o código de macro, que pode ser diferente da pasta de trabalho que se deseja testar. Eu acho ActiveWorkbookque seria útil para a maioria dos casos (porém, situações planejadas estão sempre disponíveis).
sancho.s ReinstateMonicaCellio

3
sht Is Nothingserá Truese não há nenhuma folha com esse nome, mas queremos voltar Truese não é uma folha com esse nome, daí o não. É um pouco mais fácil (mas não válido) se você reorganizar um pouco paraSheetExists = sht Is Not Nothing
Tim Williams,

3
É bom observar que, se você executar este código em sua pasta de trabalho de macro pessoal, mude de If wb Is Nothing Then Set wb = ThisWorkbookparaIf wb Is Nothing Then Set wb = ActiveWorkbook
Henrik K

2
Esta é uma abordagem altamente eficiente (veja meus comentários sobre benchmarks sob a resposta de Rory abaixo), então quem se importa com o que os detratores pensam. Observe (a partir de agora) que você tem zero votos negativos.
rory.ap

107

Se você estiver especificamente interessado apenas em planilhas, pode usar uma chamada simples de Avaliação:

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

14
@Rory Fiz alguns testes de benchmark sobre a resposta de Tim Williams. Mais de 500.000 loops, o seu demorou 22 segundos e o do Tim <1.
rory.ap

17
@roryap - se você precisa executar isso 500.000 vezes, você precisa repensar toda a sua abordagem. ;)
Rory

9
@roryap - entretanto, o uso de vários métodos lentos vai começar a acumular segundos. Eu diria que esta é uma informação extremamente valiosa, já que os "aplicativos" do Excel começam a acumular segundos facilmente com vários métodos de alcance etc.
tedcurrent

4
@roryap - essa informação é valiosa para a conversa de que maneira? Estou simplesmente afirmando que espalhar métodos ineficientes em seu código tornará o aplicativo lento como um todo. você testar 500 mil vezes é incrível e eu agradeço por fazer isso, 22 segundos não é ótimo. (Eu concordo com você)
tedcurrent

6
Mesmo que seja mais lento, parece uma solução muito mais limpa do que a resposta aceita. +1 de mim.
Sascha L.

49

Você não precisa de tratamento de erros para fazer isso. Tudo que você precisa fazer é iterar sobre todas as planilhas e verificar se o nome especificado existe:

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

Como verificar os membros de uma coleção é um problema geral, aqui está uma versão resumida da resposta de Tim:

Função Contains (objCollection As Object, strName as String) As Boolean
    Dim o como objeto
    Em caso de erro, continuar próximo
    definir o = objCollection (strName)
    Contém = (Err.Number = 0)
    Err.Clear
 Função Final

Esta função pode ser utilizada com qualquer conjunto como objecto ( Shapes, Range, Names, Workbooks, etc.).

Para verificar a existência de uma folha, use If Contains(Sheets, "SheetName") ...


5
Isso não captura tipos primitivos em Coleções, pois um erro será gerado pela Setpalavra - chave. Descobri que ao invés de usar Set, pedindo a TypeNamedo membro dos trabalhos de recolha para todos os casos, ou sejaTypeName objCollection(strName)
citizenkong

2
@Peter: Melhor adicionar algo para limpar o erro que será gerado no caso de não existência antes que a função seja encerrada - um err.clear ou On Error Resume Next. Caso contrário, o tratamento de erros no procedimento de chamada poderia ser acionado inadvertidamente em casos como o seguinte. Sub Test() On Error GoTo errhandler Debug.Print Contains(Workbooks, "SomeBookThatIsNotOpen") errhandler: If Err.Number <> 0 Then Stop End Sub
jeffreyweir

16

Corrigido: sem tratamento de erros:

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

Caso alguém queira evitar o VBA e testar se uma planilha existe puramente dentro de uma fórmula de célula, é possível usar as funções ISREFe INDIRECT:

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

Isso retornará TRUEse a pasta de trabalho contiver uma planilha chamada SheetNamee de FALSEoutra forma.


12

Eu escrevi este aqui:

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

1
Excelente função! Além de rápido, é também o mais conciso.
ChrisB

Eu acredito que esta é a resposta que mais corresponde à pergunta
Juan Joya

Eu gosto deste. Observe que se baseia no fato de que o valor padrão para sheetExist será False, pois é uma função booleana. A instrução de atribuição não atribui realmente um valor False a sheetExist se a planilha não existir, ela apenas apresenta um erro e deixa o valor padrão no lugar. Se desejar, você pode confiar no fato de que qualquer valor diferente de zero atribuído a uma variável booleana dará um resultado True e deixará de fora a comparação> 0, como: sheetExist = ActiveWorkbook.Sheets(sSheet).Index
oddacorn

5

Minha solução se parece muito com Tims, mas também funciona no caso de planilhas que não são de planilha - gráficos

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

Coloque o teste em uma função e você poderá reutilizá-lo e terá melhor legibilidade do código.

NÃO use "On Error Resume Next", pois pode entrar em conflito com outra parte do seu código.

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

Muitos anos atrasado, mas eu só precisava fazer isso e não gostei de nenhuma das soluções postadas ... Então inventei uma, tudo graças à magia de (gesto do arco-íris do Bob Esponja) "Avalie ()"!

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

Retorna TRUE se a planilha NÃO existir; FALSE se a planilha EXISTIR. Você pode substituir qualquer intervalo que desejar por "1: 1", mas não aconselho usar uma única célula, porque se ela contiver um erro (por exemplo, # N / A), retornará True.


3

wsExistsFunção compacta ( sem dependência de tratamento de erros!)

Esta é uma função curta e simples que não depende do tratamento de erros para determinar se uma planilha existe ( e é declarada corretamente para funcionar em qualquer situação!)

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

Exemplo de uso:

O exemplo a seguir adiciona uma nova planilha chamada myNewSheet, se ainda não existir:

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

Mais Informações:


2

Por que não apenas usar um pequeno loop para determinar se a planilha nomeada existe? Digamos que você esteja procurando uma planilha chamada "Planilha1" na pasta de trabalho aberta no momento.

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

Se você é fã WorksheetFunction.ou trabalha de um país que não seja inglês com um Excel que não seja em inglês, esta é uma boa solução, que funciona:

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

Ou em uma função como esta:

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

Altere "Dados" para qualquer nome de folha que você está testando ...

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

Sem nenhuma dúvida de que a função acima pode funcionar, acabei com o seguinte código que funciona muito bem:

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

Nota: Sheets_Nameé onde eu peço ao usuário para inserir o nome, então ele pode não ser o mesmo para você.


0

Fiz outra coisa: exclua uma planilha apenas se ela existir - para não obter um erro se não existir:

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

Eu descobri uma maneira fácil de fazer isso, mas não criei um novo sub para ela. Em vez disso, apenas "fiz uma verificação" no submarino em que estava trabalhando. Assumindo que o nome da planilha que estamos procurando é "Sheet_Exist" e queremos apenas ativá-lo se for encontrado:

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

Também adicionei um pop-up para quando a planilha não existir.


0

Eu sei que é um post antigo, mas aqui está outra solução simples e rápida.

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

Curto e limpo:

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

-4

Na verdade, tive uma maneira simples de verificar se a planilha existe e, em seguida, executar algumas instruções:

No meu caso, eu queria excluir a planilha e depois recriei a mesma planilha com o mesmo nome, mas o código foi interrompido se o programa não foi capaz de excluir a planilha porque ela já foi excluída

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

O problema com essa resposta é que, ao determinar que a planilha de fato existia, ela foi excluída e, portanto, não existe mais. Se isso fosse escrito como uma função, poderia ter um nome como SheetExistsAfterDeletion e sempre retornaria FALSE.
ChrisB
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.