Excel, VB - Character Operations & Date Reformatin

2019-09-05 09:57发布

ISSUE

Large dataset with many improperly or non-uniformly entered dates in a specific field. There are about 19 different ways the dates have been entered in about 60,000 records. Some entries are completely invalid and must be discarded, others must be formatted properly. I am loading the range into an array and then performing the operations. I wrote out the operations as I believe I need, however I need some help in actually getting them working. See code below; error in comments.

CURRENT PROBLEM

For entries like '54 Days' the following code should only take the characters to the left of the space, and then check if they are numeric. If they are, it keeps them, if they are not it empties that array element. In practice, nothing is happening, I still have the full entry in the array element?

ElseIf delType = "String" And Len(del(i, 1)) < 10 And InStrRev(del(i, 1), " ") Then 'Takes the number from entries like 2194 Days or 23 DPD
    del(i, 1) = Left(del(i, 1), Len(del(i, 1)) - InStrRev(del(i, 1), " "))
    If IsNumeric(del(i, 1)) = False Then 'If the characters to the left of the space are not numbers, discard
        del(i, 1) = Empty
    Else
        del(i, 1) = Format((CLng(Range("E" & i + 1).Value) - Abs(del(i, 1))), "mm/dd/yy") 'Pull order date and subtract days from it for delinquency date
    End If

ENTRY TEMPLATES

SEPT. 25, 20 (No year, no year! Delete.)
SEPT (No year, useless, delete.)
N/A (Rubbish! Deleted.)
LONG TIME AG (What moron thought this was a good idea, delete.)
JUNE 30, 200 (Apparently the field will only hold 12 characters, delete.)
CHARGED OFF (Useless, delete.)
94 DAYS (Take all characters preceding space and subtract from other field containing order date to obtain delinquent date.)
94 DPD (DPD in someones bright mind stands for Days Past Due I believe. Same as above.)
2008-7-15 12 (Not sure what additional number is, take all characters before space and transform.)
INVALID (Delete.)
BLANK (Do nothing.)
12282009 (Use nested LEFT and RIGHT and CONCATENATE with / in between.)
9202011 (Add leading zero, then same as above.)
92410 (Add leading zero, this will transform to 09/24/10)
41261 (Days since 31/12/1899, this will transform to 12/08/12)
1023 (Days since delinquent, subtract from ORDER DATE to get delinquent date.)
452 (Same as above.)
12 (Same as above.)
1432.84 (Monetary value, mistakenly entered by low IQ lackey. Delete.)

CODE (WORK IN PROGRESS)

'Perform housekeeping on delinquency date
Columns("AH:AH").Select
Selection.NumberFormat = "0"
Selection.Copy
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
    True, Transpose:=False
Dim del()
ReDim del(1 To importwsRowCount, 1 To 1)
del = Range("AH1:AH" & importwsRowCount).Value
Dim delChars As Long
Dim delType As String
For i = LBound(del, 1) To UBound(del, 1)
    delChars = Len(del(i, 1)) 'Determine length of entry
    If IsNumeric(del(i, 1)) = True Then 'Determine datatype of entry
        delType = "Numeric"
    Else
        delType = "String"
    End If
    If InStr(del(i, 1), ".") Then 'Removes monetary entries like 142.84
        del(i, 1) = Empty
    ElseIf InStr(del(i, 1), "*") Then 'Removes ***INVALID*** entries
        del(i, 1) = Empty
    ElseIf delChars = 12 Then 'Removes all entries that extend beyond the 12 character limit of the field and get cut off
        del(i, 1) = Empty
    ElseIf delType = "String" And Len(del(i, 1)) < 10 And InStrRev(del(i, 1), " ") Then 'Takes the number from entries like 2194 Days or 23 DPD
        del(i, 1) = Left(del(i, 1), Len(del(i, 1)) - InStrRev(del(i, 1), " "))
        If IsNumeric(del(i, 1)) = False Then 'If the characters to the left of the space are not numbers, discard
            del(i, 1) = Empty
        Else
            del(i, 1) = Format((CLng(Range("E" & i + 1).Value) - Abs(del(i, 1))), "mm/dd/yy") 'Pull order date and subtract days from it for delinquency date
        End If
    ElseIf delType = "Numeric" And Len(del(i, 1)) = 5 Then
        If del(i, 1) > CLng(Date) Then 'Value is greater than todays date, improperly formated date that needs character manipulation and / added
            del(i, 1) = Format(del(i, 1), "000000") 'Add leading zero
            del(i, 1) = DateSerial(Right(del(i, 1), 2), Left(del(i, 1), 2), Right(Left(del(i, 1), 2), 4)) 'Grab year, then month, then day for serialize
        Else
            del(i, 1) = Format(del(i, 1), "mm/dd/yy") 'Properly formated date that just needs format conversion
        End If
    ElseIf delType = "Numeric" And (delChars = 7 Or delChars = 8) Then
        If delChars = 7 Then
            del(i, 1) = Format(del(i, 1), "00000000") 'Add leading zero
        End If
        del(i, 1) = DateSerial(Right(del(i, 1), 4), Left(del(i, 1), 2), Right(Left(del(i, 1), 2), 6)) 'Grab year, then month, then day for serialize
    ElseIf delType = "Numeric" And delChars < 5 Then
        del(i, 1) = Format((CLng(Range("E" & i + 1)) - Abs(del(i, 1))), "mm/dd/yy")
    End If
Next i
Set delRange = Range("AJ1:AJ" & importwsRowCount)
iWS.names.Add Name:="dRange", RefersTo:=delRange
Range("dRange").Value = del 'Write array to worksheet

1条回答
聊天终结者
2楼-- · 2019-09-05 10:07

"54 Days" contains 7 characters so Len("54 Days") is 7

The space character occurs in position 3 and InStrRev("54 Days", " ") returns 3

So, we have Left("54 Days", 7 - 3) which produces "54 D" which is obviously not numeric

Perhaps try Left(del(i, 1), InStrRev(del(i, 1), " ") - 1) instead

查看更多
登录 后发表回答