Uji atau periksa apakah ada sheet

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

Pada dasarnya saya mengulang semua lembar di buku kerja asal lalu mengatur destsheetdi buku kerja tujuan ke lembar dengan nama yang sama seperti yang saat ini diiterasi di buku kerja asal.

Bagaimana saya bisa menguji jika lembar itu ada? Sesuatu seperti:

If wkbkdestination.Worksheets(ThisWorkSheet.Name) Then 
yse
sumber
2
kemungkinan duplikat dari Excel VBA Jika WorkSheet ("wsName") Ada
sancho.s ReinstateMonicaCellio

Jawaban:

173

Beberapa orang tidak menyukai pendekatan ini karena penggunaan penanganan kesalahan yang "tidak tepat", tetapi saya pikir itu dianggap dapat diterima di VBA ... Pendekatan alternatif adalah mengulang semua lembar sampai Anda menemukan kecocokan.

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
Tim Williams
sumber
5
Gunakan IMO sepenuhnya sesuai. Ini adalah jebakan untuk sesuatu yang dianggap ada dan tidak dan memiliki sejarah panjang - cf perl strict, STAE dll. Suara positif
Wudang
13
Satu mungkin harus menggunakan ActiveWorkbookbukan ThisWorkbook. Yang terakhir merujuk ke buku kerja yang berisi kode makro, yang mungkin berbeda dari buku kerja yang ingin diuji. Saya kira ActiveWorkbookakan berguna untuk kebanyakan kasus (situasi yang dibuat-buat selalu tersedia).
sancho.s ReinstateMonicaCellio
3
sht Is Nothingakan Truejika tidak ada lembar dengan nama itu, tapi kami ingin kembali Truejika ada adalah sheet dengan nama itu, maka Tidak. Ini sedikit lebih mudah (tetapi tidak valid) jika Anda mengatur ulang sedikit keSheetExists = sht Is Not Nothing
Tim Williams
3
Perlu diperhatikan bahwa jika Anda menjalankan kode ini di buku kerja makro pribadi Anda, ubah dari If wb Is Nothing Then Set wb = ThisWorkbookmenjadiIf wb Is Nothing Then Set wb = ActiveWorkbook
Henrik K
2
Ini adalah pendekatan yang sangat efisien (lihat komentar saya tentang nilai benchmark di bawah jawaban Rory di bawah), jadi siapa peduli apa yang dipikirkan para pencela. Catatan (seperti sekarang) Anda memiliki nol suara bawah.
rory .ap
107

Jika Anda hanya tertarik pada lembar kerja, Anda dapat menggunakan panggilan Evaluasi sederhana:

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
Rory
sumber
14
@Rory Saya menjalankan beberapa tes benchmark pada jawaban ini vs. Tim Williams. Lebih dari 500.000 loop, Anda membutuhkan waktu 22 detik dan Tim mengambil <1.
rory .ap
17
@roryap - jika Anda perlu menjalankan ini 500.000 kali, Anda perlu memikirkan kembali seluruh pendekatan Anda. ;)
Rory
9
@roryap - namun, menggunakan beberapa metode lambat akan mulai menumpuk beberapa detik. Menurut saya ini adalah informasi yang sangat berharga, karena "aplikasi" Excel mulai mengumpulkan detik dengan cukup mudah dengan berbagai metode Range, dll.
tedcurrent
4
@roryap - dengan cara apa informasi itu berharga untuk percakapan? Saya hanya menyatakan bahwa menyebarkan metode yang tidak efisien di sekitar kode Anda akan membuat aplikasi lambat secara keseluruhan. Anda menguji 500k kali ini luar biasa dan saya berterima kasih telah melakukannya, 22 detik tidak bagus. (Saya setuju dengan Anda)
tedcurrent
6
Meskipun lebih lambat, ini terlihat seperti solusi yang jauh lebih bersih daripada jawaban yang diterima. +1 dari saya.
Sascha L.
49

Anda tidak perlu penanganan kesalahan untuk melakukannya. Yang harus Anda lakukan adalah mengulang semua Lembar Kerja dan memeriksa apakah nama yang ditentukan ada:

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
fbonetti
sumber
21

Karena memeriksa anggota suatu koleksi adalah masalah umum, berikut adalah versi abstrak dari jawaban Tim:

Fungsi Berisi (objCollection Sebagai Objek, strName sebagai String) Sebagai Boolean
    Dim o sebagai Objek
    Pada Kesalahan Lanjutkan Berikutnya
    set o = objCollection (strName)
    Berisi = (Err.Number = 0)
    Err. Hapus
 Fungsi Akhir

Fungsi ini dapat digunakan dengan koleksi apapun seperti objek ( Shapes, Range, Names, Workbooks, dll).

Untuk memeriksa keberadaan sheet, gunakan If Contains(Sheets, "SheetName") ...

Peter Albert
sumber
5
Ini tidak menangkap tipe primitif dalam Koleksi karena kesalahan akan dimunculkan oleh Setkata kunci. Saya menemukan bahwa daripada menggunakan Set, meminta TypeNameanggota koleksi bekerja untuk semua kasus, yaituTypeName objCollection(strName)
citizenkong
2
@Peter: Terbaik untuk menambahkan sesuatu untuk menghapus kesalahan yang akan muncul jika tidak ada sebelum funciton berhenti - baik err.clear atau On Error Resume Next. Jika tidak, penanganan kesalahan dalam prosedur panggilan dapat dipicu secara tidak sengaja dalam kasus seperti berikut ini. Sub Test() On Error GoTo errhandler Debug.Print Contains(Workbooks, "SomeBookThatIsNotOpen") errhandler: If Err.Number <> 0 Then Stop End Sub
jeffreyweir
16

Diperbaiki: Tanpa penanganan kesalahan:

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
Shai Alon
sumber
14

Jika ada yang ingin menghindari VBA dan menguji apakah lembar kerja hanya ada di dalam rumus sel, dimungkinkan menggunakan fungsi ISREFdan INDIRECT:

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

Ini akan dikembalikan TRUEjika buku kerja berisi lembar yang disebut SheetNamedan FALSEsebaliknya.

VirtualMichael
sumber
12

Saya menulis yang ini:

Function sheetExist(sSheet As String) As Boolean
On Error Resume Next
sheetExist = (ActiveWorkbook.Sheets(sSheet).Index > 0)
End Function
AOBR
sumber
1
Fungsi yang bagus! Tidak hanya cepat, tapi juga paling ringkas.
ChrisB
Saya percaya ini adalah jawaban yang paling sesuai dengan pertanyaan
Juan Joya
Saya suka yang ini. Perhatikan bahwa ini bergantung pada fakta bahwa nilai default untuk sheetExist akan menjadi False karena ini adalah fungsi Boolean. Pernyataan tugas tidak benar-benar menetapkan nilai False ke sheetExist jika sheet tidak ada, itu hanya kesalahan dan meninggalkan nilai default di tempatnya. Jika Anda mau, Anda dapat mengandalkan fakta bahwa nilai bukan nol yang ditetapkan ke variabel Boolean akan memberikan hasil True dan sheetExist = ActiveWorkbook.Sheets(sSheet).Index
mengabaikan
5

Solusi saya sangat mirip dengan Tim tetapi juga berfungsi dalam kasus lembar non-lembar kerja - bagan

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

.

uildriks
sumber
3

Letakkan tes dalam suatu fungsi dan Anda akan dapat menggunakannya kembali dan Anda memiliki keterbacaan kode yang lebih baik.

JANGAN gunakan "On Error Resume Next" karena dapat menimbulkan konflik dengan bagian lain dari kode Anda.

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
Martin Carlsson
sumber
3

Bertahun-tahun terlambat, tetapi saya hanya perlu melakukan ini dan tidak menyukai solusi yang diposting ... Jadi saya membuat satu, semua berkat keajaiban (gerakan tangan pelangi SpongeBob) "Evaluasi ()"!

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

Mengembalikan TRUE jika Sheet TIDAK ada; SALAH jika sheet ADA. Anda dapat mengganti rentang apa pun yang Anda suka untuk "1: 1", tetapi saya menyarankan agar tidak menggunakan satu sel, karena jika mengandung kesalahan (misalnya, # N / A), itu akan mengembalikan True.

X37V
sumber
3

wsExistsFungsi kompak ( tanpa bergantung pada Penanganan Kesalahan!)

Berikut adalah fungsi singkat & sederhana yang tidak bergantung pada penanganan kesalahan untuk menentukan apakah lembar kerja ada ( dan dinyatakan berfungsi dengan benar dalam situasi apa pun !)

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

Contoh Penggunaan:

Contoh berikut menambahkan lembar kerja baru bernama myNewSheet, jika belum ada:

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

Informasi Lebih Lanjut:

ashleedawg.dll
sumber
2

Mengapa tidak menggunakan loop kecil untuk menentukan apakah lembar kerja bernama ada? Katakanlah jika Anda sedang mencari Lembar Kerja bernama "Sheet1" di buku kerja yang saat ini dibuka.

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
ScottMcC
sumber
2

Jika Anda adalah penggemar WorksheetFunction.atau Anda bekerja dari negara non-Inggris dengan Excel non-Inggris, ini adalah solusi yang baik, yang berhasil:

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

Atau dalam fungsi seperti ini:

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Not WorksheetFunction.IsErr(Evaluate("'" & sName & "'!A1"))
End Function
Vityata
sumber
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
Philipp88
sumber
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
Shrikant
sumber
1

Ubah "Data" menjadi nama sheet apa pun yang Anda uji ...

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
gth826a
sumber
1

Tanpa ragu bahwa fungsi di atas dapat berfungsi, saya baru saja berakhir dengan kode berikut yang berfungsi dengan cukup baik:

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

Catatan: Sheets_Nameadalah tempat saya meminta pengguna untuk memasukkan nama, jadi ini mungkin tidak sama untuk Anda.

MAx Segura
sumber
0

Saya melakukan hal lain: hapus lembar hanya jika ada - tidak mendapatkan kesalahan jika tidak:

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
Shai Alon
sumber
0

Saya menemukan cara mudah untuk melakukannya, tetapi saya tidak membuat sub baru untuk itu. Sebaliknya, saya hanya "memeriksa" di sub-sub yang sedang saya kerjakan. Dengan asumsi nama sheet yang kita cari adalah "Sheet_Exist" dan kita hanya ingin mengaktifkannya jika ditemukan:

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

Saya juga menambahkan pop-up ketika sheet tidak ada.

imjordy23
sumber
0

Saya tahu ini adalah posting lama, tetapi ini adalah solusi sederhana lain yang cepat.

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
Tamu
sumber
0

Pendek dan bersih:

Function IsSheet(n$) As Boolean
    IsSheet = Not IsError(Evaluate(n & "!a1"))
End Function
Pahlawan Excel
sumber
-4

Saya sebenarnya memiliki cara sederhana untuk memeriksa apakah lembar itu ada dan kemudian menjalankan beberapa instruksi:

Dalam kasus saya, saya ingin menghapus sheet dan kemudian membuat ulang sheet yang sama dengan nama yang sama tetapi kode terputus jika program tidak dapat menghapus sheet karena sudah dihapus.

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
chenaou
sumber
Masalah dengan jawaban ini adalah bahwa setelah menentukan bahwa sheet tersebut benar-benar ada, ia dihapus dan oleh karena itu tidak ada lagi. Jika ini ditulis sebagai fungsi, ini mungkin memiliki nama seperti SheetExistsAfterDeletion dan akan selalu mengembalikan FALSE.
ChrisB