В Excel с VB я не мог изменить все вхождения между {MyText} на нижний регистр

В Excel VBA я не мог изменить все вхождения между {MyText} на нижний регистр.

Я просматривал весь столбец A и B, и каждый раз, когда я находил текст между {}, я меняю его на нижний регистр.

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

как напр. в ячейке у нас было "Bla Bla Bla {Abc} bla bla {xYz} и {HELLO}"

У меня было бы в результате "Бла Бла Бла {abc} бла бла {xYz} и {HELLO}"

Однако я ожидаю, что это будет так:

"Бла-бла-бла {abc} бла-бла {xyz} и {привет}"

Даже если я снова запускаю код, он применяется только в первом случае, ниже приведен VBA, который у меня был:

Set MyRange = Worksheets("Sheet1").Range("G:G,H:H") 
Dim temp As String
For Each c In MyRange 
    If c.Value Like "*{*" Then      
    temp = Split(c.Value, "{")(1)        
    temp = Split(temp, "}")(0)        
    c.Value = Replace(c.Value, temp, LCase(temp))           
    Else
    End If
Next c
End Sub

Regex может быть здесь хорошим.

BigBen 22.03.2022 15:04

Привет, BigBen. К сожалению, я раньше не работал, не могли бы вы помочь во всем этом? Спасибо.

SeifeddineBMZ 22.03.2022 15:08
stackoverflow.com/questions/22542834/…
BigBen 22.03.2022 15:09

Пример шаблона RegEx, который вы могли бы использовать: https://regex101.com/r/1gP1Ms/1

Pᴇʜ 22.03.2022 15:12
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
2
4
79
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Простое решение без RegEx может работать следующим образом:

Sub test()
    Debug.Print LowerCaseBrackets("Bla Bla Bla {Abc} bla bla {xYz} and {HELLO}")
End Sub

Public Function LowerCaseBrackets(ByVal InputString As String) As String
    Dim SplitStarts() As String
    
    SplitStarts = Split(InputString, "{")
    
    Dim iStart As Variant
    For iStart = LBound(SplitStarts) + 1 To UBound(SplitStarts)
        Dim EndPos As Long
        EndPos = InStr(SplitStarts(iStart), "}")
        SplitStarts(iStart) = LCase(Left$(SplitStarts(iStart), EndPos - 1)) & Mid$(SplitStarts(iStart), EndPos)
    Next iStart
    
    LowerCaseBrackets = Join(SplitStarts, "{")
End Function

Split разобьет строку на следующие части:

Bla Bla Bla 
Abc} bla bla 
xYz} and 
HELLO}

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

For iStart = LBound(SplitStarts) + 1

Перебираем следующие части строки и ищем положение концевой скобки в этой части

EndPos = InStr(SplitStarts(iStart), "}")

Затем мы берем левое искусство, преобразуем его в нижний регистр.

LCase(Left$(SplitStarts(iStart), EndPos - 1))

и добавьте остальные с

& Mid$(SplitStarts(iStart), EndPos)

После этого цикла наш массив SplitStarts выглядит так:

Bla Bla Bla 
abc} bla bla 
xyz} and 
hello}

И присоединяем его с помощью открывающей скобки

LowerCaseBrackets = Join(SplitStarts, "{")

чтобы получить нашу последнюю строку

Bla Bla Bla {abc} bla bla {xyz} and {hello}

Другим альтернативным решением может быть

Public Function LowerCaseBrackets(ByVal InputString As String) As String
    Dim Pos As Long
    Do While InStr(Pos + 1, InputString, "{")
        Dim EndPos As Long
        EndPos = InStr(Pos + 1, InputString, "}")
        
        Mid(InputString, Pos + 1, EndPos - 1) = LCase(Mid(InputString, Pos + 1, EndPos - 1))
        Pos = EndPos
    Loop
    LowerCaseBrackets = InputString
End Function
Ответ принят как подходящий

Regex - хороший способ. Однако, если вы ищете решение VBA, попробуйте следующее. Код учитывает неправильный ввод, как показано в тестовых примерах:

Option Explicit

Private Sub Test()
   Debug.Print Lowercase("Bla Bla Bla {Abc} bla bla {xYz} and {HELLO}")
   Debug.Print Lowercase("Bla Bla Bla bla bla ")
   Debug.Print Lowercase("Bla Bla Bla and {HELLO")
End Sub

Private Function Lowercase(ByVal Value As String) As String
   Dim i As Integer
   Dim j As Integer
   
   j = 1
   
   Do
      If j > 0 Then
         i = InStr(j, Value, "{")
         
         If i > 0 Then
            j = InStr(i, Value, "}")
            If j > 0 Then Mid(Value, i + 1, j - i - 1) = LCase(Mid(Value, i + 1, j - i - 1))
         End If
      End If
   Loop While i > 0 And j > 0
   
   Lowercase = Value
End Function

Вау, я на самом деле очень удивлен, что Mid(Value, i + 1, j - i - 1) = LCase(Mid(Value, i + 1, j - i - 1)) работает. Никогда бы не подумал, что это вообще что-то заменит в Value.

Pᴇʜ 22.03.2022 16:01

Возможно, немного удивительно, но это в официальная документация.

Brian M Stafford 22.03.2022 16:22

А как насчет этого подхода?
Я предлагаю вам следить за тем, чтобы быть внутри или вне "региона" фигурных скобок, используя логическое значение, что-то вроде (±псевдокод):

dim b_inside as Boolean;
dim Line as string; ' this is the text you're going to manipulate

for (int i = 0, i < Line.Length, i++):
    if Line[i] == "{" then b_inside = True;
    if Line[i] == "}" then b_inside = False;
    
    if b_inside and 
      (Line[i] >= "A") and 
      (Line[i] <= "Z")
    then Line[i] = LowerCase(Line[i])
next i

Я бы пропустил (Line[i] >= "A") and (Line[i] <= "Z") и вставил все символы от b_inside до LCase(Line[i]), потому что есть иностранные языки, в которых есть буквы, отличные от A-Z, которые нужно преобразовать в немецкие ÄÜÖ. • Теперь было бы интересно, какой из трех подходов быстрее ;)

Pᴇʜ 22.03.2022 16:20

Моя версия ответа анализирует строку, потому что вы можете заменить тот же текст, но НЕ заключенный в "{}":

Option Explicit

Sub test()
    Dim origText As String
    Dim lowerText As String
    origText = "Bla Abc Bla {Abc} bla bla {xYz} and {HELLO}"
    lowerText = MakeItLower(origText)
    Debug.Print "original text: " & origText
    Debug.Print "   lower text: " & lowerText
End Sub

Function MakeItLower(ByVal text As String) As String
    Dim result As String
    Dim pos0 As Long
    Dim pos1 As Long
    Dim pos2 As Long
    pos0 = 1
    pos1 = InStr(1, text, "{", vbTextCompare)
    Do While pos1 > 0
        result = result & Mid$(text, pos0, pos1 - pos0 + 1)
        pos2 = InStr(pos1, text, "}", vbTextCompare)
        If pos2 > 0 Then
            Dim textToReplace As String
            textToReplace = Mid$(text, pos1 + 1, pos2 - pos1 - 1)
            result = result & LCase(textToReplace) & "}"
            pos0 = pos2 + 1
        End If
        pos1 = InStr(pos2, text, "{", vbTextCompare)
    Loop
    MakeItLower = result
End Function

Другие вопросы по теме