Sayfanın olup olmadığını test edin veya kontrol edin


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

Temel olarak, kaynak çalışma kitabındaki tüm sayfalarda döngü yapıyorum ve ardından destsheethedef çalışma kitabını, başlangıç ​​çalışma kitabındaki şu anda yinelenen ile aynı ada sahip sayfaya ayarlıyorum .

Bu sayfanın var olup olmadığını nasıl test edebilirim? Gibi bir şey:

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 

Yanıtlar:


173

Bazı insanlar, hata işlemenin "uygunsuz" bir şekilde kullanılması nedeniyle bu yaklaşımı sevmezler, ancak VBA'da kabul edilebilir olduğunu düşünüyorum ... Alternatif bir yaklaşım, bir eşleşme bulana kadar tüm sayfaları döngüye sokmaktır.

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
Tamamen uygun IMO kullanın. Bu, var olarak kabul edilen ve olmayan ve uzun bir geçmişi olan bir şey için bir tuzak - cf perl tight, STAE vb. Yükseltildi
Wudang

13
Bunun ActiveWorkbookyerine muhtemelen kullanılmalı ThisWorkbook. İkincisi, çalışma kitabından birinin test etmek istediğinden farklı olabilecek makro kodunu içeren çalışma kitabına atıfta bulunur. Sanırım ActiveWorkbookçoğu durum için faydalı olacaktır (yine de uydurma durumlar her zaman mevcuttur).
sancho.s ReinstateMonicaCellio

3
sht Is Nothingolacak Trueorada bu adı taşıyan hiçbir levha, ama biz dönmek istiyorsanız Trueorada eğer olduğunu dolayısıyla değil, o adla bir levha. Biraz yeniden düzenlerseniz biraz daha kolay (ama geçerli değil)SheetExists = sht Is Not Nothing
Tim Williams

3
Nota iyi olduğunu kişisel makro çalışma kitabında bu kodu çalıştırırsanız, değişiklik gelen If wb Is Nothing Then Set wb = ThisWorkbooketmekIf wb Is Nothing Then Set wb = ActiveWorkbook
Henrik K

2
Bu, oldukça verimli bir yaklaşımdır (aşağıdaki Rory'nin cevabı altındaki kriterler hakkındaki yorumlarıma bakın), bu yüzden, hakaret edenlerin ne düşündüğü kimin umurunda. Not (şu an itibariyle) sıfır eksi oyunuz var.
rory.ap

107

Yalnızca çalışma sayfalarıyla özellikle ilgileniyorsanız, basit bir Değerlendir çağrısı kullanabilirsiniz:

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

14
@Rory Tim Williams'ın cevabına karşı bazı kıyaslama testleri yaptım. 500.000'den fazla döngü, sizinki 22 saniye sürdü ve Tim <1'i aldı.
rory.ap

17
@roryap - Bunu 500.000 kez çalıştırmanız gerekiyorsa, tüm yaklaşımınızı yeniden düşünmeniz gerekir. ;)
Rory

9
@roryap - ancak, birkaç yavaş yöntem kullanmak saniyeler birikmeye başlayacaktır. Excel "uygulamaları" çeşitli Aralık yöntemleri vb.
İle

4
@roryap - bu bilgi konuşma için ne şekilde değerlidir? Verimsiz yöntemleri kodunuzun etrafına dağıtmanın uygulamayı bir bütün olarak yavaşlatacağını söylüyorum. Bu 500 bin kez test etmeniz harika ve yaptığınız için teşekkür ederim, 22 saniye harika değil. (Sana katılıyorum)
tedcurrent

6
Daha yavaş olsa bile, kabul edilen cevaptan çok daha temiz bir çözüm gibi görünüyor. Benden +1.
Sascha L.

49

Bunu başarmak için hata işlemeye ihtiyacınız yoktur. Tek yapmanız gereken tüm Çalışma Sayfalarını yinelemek ve belirtilen adın var olup olmadığını kontrol etmek:

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

Bir koleksiyonun üyelerini kontrol etmek genel bir sorun olduğu için, işte Tim'in cevabının soyutlanmış bir versiyonu:

Fonksiyon (objCollection As Object, strName as String) As Boolean
    Nesne olarak Dim o
    Hatada Devam Et Sonraki
    set o = objCollection (strName)
    İçerir = (Err.Number = 0)
    err.Clear
 Son İşlevi

Bu fonksiyon, (nesne gibi bir toplama ile kullanılabilir Shapes, Range, Names, Workbooks, vs.).

Bir sayfanın varlığını kontrol etmek için kullanın If Contains(Sheets, "SheetName") ...


5
SetAnahtar kelime tarafından bir hata ortaya çıkacağı için bu, Koleksiyonlardaki ilkel türleri yakalamaz . Kullanmak yerine koleksiyonun üyesini Setistemek TypeNametüm vakalar için çalışıyor, yaniTypeName objCollection(strName)
Citenkong

2
@Peter: En iyisi, işlev sona ermeden önce mevcut olmama durumunda ortaya çıkacak hatayı gidermek için bir şey eklemektir - bir err.clear veya On Error Resume Next. Aksi takdirde, aşağıdaki gibi durumlarda arama prosedüründeki hata işleme yanlışlıkla tetiklenebilir. Sub Test() On Error GoTo errhandler Debug.Print Contains(Workbooks, "SomeBookThatIsNotOpen") errhandler: If Err.Number <> 0 Then Stop End Sub
jeffreyweir

16

Düzeltildi: Hata işleme olmadan:

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

Herhangi birinin VBA'dan kaçınmak ve bir çalışma sayfasının yalnızca bir hücre formülünde olup olmadığını test etmek istemesi durumunda, ISREFve INDIRECTişlevlerini kullanarak mümkündür :

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

Bu dönecektir TRUEçalışma kitabı olarak adlandırılan bir sayfa içeriyorsa SheetNameve FALSEaksi.


12

Bunu ben yazdım:

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

1
Harika işlev! Sadece hızlı değil, aynı zamanda en özlü.
ChrisB

Soruya en çok karşılık gelen cevabın bu olduğuna inanıyorum
Juan Joya

Bunu beğendim. Bir Boolean işlevi olduğundan, sheetExist için varsayılan değerin False olacağı gerçeğine dayandığını unutmayın. Atama ifadesi, sayfa yoksa, aslında pageExist'e bir False değeri atamaz, yalnızca hata verir ve varsayılan değeri yerinde bırakır. İsterseniz, bir Boolean değişkenine atanan sıfır olmayan herhangi bir değerin bir True sonuç vereceğine ve> 0 karşılaştırmasını dışarıda bırakacağına sheetExist = ActiveWorkbook.Sheets(sSheet).Index
güvenebilirsiniz

5

Çözümüm Tims'e çok benziyor ancak çalışma sayfası olmayan sayfalarda da çalışıyor - grafikler

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

Testi bir işleve koyun ve yeniden kullanabileceksiniz ve daha iyi kod okunabilirliğine sahip olacaksınız.

Kodunuzun diğer bölümleriyle çakışabileceğinden "Hata Durumunda Devam Ettirme" seçeneğini KULLANMAYIN.

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

Yıllar geç oldu, ama bunu yapmam gerekiyordu ve yayınlanan çözümlerin hiçbirini beğenmedim ... Bu yüzden (SpongeBob gökkuşağı elleri hareketi) "Evaluate ()" sihri sayesinde bir tane uydurdum!

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

Sayfa yoksa DOĞRU döndürür; Sayfa varsa YANLIŞ. "1: 1" yerine istediğiniz aralığı değiştirebilirsiniz, ancak tek bir hücre kullanılmamasını tavsiye ederim, çünkü bir hata içeriyorsa (örneğin, # N / A), True döndürür.


3

Kompakt wsExistsfonksiyonu ( olmadan Hata İşleme dayanarak!)

İşte bir çalışma sayfasının var olup olmadığını belirlemek için hata işlemeye dayanmayan ( ve her durumda uygun şekilde çalıştığı bildirilen !) Kısa ve basit bir işlev.

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

Örnek Kullanım:

Aşağıdaki örnek myNewSheet, zaten mevcut değilse adlı yeni bir çalışma sayfası ekler :

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

Daha fazla bilgi:


2

Neden adlandırılmış çalışma sayfasının var olup olmadığını belirlemek için sadece küçük bir döngü kullanmıyorsunuz? Şu anda açık olan çalışma kitabında "Sayfa1" adlı bir Çalışma Sayfası mı arıyorsunuz?

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

Eğer bir hayranı iseniz WorksheetFunction.veya İngilizce olmayan bir Excel ile İngilizce olmayan bir ülkeden çalışmak bu iyi bir çözümdür eserler olduğunu:

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

Veya bunun gibi bir işlevde:

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

"Veri" yi test ettiğiniz sayfa adına değiştirin ...

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

Yukarıdaki işlevin çalışabileceğinden şüphe duymadan, oldukça iyi çalışan aşağıdaki kodu buldum:

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

Not: Sheets_Namekullanıcıdan adı girmesini istediğim yerdir, bu nedenle bu sizin için aynı olmayabilir.


0

Başka bir şey yaptım: bir sayfayı yalnızca varsa silin - yoksa hata almamak için:

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

Bunu yapmanın kolay bir yolunu buldum, ancak bunun için yeni bir abonelik oluşturmadım. Bunun yerine, üzerinde çalıştığım denizaltında "bir kontrol yaptım". Aradığımız sayfa adının "Sheet_Exist" olduğunu varsayarsak ve bulunursa onu etkinleştirmek istiyoruz:

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

Ayrıca sayfanın olmadığı zamanlar için bir pop-up ekledim.


0

Bunun eski bir gönderi olduğunu biliyorum ama işte hızlı olan başka bir basit çözüm.

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

Kısa ve temiz:

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

-4

Aslında sayfanın var olup olmadığını kontrol etmenin ve sonra bazı talimatları yürütmenin basit bir yolunu buldum:

Benim durumumda, sayfayı silmek istedim ve ardından aynı sayfayı aynı adla yeniden oluşturdum, ancak program zaten silinmiş olduğu için sayfayı silemediğinde kod kesildi

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

Bu yanıtla ilgili sorun, sayfanın gerçekte var olduğunu belirledikten sonra silinmesi ve dolayısıyla artık mevcut olmamasıdır. Bu bir işlev olarak yazıldıysa, SheetExistsAfterDeletion gibi bir ada sahip olabilir ve her zaman FALSE döndürür.
ChrisB
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.