VBA Проверьте, существует ли имя листа [дубликат]

Краткий ответ: ваш метод foo() возвращается немедленно, а вызов $ajax() выполняется асинхронно после возврата функции . Проблема заключается в том, как и где сохранить результаты, полученные при вызове async, после его возврата.

В этом потоке было задано несколько решений. Возможно, самый простой способ - передать объект методу foo() и сохранить результаты в члене этого объекта после завершения асинхронного вызова.

function foo(result) {
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;   // Store the async result
        }
    });
}

var result = { response: null };   // Object to hold the async result
foo(result);                       // Returns before the async completes

Обратите внимание, что вызов foo() ] все равно не вернут ничего полезного. Однако результат асинхронного вызова теперь будет сохранен в result.response.

71
задан L42 12 February 2015 в 23:08
поделиться

18 ответов

Некоторым людям не нравится этот подход из-за «неуместного» использования обработки ошибок, но я думаю, что это считается приемлемым в VBA ... Альтернативный подход заключается в том, чтобы зацикливать все листы, пока вы не найдете совпадение.

 Function SheetExists(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
     SheetExists = Not sht Is Nothing
 End Function
124
ответ дан Tim Williams 31 August 2018 в 17:32
поделиться

Я написал это:

Function sheetExist(sSheet As String) As Boolean
On Error Resume Next
sheetExist = (ActiveWorkbook.Sheets(sSheet).Index > 0)
End Function
1
ответ дан AOBR 31 August 2018 в 17:32
поделиться

Компактная функция wsExists ( без зависит от обработки ошибок!) [/ ​​g6]

Вот короткий & amp; простую функцию, которая не полагается на обработку ошибок, чтобы определить, существует ли рабочий лист ( и ], [3], [3] hr>

Пример использования:

В следующем примере добавляется новый лист с именем myNewSheet, если он еще не существует:

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

Дополнительная информация :

-1
ответ дан ashleedawg 31 August 2018 в 17:32
поделиться

На самом деле у меня был простой способ проверить, существует ли лист, а затем выполнить некоторую инструкцию:

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

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
1
ответ дан Cody Gray 31 August 2018 в 17:32
поделиться

Измените «данные» на любое имя листа, которое вы тестируете для ...

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
ответ дан Dan Lowe 31 August 2018 в 17:32
поделиться

Для этого вам не нужна обработка ошибок. Все, что вам нужно сделать, это перебрать все листы и проверить, существует ли указанное имя:

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
31
ответ дан fbonetti 31 August 2018 в 17:32
поделиться

Я придумал простой способ сделать это, но я не создал для него новую подсистему. Вместо этого я просто «проверил чек» в суб, над которым я работал. Предполагая, что имя листа, которое мы ищем, является «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
ответ дан imjordy23 31 August 2018 в 17:32
поделиться

Положите тест в функцию, и вы сможете его повторно использовать, и у вас будет более удобная читаемость кода.

НЕ используйте «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
2
ответ дан Martin Carlsson 31 August 2018 в 17:32
поделиться

Поскольку проверка членов коллекции является общей проблемой, вот абстрагированная версия ответа Тима:

Function Contains(objCollection As Object, strName as String) As Boolean
    Dim o as Object
    On Error Resume Next
    set o = objCollection(strName)
    Contains = (Err.Number = 0)
    Err.Clear
 End Function

Эта функция может использоваться с любой коллекцией, подобной объекту (Shapes, Range, Names, Workbooks и т. д.).

Чтобы проверить наличие листа, используйте If Contains(Sheets, "SheetName") ...

20
ответ дан Peter Albert 31 August 2018 в 17:32
поделиться
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
ответ дан Philipp88 31 August 2018 в 17:32
поделиться

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

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
73
ответ дан Rory 31 August 2018 в 17:32
поделиться

Почему бы просто не использовать небольшой цикл, чтобы определить, существует ли именованный лист? Скажите, искали ли вы рабочую таблицу с именем «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
1
ответ дан ScottMcC 31 August 2018 в 17:32
поделиться

Я сделал другое: удалите лист только в том случае, если он существует - не получить ошибку, если это не так:

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
12
ответ дан Shai Alon 31 August 2018 в 17:32
поделиться
    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
ответ дан Shrikant 31 August 2018 в 17:32
поделиться

Мое решение очень похоже на 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

.

4
ответ дан uildriks 31 August 2018 в 17:32
поделиться

В случае, если кто-то хочет избежать VBA и проверить, существует ли таблица только внутри формулы ячейки, возможно использование функций ISREF и INDIRECT:

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

Это вернет TRUE, если книга содержит лист, названный SheetName и FALSE в противном случае.

10
ответ дан VirtualMichael 31 August 2018 в 17:32
поделиться

Если вы поклонник WorksheetFunction. или работаете в неанглийской стране с неанглийским Excel, это хорошее решение, которое работает:

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

Или в функции например:

Function WorksheetExists(sName As String) As Boolean
    WorksheetExists = Not WorksheetFunction.IsErr(Evaluate("'" & sName & "'!A1"))
End Function
2
ответ дан Vityata 31 August 2018 в 17:32
поделиться

Много лет спустя, но мне просто нужно было это сделать, и мне не понравилось, что какое-либо из решений было опубликовано ... Итак, я сделал все, благодаря магии (жестом в форме радуги SpongeBob) «Evaluate ()» !

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

Возвращает TRUE, если лист НЕ существует; FALSE, если лист существует. Вы можете заменить любой диапазон, который вам нравится, на «1: 1», но я советую не использовать одну ячейку, потому что если она содержит ошибку (например, # N / A), она вернет True.

1
ответ дан X37V 31 August 2018 в 17:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: