Процедура очистки классификатора текста VBA - PullRequest
0 голосов
/ 19 ноября 2018

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

,""10/20/18"""",        >>> ,"10/20/18""",  
,"10/20/18"""4380012"", >>> ,"10/20/18""4380012",  
,"10/20"/18""4380012",  >>> ,"10/20/18""4380012",
,""""4380012",          >>> ,"""4380012",

Моей первой идеей было отметить позиции двух внешних запятых и сохранить расстояние между ними. Я знаю, что по крайней мере должна быть пара кавычек между полями, поэтому я подумал, что перемещение i и i + 1 через поле может быть хорошим способом выяснить, куда оно должно идти, но я не смог определить лучшая конфигурация для этого.
затем я подумал, что нужно войти с обеих сторон, выполнив i = i + 1 и n = n-1 с левой и правой сторон соответственно, но столкнулся с аналогичными трудностями.

Самая большая проблема была, когда на внутренних или внешних краях были дополнительные квалификаторы, а другое поле было пустым.

'My String
strLn as String
'Total number of quotes, good path = 4, bad path > 4
QuoteTotal as Integer
'the First quotes position
FirstQ as Integer
'The Ending quote position
RightQ as Integer
'Counter equals the position of the leading comma
Counter as Integer
'holds the quote character for use throughout code
Q as String
Q = Chr(34)
'Holds the comma character for use throughout the code
C as String
C = Chr(44)
'Holds the position of the last quote and the number of quotes between the fields
Dim LFieldQ As Integer
Dim LFieldQTotal As Integer
LFieldQ = 0
LFieldQTotal = 0
'Tracks position and length of the first data we find moving left to right
Dim LData as Integer
Dim LDatalen as Integer

    For i = Counter To Len(strLn)
        If (Mid(strLn, i, 1) = Q) Then
            LFieldQTotal = LFieldQTotal + 1
        End If
        If (Mid(strLn, i + 1, 1) = Q And Mid(strLn, i + 2, 1) = C) Then
            LFieldQTotal = LFieldQTotal + 1
            LFieldQ = i + 1
            Exit For
        End If
    Next

    If (LFieldQTotal <> 4) Then
        For i = FirstQ + 1 To LFieldQ
            If (Mid(strLn, i, 1) = Q) Then
                strLn = Mid(strLn, 1, i - 1) & Replace(strLn, Q, "", i, 1)
            ElseIf (Mid(strLn, i, 1) <> Q) Then
                LData = i
                For n = i To LFieldQ
                    If (Mid(strLn, n, 1) = Q) Then
                        LDatalen = n - 1
                        i = n
                        Exit For
                    End If
                Next
            End If
        Next
    End If

(я знаю, что это неполно)
этот блок был моей текущей попыткой пройти i и i + 1 через поле. Я пойман на том, что у меня есть счастливый выход, но я не должен этого делать, потому что внешнее выражение if уже определило, что мы не найдем счастливый путь.
Я хочу, чтобы аспект очистки мог убрать любое количество и любую комбинацию дополнительных классификаторов, что также может быть ненужным критерием, который я навязываю, потому что, честно говоря, потенциально будет только один полный дополнительный набор, помещенный в поле, но я хочу, чтобы он работал на все случаи жизни. любые мысли будут оценены. не ищет решенный блок кода, но любой толчок в правильном направлении был бы великолепен.

1 Ответ

0 голосов
/ 20 ноября 2018

часть информации, которую я не знал в начале, всегда будет иметь значение в нужном поле, поэтому мне придется иметь дело только с примерами, такими как

,"""""4380012",         >>> ,"""4380012",
,""""4380012"",         >>> ,"""4380012",
,""10/20/18"""4380012", >>> ,"10/20/18""4380012",

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

Private Sub TestSub()
Dim strLn As String
Dim i As Integer
Dim n As Integer
Dim s As Integer
Dim Q As String
Q = Chr(34)

strLn = "," & Q & Q & Q & "ABC" & Q & Q & Q & Q & Q & "DEF" & Q & ","
LfieldQ = Len(strLn) - 1
MsgBox (strLn)
n = LfieldQ

Do While n > FirstQ
    If (Mid(strLn, n, 1) = Q And Mid(strLn, n - 1, 1) = Q And (n = LfieldQ)) Then
        strLn = Mid(strLn, 1, n - 2) & Replace(strLn, Q, "", n - 1, 1)
        LfieldQ = LfieldQ - 1
        n = n + 1
    ElseIf (Mid(strLn, n, 1) = Q And Mid(strLn, n - 1, 1) <> Q And (n = LfieldQ)) Then
        For i = n - 1 To FirstQ Step -1
            If (Mid(strLn, i, 1) = Q) Then
                n = i
                Exit For
            End If
        Next i
        If (Mid(strLn, n, 1) = Q And Mid(strLn, n - 1, 1) = Q) Then
            n = n - 1
            For i = n - 1 To FirstQ Step -1
                If (Mid(strLn, i, 1) = Q And i <> FirstQ) Then
                    strLn = Mid(strLn, 1, i - 1) & Replace(strLn, Q, "", i, 1)
                ElseIf (Mid(strLn, i, 1) <> Q) Then
                    For s = i To FirstQ Step -1
                        If (Mid(strLn, s, 1) = Q And s <> FirstQ) Then
                            strLn = Mid(strLn, 1, s - 1) & Replace(strLn, Q, "", s, 1)
                            Exit For
                        End If
                    Next
                End If
            Next
        End If



    End If
    n = n - 1
Loop
MsgBox (strLn)
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...