Обработка неверных значений, переданных в функцию Access VBA - PullRequest
7 голосов
/ 21 июня 2011

У меня есть функция VBA, которая в основном выглядит следующим образом:

Public Function JoinDateTime(DateTime As String, Time As String) As Date
    Dim dtDate As Date
    dtDate = CDate(Format(DateTime, "dd/mm/yyyy"))
    dtDate = dtDate & " " & Format(Time, "hh:mm")
    JoinDateTime = dtDate
End Function

Она склеивает дату и время вместе в значение datetime.(Реальная функция имеет еще немного логики.)

Проблема в том, что я хотел бы добавить обработку для раздражающих значений, передаваемых ей.Это в основном для пустых / нулевых значений - если DateTime пусто, вернуть пустое.Если это текстовая строка, возвращающая #Error, чтобы она не просто молча провалилась, кажется хорошей идеей.

Проблема в том, что я не уверен, как это сделать.Я думал о досрочном возврате, возможно, что-то вроде толкания этого в начале функции:

If DateTime = Null or DateTime = "" Then 
    JoinDateTime = Null
End If

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

Есть ли способ сделать это?Лучший способ, в идеале?

Ответы [ 4 ]

4 голосов
/ 21 июня 2011

Для преждевременного возврата из функции в VBA необходимо использовать оператор Exit Function, аналогичный Exit Sub, Exit For и т. Д. Итак, этот

If DateTime = Null or DateTime = "" Then 
    JoinDateTime = Null
    Exit Function 'Au revoir
End If

предотвратит остальныекода ниже от выполнения.

2 голосов
/ 21 июня 2011

Прежде всего, вам нужно изменить объявление функции, чтобы использовать Variant вместо String. Это связано с тем, что в VBA тип данных String не может содержать значение Null. Если вы хотите, чтобы ваша функция возвращала Null для недопустимых дат, вам также потребуется изменить тип возвращаемого значения на Variant. Я также приму совет Mitch Wheat и переименую ваши аргументы в нечто, не конфликтующее со встроенными функциями (например, dateSection и timeSection).

Во-вторых, сравнение DateTime = Null никогда не будет оценено как истинное. Любое сравнение со значением Null приведет к значению Null. Вместо этого вы должны использовать функцию IsNull () (см. Ошибка 5).

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

Собираем все вместе:

Public Function JoinDateTime(dateSection As Variant, timeSection As Variant) As Variant
    Dim dtDate As Date
    If IsNull(dateSection) Then
        JoinDateTime = Null
    Else
        dtDate = CDate(Format(dateSection, "dd/mm/yyyy"))
        dtDate = dtDate & " " & Format(timeSection, "hh:mm")
        JoinDateTime = dtDate
    End If
End Function
2 голосов
/ 21 июня 2011

Самый чистый и надежный способ сделать это - вызвать ошибку.

Public Function JoinDateTime(DateTime As String, Time As String) As Date
    If DateTime = "" Then 
        Err.Raise _
            Number:=12345, _
            Source:="JoinDateTime", _
            Description:="Invalid input. DateTime cannot be empty string."
    End If
    'NB: could also check for IsNull(DateTime) if DateTime were type Variant.
    ' etc.

Это отобразит ошибку со следующим сообщением: «Ошибка времени выполнения« 12345 »: неверный ввод. DateTime не может быть пустой строкой». и исполнение остановится.

Если вы не хотите останавливать выполнение, вы можете обработать ошибку в процедуре, которая вызывает JoinDateTime. Например:

Sub tester()

    On Error GoTo ErrorHandler ' Telling VBA where to go when an error is raised

    Dim d As String
    Dim j As Date        
    d = InputBox("Date please:")
    j = JoinDateTime(d) ' Raises an error upon invalid input
    MsgBox Prompt:=j

ErrorHandler:
    Select Case Err.Number
    Case 12345 ' "Invalid input" error was raised, therefore do the following...
        ' Whatever you want to happen when this error occurs, e.g.
        ' MsgBox Prompt:=Err.Description
        ' or 
        ' j = 0
        ' Resume Next
    End Select
    Resume ExitProcedure

ExitProcedure:
    'Cleanup code goes here
End Sub
1 голос
/ 21 июня 2011
If Nz(DateTime, "") = "" Then 
    JoinDateTime = Null
End If

Два момента: может быть, лучше вернуть «особую» дату (например, начало эпохи), чем возвращать ноль;также 'DateTime' не является хорошим именем для переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...