Как преобразовать строку формата ddmmyyyy в yymmdd - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь преобразовать несколько строк в указанный c формат. Например:

  • ddmmyyyy для преобразования в гггммдд или ггггммдд
  • ггггммдд для преобразования в ddmmyy или ddmmyyyy
  • ddmmyy для преобразования в ddmmyyyy или ddmmy 1009 * yymmdd для преобразования в ddmmyy или ddmmyyyy

Но я не знаю, какой формат будет передан во время выполнения. Есть ли способ добиться этого в VBA? Я создал функцию ниже, которая учитывает дату определенной длины, но она будет работать только для 2 сценариев ios.

Function FormatDate(sDate As String, sFormat As String) As String
    Dim Y As Long, M As Long, D As Long
   
    If Len(sDate) = 6 Then
        Y = Left(sDate, 2)
        M = Mid(sDate, 3, 2)
        D = Right(sDate, 2)
    Else
        Y = Left(sDate, 4)
        M = Mid(sDate, 5, 2)
        D = Right(sDate, 2)
    End If
 
    FormatDate = Format(DateSerial(Y, M, D), sFormat)
End Function

Ответы [ 2 ]

2 голосов
/ 24 января 2020
Function FormatDate(ByVal srcDate As String, ByVal srcFormat As String, ByVal dstFormat As String) As String
If Len(srcDate) <> Len(srcFormat) Then Exit Function
Dim d As String, m As String, y As String
Dim i As Integer
For i = 1 To Len(srcDate)
    Select Case Left(srcFormat, 1)
        Case "y"
            y = y & Left(srcDate, 1)
        Case "m"
            m = m & Left(srcDate, 1)
        Case "d"
            d = d & Left(srcDate, 1)
        End Select
    srcDate = Mid(srcDate, 2)
    srcFormat = Mid(srcFormat, 2)
Next i
For i = 1 To 3
    Select Case Left(dstFormat, 2)
        Case "dd"
            FormatDate = FormatDate & d
        Case "mm"
            FormatDate = FormatDate & m
        Case "yy"
            If Left(dstFormat, 4) = "yyyy" Then
                FormatDate = FormatDate & "20" & Right(y, 2)
                dstFormat = Mid(dstFormat, 3)
            Else
                FormatDate = FormatDate & Right(y, 2)
            End If
        Case Else
            FormatDate = ""
            Exit Function
        End Select
    dstFormat = Mid(dstFormat, 3)
Next
End Function
Debug.Print FormatDate("25012019", "ddmmyyyy", "mmddyy")
Debug.Print FormatDate("25 01 2019", "dd mm yyyy", "ddmmyyyy")
' and so on ... '
1 голос
/ 24 января 2020

Поскольку может быть неоднозначность относительно того, что означает строка типа «010102» (1 января 2002 г. или 2 января 2001 г.), вы можете сначала выполнить итерации по датам, чтобы определить, какая из двух интерпретаций работает для всех других дат.

Здесь я предполагаю, что все даты будут использовать одинаковый формат. Тогда вы можете надеяться, что есть хотя бы одна строка, которую можно интерпретировать только одним способом, например, «000102» может означать только 2 января 2000 года. Поэтому, если вы найдете такой вход, вы можете предположить, что другие входы также находятся в yymmdd формат.

Для этой цели вы можете использовать эту функцию:

Public Function GuessDateFormat(cells As Variant, minDate As Date, maxDate As Date) As String
    Dim size As Integer
    Dim cellDate As Date
    Dim dateFormat As Integer ' 0, 1 or 2
    Dim value As String

    GuessDateFormat = "inconsistent"

    size = Len(cells(1, 1).value)
    If size <> 6 And size <> 8 Then Exit Function
    For Each cell In cells
        value = cell.value
        If Len(value) <> size Then Exit Function ' Conflicting format sizes

        cellDate = DateSerial(Left(value, size - 4), Mid(value, size - 3, 2), Right(value, 2))
        If cellDate < minDate Or cellDate > maxDate Or Format(cellDate, Right("yyyymmdd", size)) <> value Then
            dateFormat = dateFormat Or 2 ' format should not be yy[yy]mmdd
        End If

        cellDate = DateSerial(Right(value, size - 4), Mid(value, 3, 2), Left(value, 2))
        If cellDate < minDate Or cellDate > maxDate Or Format(cellDate, Left("ddmmyyyy", size)) <> value Then
            dateFormat = dateFormat Or 1 ' format should not be ddmmyy[yy]
        End If

        If dateFormat = 3 Then Exit Function ' Neither format is possible
    Next
    GuessDateFormat = Array("ambiguous", Right("yyyymmdd", size), Left("ddmmyyyy", size))(dateFormat)
End Function

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

Так, например, если ваши входные строки импортированы в диапазоне A1: A10, и вы считаете, что все даты должны быть между 1-1-2000 и сегодняшней датой, то вы бы вызвали вышеуказанную функцию из внутри ячейки, например:

=GuessDateFormat(A1:A10, DATE(2000,1,1), NOW())

Если все в порядке, функция вернет "ddmmyy", "ddmmyyyy", "yymmdd" или "yyyymmdd". Если все входные данные неоднозначны, и невозможно сделать определенный выбор, возвращаемое значение будет «неоднозначным» (неудача!).

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

Function DateFromFormat(dateString As String, srcFormat As String) As Date
    Dim dateParts(3) As String

    For i = 1 To Len(srcFormat)
        j = InStr("ymd", Mid(srcFormat, i, 1))
        If j Then dateParts(j) = dateParts(j) + Mid(dateString, i, 1)
    Next
    DateFromFormat = DateSerial(dateParts(1), dateParts(2), dateParts(3))
End Function

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

  A      |      B
---------+-----------------
19112018 | =DateFromFormat(A1, A$11)
01012002 | =DateFromFormat(A2, A$11)
02022001 | =DateFromFormat(A3, A$11)
03102005 | =DateFromFormat(A4, A$11)
04012020 | =DateFromFormat(A5, A$11)
15052019 | =DateFromFormat(A6, A$11)
19122019 | =DateFromFormat(A7, A$11)
19112019 | =DateFromFormat(A8, A$11)
20012001 | =DateFromFormat(A9, A$11)
06082006 | =DateFromFormat(A10, A$11)
=GuessDateFormat(A1:A10, DATE(2000,1,1), NOW())

В первом столбце есть строки во втором столбце есть даты (не забудьте отформатировать как дату в Excel)

Отсюда вы можете решить, что делать с этими датами, например, отформатировать их в какой-либо формат строки, который вам нравится. Это можно сделать с помощью функции =TEXT() в Excel.

...