2014-05-07 3 views
0

Я работаю на разбор текстового файла, который имеет строки, подобные этим:InStr разделителя вопрос

Некоторый текст (2934418) - KB2933528 - XP x86
Некоторый текст - KB2923392
SOMETEXT - KB2933528 - XP x64/2003

(Примечание: нет пустых строк не на текстовый файл)

Я пытаюсь использовать Функция InStr для анализа текста и получения только номеров KB, но я не могу понять, какие разделители использовать для этого. Поскольку «-» - это те же символы, он продолжает возвращать одно и то же значение вместо поиска второго «-». Вот код, который у меня есть прямо сейчас.

intKbOpen = InStr(1, linedata, "-") intKbClose = InStr(1, linedata, "-") intKbDelta = (intKbOpen - intKbClose) strKb = Mid(linedata, intKbOpen, intKbDelta)

ответ

1

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

intKbOpen = InStr(1, linedata, "-") + 1 
intKbClose = InStr(intKbOpen, linedata, "-") 
If intKbClose = 0 Then 
    intKbClose = Len(linedata) 
    intKbDelta = (intKbClose - intKbOpen) - 1 
    strKb = Trim(Mid(linedata, intKbOpen + 1, intKbDelta + 1)) 
Else 
    intKbDelta = (intKbClose - intKbOpen) - 1 
    strKb = Trim(Mid(linedata, intKbOpen + 1, intKbDelta)) 
+0

Это работает для первой и последней строки текстового файла. Но так как во второй строке отсутствует вторая «-», я получаю ошибку во время выполнения. потому что intKbDelta - отрицательное число – user3586080

+0

@ user3586080 Я обновил код, чтобы обработать эту ситуацию. –

+0

Спасибо, все. Пришлось немного поиграть с ним и добавить IF ... Затем ... Else заявление, но он получил правильную работу с вашей помощью! – user3586080

3

Я мог бы предложить, используя регулярные выражения вместо этого? Если вы перейдете в Инструменты ---> Ссылки в VBE, установите флажок «Время выполнения сценариев Microsoft». Это позволяет получить доступ к классу RegExp, который можно использовать следующим образом:

Public Sub Test() 
    Dim oRegExp As RegExp 
    Set oRegExp = New RegExp 

    Dim oMatches As MatchCollection 
    Dim oMatch As Match 

    With oRegExp 
     .Global = True 'It will find all the matches, not just the first one 
     .IgnoreCase = True 'I'm assuming you would still want to capture even if the "kb" is lowercase 
     .Multiline = True 'I'm assuming your data may have end-of-line characters in it 
     .Pattern = "KB\d+" 'This means, match the letter K, then the letter B, then one or more digits. Ignore everything else. 
     Set oMatches = .Execute("Some text (2934418) - KB2933528 - XP x86 Some text - KB2923392 Sometext - KB2933528 - XP x64/2003") 
    End With 

    For Each oMatch In oMatches 
     Debug.Print oMatch 
    Next 
End Sub 

Выполнение этой функции приводит к следующему печатаемого немедленному окна в VBA:

KB2933528 
KB2923392 
KB2933528 
+0

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

+1

Хорошо, удачи! Если у вас есть такая возможность, вы можете посмотреть [Регулярные выражения] (http://www.regular-expressions.info/quickstart.html), поскольку они обеспечивают большую мощность, чтобы точно указать, что вы хотите. Возможно, они могут помочь вам в будущих проектах :) – Blackhawk

1

Некоторые заметки, не подходит для SQL, кроме как UDF, который не будет доступен за пределами MS Access.

x1 = "Some text (2934418) - KB2933528 - XP x86" 
x2 = "Some Text - KB2923392" 
x3 = "Sometext - KB2933528 - XP x64/2003" 

astrX = Split(x1, "-") '' And so on 

For i = 0 To UBound(astrX) 
    ''# is any number 
    If astrX(i) Like "*KB###*" Then 
     sKB = astrX(i) 
    End If 
Next 

Debug.Print sKB