Функция VBA: извлечение даты из строки - несоответствие типов - PullRequest
0 голосов
/ 16 октября 2018

Я написал простую функцию для извлечения даты из ячеек.У меня есть несколько ячеек, содержащих строки "5-Oct-2018" и другие ячейки, содержащие "2018/10/10 Random Texts".Я хочу обрезать произвольные тексты, а также преобразовать оставшиеся строки в даты в том же формате.

Поскольку случайные тексты появляются когда-либо, только если длина строки> 10 символов или более, я решил усечь все вправо.

Я написал следующее, но оно застревает наэта строка "FnDateExtract = Format (CDate (RawExtract)," yyyy / mm / dd ")" говорит о несоответствии типов.Что я делаю не так?

Function FnDateExtract(fnFile, fnTab, fnRow, fnColumn) As Date
    Dim RawExtract As String
    With Workbooks(fnFile).Worksheets(fnTab)
        RawExtract = .Cells(fnRow, fnColumn).Text
        If Len(RawExtract) > 10 Then RawExtract = Left(RawExtract, 10)
        FnDateExtract = Format(CDate(RawExtract), "yyyy/mm/dd")
    End With
End Function

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

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

Function FnDateExtract(fnFile, fnTab, fnRow, fnColumn) As Date
Dim RawExtract As String
    With Workbooks(fnFile).Worksheets(fnTab)
        RawExtract = .Cells(fnRow, fnColumn).Text
        If Len(RawExtract) > 10 Then RawExtract = Left(RawExtract, 10)

        If IsDate(RawExtract) Then
            FnDateExtract = CDate(Format(RawExtract, "yyyy/mm/dd"))
        Else
            FnDateExtract = vbEmpty
        End If

    End With

End Function

В более улучшенной версии можно правильно определить параметры, например:

Function FnDateExtract(ByVal fnFile As String, ByVal fnTab As String, _
                    ByVal fnRow As Long, ByVal fnColumn As Long) As Date

Функция все еще может быть легко нарушена, если вы полагаете, что выесть книга с именем fnFile с листом fnTab.Самый простой (возможно, быстрый и грязный) способ справиться с этим - добавить обработчик ошибок.

Так что вторая версия может выглядеть так

Function FnDateExtract(ByVal fnFile As String, ByVal fnTab As String, _
                    ByVal fnRow As Long, ByVal fnColumn As Long) As Date
Dim RawExtract As String

On Error GoTo EH

    With Workbooks(fnFile).Worksheets(fnTab)
        RawExtract = .Cells(fnRow, fnColumn).Text
        If Len(RawExtract) > 10 Then RawExtract = Left(RawExtract, 10)
        If IsDate(RawExtract) Then
            FnDateExtract = CDate(Format(RawExtract, "yyyy/mm/dd"))
        Else
            FnDateExtract = vbEmpty
        End If
    End With

    Exit Function

EH:
    FnDateExtract = vbEmpty

End Function
0 голосов
/ 16 октября 2018

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

Function FnDateExtract(fnFile, fnTab, fnRow, fnColumn) As Date
    Dim RawExtract As String
    With Workbooks(fnFile).Worksheets(fnTab)
        RawExtract = Left(CStr(.Cells(fnRow, fnColumn).Text), 10)
        FnDateExtract = CDate(Format(RawExtract, "yyyy/mm/dd"))
    End With
End Function

Переместил CDate() за пределы функции Format(), чтобы установить тип возвращаемого значения Date

Также обратите внимание, что вы можете использовать InStr(*string*, " ") - 1 вместо 10 с функцией Left() для захвата строки даты.Это может быть более точным в определенных ситуациях.

...