Удалите рабочий лист, если он существует, и создайте новый

#vba #excel

#vba #excel

Вопрос:

Я хочу просмотреть свои рабочие листы Excel и найти лист с определенным именем и удалить этот лист, если он найден. После этого я хочу создать лист после всех существующих листов с таким именем. Мой код выглядит следующим образом:

 For Each ws In Worksheets
    If ws.Name = "asdf" Then
        Application.DisplayAlerts = False
        Sheets("asdf").Delete
        Application.DisplayAlerts = True
        End
    End If
Next

Sheets.Add(After:=Sheets(Sheets.count)).Name = "asdf"
  

Однако это не выполняет оба этих действия за один запуск кода. Если лист уже существует, он просто удалит лист, а не создаст новый, как я хочу. Мне нужно запустить его снова, чтобы создать новый.

Как мне исправить мой код, чтобы удалить старый лист, если он существует, и создать новый?

Ответ №1:

Удалите End инструкцию, ваш код завершается после нахождения и удаления рабочего листа asdf .

 For Each ws In Worksheets
    If ws.Name = "asdf" Then
        Application.DisplayAlerts = False
        Sheets("asdf").Delete
        Application.DisplayAlerts = True
    End If
Next

Sheets.Add(After:=Sheets(Sheets.count)).Name = "asdf"
  

Ответ №2:

Вместо перебора Worksheets вы можете проверить существование элемента в коллекции, попытавшись получить его:

 Function GetWorksheet(shtName As String) As Worksheet
    On Error Resume Next
    Set GetWorksheet = Worksheets(shtName)
End Function

If Not GetWorksheet("asdf") Is Nothing Then
    Application.DisplayAlerts = False
    Worksheets("asdf").Delete
    Application.DisplayAlerts = True
End If
Worksheets.Add(After:=sheets(sheets.Count)).name = "asdf"
  

Однако самым простым методом было бы попытаться удалить лист, заключенный в On Error Resume Next On Error GoTo 0 «блок»:

 Application.DisplayAlerts = False
On Error Resume Next
Worksheets("asdf").Delete
On Error GoTo 0
Application.DisplayAlerts = True
Worksheets.Add(After:=sheets(sheets.Count)).name = "asdf"
  

Ответ №3:

Я не согласен с тем, что «самый простой» подход заключается в преднамеренном создании (и подавлении) ошибки. Лично я бы выбрал метод loop-to-locate, пытаясь удалить только в том случае, если объект существует.

Если вы все равно собираетесь заново создавать рабочий лист, это выполнит свою работу почти в каждом случае:

 Sheets("asdf").Cells.Delete  'deletes all cells in the specified worksheet
  

Безопасное удаление рабочего листа

Если однострочный вариант (выше) у вас не работает (возможно, из-за некоторых стойких фоновых цветов / изображений), то вот вспомогательный модуль, который вы можете вызвать для удаления любого указанного рабочего листа:

 Sub deleteSheet(wsName As String)
  Dim ws As Worksheet
  For Each ws In ThisWorkbook.Sheets 'loop to find sheet (if it exists)
    Application.DisplayAlerts = False 'hide confirmation from user
    If ws.Name = wsName Then ws.Delete 'found it! - delete it
    Application.DisplayAlerts = True 'show future confirmations
  Next ws
End Sub
  

Назовите его просто как:

 deleteSheet "asdf"
  

…где asdf — название рабочего листа (вкладки), который нужно удалить.


Удалить и заменить рабочий лист

В качестве альтернативы, вызов подраздела ниже удалит и заменит рабочий лист, присвоив ему то же имя и поместив его в ту же позицию табуляции, что и исходный:

 Sub resetSheet(wsName As String)
  Dim ws As Worksheet, ws2 As Worksheet
  For Each ws In ThisWorkbook.Sheets        'loop to find sheet (if it exists)
    If ws.Name = wsName Then                'found it!
      Set ws2 = ThisWorkbook.Sheets.Add(ws) 'add new sheet located before old one
      Application.DisplayAlerts = False     'hide confirmation from user
      ws.Delete                             'delete sheet (new one takes its place)
      Application.DisplayAlerts = True      'show future confirmations
      ws2.Name = wsName                     'rename new sheet to old name
      Exit Sub                              'finished! (no need to continue looping)
    End If
  Next ws
End Sub
  

О ThisWorkbook :

Я использовал ThisWorkbook в обоих подразделах, что важно при запуске VBA, который изменяет другие книги, или при одновременном открытии нескольких книг.

Использование ThisWorkbook гарантирует, что ваш код всегда ссылается на рабочую книгу, где находится код, который его вызвал.

Без этого, например, если у вас открыты два похожих файла, и вы просматриваете один, ожидая запуска VBA в другой книге, если в книге, которая находится «сверху», есть рабочий лист с именем того, который VBA пытается удалить, он удалит рабочий лист в текущей (активной) книге вместо предполагаемого.

(… и вы не можете Ctrl Z отменить VBA!)