Неожиданная ошибка из UDF, которая проверяет, можно ли найти файл

#excel #vba

#excel #vba

Вопрос:

У меня есть if-оператор в моем коде:

 If sharepointFileExists(sFullFilePath) Or fileOnDisk(sFullFilePath) Then
 

который вызывает две функции:

 Function fileOnDisk(ByVal strPath As String) As Boolean
    fileOnDisk = CBool(Len(Dir(strPath)) > 0)
End Function
 

и

 Function sharepointFileExists(ByVal strUrl As String) As Boolean
    On Error GoTo ErrorHandler
    Dim oHttp As Object
    
    Set oHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    oHttp.Open "HEAD", strUrl, False
    oHttp.Send
    'Debug.Print oHttp.Status
    sharepointFileExists = CBool(oHttp.Status = 200)
    Exit Function
ErrorHandler:
    'Debug.Print Err.Number amp; " - " amp; Err.Description
    'Debug.Print "Feil: - " amp; oHttp.Status
    sharepointFileExists = False
End Function
 

У меня есть несколько файлов, которые используют этот код, и в одном из них я получаю сообщение об ошибке, хотя входные данные должны быть одинаковыми для всех них.

В функции fileOnDisk я получаю сообщение об ошибке

Ошибка времени выполнения ’52’: неверное имя или номер файла

Аргумент, предоставляемый функции, является чем-то вроде https://nhy.sharepoint.com/teams/Team-xxxxxx/xxxx/xxxx/Excel-file.xlsx , который я ожидал Dir бы не найти на диске и, таким образом, вернуть строку нулевой длины (согласно документации). Вместо этого я получаю ошибку, описанную выше.

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

введите описание изображения здесь

У кого-нибудь есть представление о том, что здесь происходит?

Комментарии:

1. Вам действительно нужно передавать один и тот же файл в обе функции? Разве вы не можете проверить, является ли Left() 4 символами http, и отправить строку в соответствующую функцию? Или fileOnDisk проверьте, является ли это http, и просто передайте false обратно

2. Встроите обработку ошибок в fileOnDisk , аналогично тому, что вы уже сделали в sharepointFileExists

3. @chrisneilsen Да, я, наверное, просто так и сделаю. Есть ли у вас какие-либо идеи, почему возникает эта конкретная ошибка? Я действительно не понимаю, почему Dir он не хочет обрабатывать эту строку, тем более что она прекрасно работает в других версиях файла.

4. Существует много строк, которые Dir не могут быть интерпретированы как пути, те, которые начинаются с https:// , являются лишь подмножеством.

5. Я думаю, это зависит от вашего варианта использования, но я ожидаю, что вы захотите вернуться. FALSE для любого неверно сформированного параметра, переданного в fileOnDisk , точно так же, как вы делаете для sharepointFileExists . В качестве примера, если бы вы сдали X:Y:Z экзамен, я бы ожидал FALSE разумного ответа.

Ответ №1:

Dir() Метод выдает ошибку, если родительский каталог не существует. FileSystemObject В этом случае вам нужно использовать the, который просто возвращает логическое значение.

 Function fileOnDisk(ByVal strPath As String) As Boolean
    With CreateObject("Scripting.FileSystemObject")
        fileOnDisk = .FileExists(strPath)
    End With
End Function
 

Комментарии:

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

2. Хотя Filesystemobject является жизнеспособной альтернативой, ваше утверждение, что метод Dir() выдает ошибку, если родительский каталог не существует , неверно. Он просто возвращает пустую строку (при условии, что переданный путь синтаксически корректен).

Ответ №2:

Встроите обработку ошибок в fileOnDisk , аналогично тому, что вы уже сделали в sharepointFileExists

Существует много строк, которые Dir не может интерпретировать как пути, те, которые начинаются с https:// , являются лишь подмножеством

 Function fileOnDisk(ByVal strPath As String) As Boolean
    On Error GoTo EH
    fileOnDisk = CBool(Len(Dir(strPath)) > 0)
Exit Function
EH:
    fileOnDisk = False
End Function
 

Ответ №3:

Поскольку dir(), вероятно, не может получить доступ к файлам, которые не являются локальными, он выдает сообщение об ошибке.
Вы могли бы исправить это, отредактировав функцию fileOnDisk следующим образом:

 Function fileOnDisk(ByVal strPath As String) As Boolean
    if left(lcase(strPath), 4) <> "http" then
        fileOnDisk = CBool(Len(Dir(strPath)) > 0)
    else
        fileOnDisk = false
    end if
End Function