VBA - извлечь определенную часть строки - PullRequest
0 голосов
/ 09 октября 2018

Я довольно новичок в VBA, но не программирую в целом.Я пытаюсь сделать макрос в VBA, который форматирует название модели списка имен телефонов в нечто управляемое.Например, я хочу следующее имя:

P10, 12,9 см (5,1 "), 4 ГБ, 64 ГБ, 20 МП

Форматируется как

P10 5.1 "64 ГБ

Мне удалось извлечь первые два элемента отформатированного имени, используя Split и Mid.

ThisВот мой код для первых двух частей:

'First part of format
firstPart = Trim(Split(modelName, ",")(0))
Debug.Print formattedModelName

'Second part of format
openPos = InStr(modelName, "(")
closePos = InStr(modelName, ")")

secondPart = Mid(modelName, openPos + 1, closePos - openPos - 1)

Мой вопрос заключается в том, как извлечь 64 GB, а не 4 GB.Я попытался перебрать все символы и сохранить последние 5 символов, чтобы увидеть, соответствуют ли они тому, что я хотел.Но должен быть лучший способ.

Буду признателен за любую помощь, большое спасибо

РЕДАКТИРОВАТЬ

Вот еще один пример вводаи вывод по запросу: Ввод:

iPhone iPhone SE, 10,2 см (4 "), 640 x 1136 пикселей, 16 ГБ, 12 Мп, iOS 9, сортировка, Gr

Ожидаемый результат:

iPhone iPhone SE 4 "16 ГБ

Ответы [ 6 ]

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

Использование регулярных выражений:

Допущения:

  • Имя телефона начинается с начала строки и заканчивается первой запятой
  • Размер экрана является первымзапись, которая начинается с числа, которое может быть десятичным, и заканчивается "
  • Память - это последняя запись, которая начинается с целого числа и заканчивается на GB
  • Для этого мы будем использовать Replace метод

Option Explicit
Function phone(S As String) As String
    Dim RE As Object
    Const sPat As String = "^([^,]+).*?(\b[\d.]+"").*(\b\d+\s+GB).*"

Set RE = CreateObject("vbscript.regexp")
With RE
    .Pattern = sPat
    .Multiline = True
    phone = .Replace(S, "$1 $2 $3")
End With

End Function

enter image description here

Объяснение регулярных выражений и замена шаблонов

^([^,]+).*?(\b[\d.]+").*(\b\d+\s+GB).*

Опции: чувствительны к регистру;^ $ совпадение при переносе строки

$ 1 $ 2 $ 3

Создано с помощью RegexBuddy

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

Я немного опоздал на вечеринку!

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

Если ваш текств ячейке A1 затем попробуйте эти формулы для извлечения соответствующей информации:

enter image description here

enter image description here

  1. =LEFT(A1,(FIND(",",A1,1)-1))

  2. =MID(A1,SEARCH("(",A1)+1,SEARCH(")",A1)-SEARCH("(",A1)-1)

  3. =MAX(VALUE(MID(A1,FIND("GB",A1)-3,2)),VALUE(IFERROR(MID(A1,IFERROR(FIND("GB",A1,FIND("GB",A1)+1),0)-3,3),0)))&" GB"

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

Вот функция, которую я сделал, которая должна работать всегда.

Для решения проблемы получения правильного значения хранилища он проходит через каждый раздел, разделенный запятыми, и ищет «ГБ», а затем сохраняетотслеживать наибольшее значение в одном из этих разделов, которое затем должно быть значением хранилища.

Public Function FormatName(Inp As String) As String

    Dim ArrInp As Variant, i As Integer, Temp As String

    ArrInp = Split(Trim(Inp), ",")
    FormatName = ArrInp(0) & " " & Mid(Inp, InStr(Inp, "(") + 1, InStr(Inp, ")") - InStr(Inp, "(") - 1)

    For i = 1 To UBound(ArrInp)
        If InStr(UCase(ArrInp(i)), "GB") <> 0 And Val(ArrInp(i)) > a Then
            Temp = ArrInp(i)
        End If
    Next
    FormatName = FormatName & Temp

End Function

Надеюсь, это поможет.

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

Как насчет использования RegEx для извлечения значений и использования последнего.Просто добавьте ссылку на библиотеку: «Регулярные выражения Microsoft VBScript 5.5».Тогда вы можете сделать это ..

Option Explicit

Public Function xx()
Dim modelName As String
Dim firstPart As String
Dim Pattern As String
Dim GBString As String
Dim regEx As New RegExp
Dim finalName As String
Dim matches As MatchCollection

Let modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
firstPart = Trim(Split(modelName, ",")(0))


With regEx
    .Global = True
    .IgnoreCase = True
    .Pattern = "[0-9]+ GB"
End With

Set matches = regEx.Execute(modelName)

If matches.Count > 0 Then
    GBString = matches(matches.Count)
Else
    GBString = "<unknown GB>"
End If

finalName = firstPart + GBString

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

Попробуйте,

Option Explicit

Function oneTwoThree(str As String)

    Dim vals As Variant

    vals = Split(str, ",")

    oneTwoThree = Join(Array(vals(0), _
                             Split(Split(vals(2), "(")(1), ")")(0), _
                             Trim(vals(4 + (InStr(1, vals(4), "gb", vbTextCompare) = 0)))), " ")

End Function

enter image description here

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

Попробуйте следующий сегмент кода:

Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ",")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String

firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(2), InStr(data(2), "(") + 1), ")", ""))
thirdPart = Trim(data(4))


MsgBox firstPart & " " & secondPart & " " & thirdPart

Вы должны быть очень осторожны с подстрокой данных разделителя.Например, если ваш основной текст P10, 12 cm (5.1"), 4 GB, 64 GB, 20 MP, код больше не работает.Предполагая, что у вас всегда есть запятая и пробел между элементами данных, которые вы могли бы написать вместо:

Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ", ")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String

firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))
thirdPart = Trim(data(3))

MsgBox firstPart & " " & secondPart & " " & thirdPart

И это всегда будет работать.

Если элемент 4 MB не всегда присутствует, выполнитеследующее:

Dim modelName As String: modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
Dim data() As String: data = Split(modelName, ", ")
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String

firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))

Select Case InStr(modelName, "4 GB")
    Case 0
        thirdPart = Trim(data(2))
    Case Else
        thirdPart = Trim(data(3))
End Select

MsgBox firstPart & " " & secondPart & " " & thirdPart

ОБНОВЛЕНИЕ:

Думаю, теперь я получил именно то, что вы хотите.Я попробовал следующий код с тремя примерами, которые вы дали нам по вашему вопросу, и это сработало (проблема была в том, что я не понял, что вы хотели получить последнее значение данных до значения MD.

Dim modelName As String
Dim data() As String
Dim firstPart As String
Dim secondPart As String
Dim thirdPart As String

modelName = "P10, 12,9 cm (5.1""), 4 GB, 64 GB, 20 MP"
data = Split(modelName, ", ")
firstPart = Trim(data(0))
secondPart = Trim(Replace(Mid(data(1), InStr(data(1), "(") + 1), ")", ""))
thirdPart = Trim(data(Application.Match("*MP", data, 0) - 2))

MsgBox firstPart & " " & secondPart & " " & thirdPart

Выможно попробовать с

modelName = "P10, 12,9 cm (5.1""), 64 GB, 20 MP"

или с

modelName = "iPhone iPhone SE, 10,2 cm (4""), 640 x 1136 pixel, 16 GB, 12 MP, iOS 9, Sort, Grå"

Это всегда даст вам ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...