Как я могу вспомнить правильный номер из текстовой строки в Excel? - PullRequest
2 голосов
/ 02 мая 2020

Рассмотрим следующую текстовую строку:

(*4,14)(7,15)(10,13)(9,12)-(1,8)(2,6)-5,3-11

Моя цель - подсчитать, сколько левых скобок ("("), запятых вне скобок и дефисов перед каждым отдельным числом в этой строке (например, 3 левые скобки перед номером 10, 6 левых скобок и 3 дефиса перед 11).

Мое текущее решение состоит в том, чтобы сначала вызвать оставшуюся текстовую строку перед каждым отдельным числом, просто =LEFT(A1,(FIND("1",A1,1)-1)), но случается, что Excel будет вызывать строку, появившуюся перед первым «1» (т. е. (*4,), вместо вызова оставшейся строки из фактического числа «1» в строке (т. е. (*4,14)(7,15)(10,13)(9,12)-().

Примечание, есть идеи, как посчитать количество запятых за скобками?

Помощь будет очень полезна!

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

Если у вас есть версия Excel с функцией FILTERXML (Windows Excel 2013+), вы можете использовать:

=SUM(LEN(FILTERXML("<t>" & SUBSTITUTE(SUBSTITUTE(A1,"(","<s>"),")","</s>") & "</t>","//t")))- LEN(SUBSTITUTE(FILTERXML("<t>" & SUBSTITUTE(SUBSTITUTE(A1,"(","<s>"),")","</s>") & "</t>","//t"),",",""))

Формула создает xml, где s узлы - это то, что включено в скобки, а узел t - это все остальное.

Если у вас нет функции FILTERXML, решение VBA будет лучшим решением. Зависит от вашей версии Excel и от Windows или MA C.

1 голос
/ 02 мая 2020

Количество символов

enter image description here

Option Explicit

Function countChars(SourceString As String, SourceNumber As Variant, _
  CountChar As String, Optional countRight As Boolean = False) As Long

    Dim NumberDouble As Double
    Dim NumberString As String
    Dim NumberLength As Long
    Dim StringLength As Long
    Dim CurrentStart As Long
    Dim CurrentFound As Long
    Dim i As Long
    Dim isFound As Boolean

    StringLength = Len(SourceString)

    If VarType(SourceNumber) = 8 Then
        If Not IsNumeric(SourceNumber) Then _
          Exit Function   ' SourceNumber is not numeric.
    End If
    NumberDouble = Val(SourceNumber)
    If NumberDouble <> Int(NumberDouble) Then _
      Exit Function       ' SourceNumber is not an integer.
    NumberString = CStr(NumberDouble)
    NumberLength = Len(NumberString)

    CurrentStart = 1
    Do
        CurrentFound = InStr(CurrentStart, SourceString, NumberString)
        GoSub checkNumber
        If isFound Then
            GoSub countTheChars
            Exit Do
        End If
        CurrentStart = CurrentFound + 1
    Loop Until CurrentFound = 0

Exit Function

countTheChars:  ' Can be written better.
    If Not countRight Then
        For i = 1 To CurrentFound - 1
            If Mid(SourceString, i, 1) = CountChar Then
                countChars = countChars + 1
            End If
        Next i
    Else
        For i = CurrentFound + 1 To StringLength
            If Mid(SourceString, i, 1) = CountChar Then
                countChars = countChars + 1
            End If
        Next i
    End If

checkNumber:  ' Check for adjacent numbers.
   Select Case CurrentFound
       Case 0: Exit Function  ' NumberString (initially) not found.
       Case 1                 ' NumberString found at the beginning.
           isFound = Not _
             IsNumeric(Mid(SourceString, CurrentFound + NumberLength, 1))
       Case StringLength - NumberLength + 1   ' NumberString found at the end.
           isFound = Not _
             IsNumeric(Mid(SourceString, CurrentFound - 1, 1))
       Case Else               ' NumberString found in the middle.
           isFound = Not _
             IsNumeric(Mid(SourceString, CurrentFound + NumberLength, 1)) _
             And Not IsNumeric(Mid(SourceString, CurrentFound - 1, 1))
   End Select
Return

End Function
...