Функция VBA или Excel для подсчета ненулевых значений в строке через запятую - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть ячейка (я), которая содержит следующее: [90,90,90,0,90].

Я хочу только посчитать ненулевые цифры до или после запятой.

Итак, в приведенном выше примере ответ 4, так как «90» появляется 4 раза.

Если в ячейке содержится [180,180,0,0,0,0,0,0,90], ответ будет 3.

Есть ли функция VBA или Excel (воспроизводится с помощью LEN, ЗАМЕНА, ТРИМ и т. Д. Без удачи) чтобы сделать это?

Спасибо,

Тим

Ответы [ 4 ]

0 голосов
/ 03 декабря 2018

Приведенная ниже формула массива сделает то, что вы хотите.

Чтобы ввести / подтвердить формулу массива , удерживайте нажатой клавишу ctrl + смещение при нажатии введите .Если вы сделаете это правильно, Excel поместит фигурные скобки {...} вокруг формулы, отображаемой в строке формул.

=SUM(--IFERROR(-TRIM(MID(SUBSTITUTE(A1,",",REPT(" ",99)),seq_99,99))<>0,0))

, где seq_99 - Именованная формула, которая ссылается на:

=IF(ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))=1,1,(ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))-1)*99)
  • SUBSTITUTE заменяет каждую запятую на 99 пробелов
  • Функция MID с формулой seq_99 для start_number возвращает массив значений, начиная с {1,99,198,297,...} `которое будет каждым из значений в строке.
  • TRIM удаляет лишние пробелы из каждого элемента массива
  • - преобразует строковое представление числа вчисловое значение
    • Это вернет ошибку для нулевых строк в массиве
  • Затем мы проверяем каждый элемент в массиве, чтобы убедиться, что он не равен нулю,
    • Это вернет массив `{TRUE, FALSE, # VALUE!, ...}
    • IFERROR преобразует ошибки в нули
  • Сумма затем добавит все значения TRUE (TRUE = +1 в Excel)

Для метода VBA:

Option Explicit
Function nonZero(s As String) As Long
    Dim v, w
    Dim l As Long
v = Split(s, ",")
For Each w In v
    If Val(w) <> 0 Then l = l + 1
Next w
nonZero = l
End Function

РЕДАКТИРОВАТЬ Я предположил, что скобки […], которые вы показываете, на самом деле не были в ячейке, но показали границы ячейки.Если они могут быть, а могут и не быть в ячейке, вы должны изменить приведенную выше формулу на:

=SUM(--IFERROR(-TRIM(MID(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"[",""),"]",""),",",REPT(" ",99)),seq_99,99))<>0,0))

или пользовательскую функцию на:

Option Explicit
Function nonZero(s As String) As Long
    Dim v, w
    Dim l As Long
    Dim str As String
str = Replace(s, "[", "")
str = Replace(str, "]", "")

v = Split(str, ",")
For Each w In v
    If Val(w) <> 0 Then l = l + 1
Next w
nonZero = l
End Function
0 голосов
/ 03 декабря 2018

Построим формулу Excel шаг за шагом, чтобы вы могли увидеть подход.

План состоит в том, чтобы рассчитать длину строки, не содержащей нулевых элементов, и сравнить ее сдлина исходной строки.

Первый шаг - заменить любые нулевые элементы пустыми строками.Но мы не можем просто удалить все нули, потому что в ненулевых записях могут быть нули (например, «100»).Таким образом, мы должны определить записи списка.

Здесь я предполагаю пару вещей:

  1. Между запятыми и элементами списка не будет пробелов (пробелов).
  2. Если элемент списка начинается сноль, то элемент равен нулю.Другими словами, ведущие нули (например, 012) НЕ допускаются.

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

Итак, мы можем удалить ноль элементов, подставив ", 0" в ",".Но мы попали в ловушку.Подстановка ", 0" не найдет 0, если это первый элемент.Итак, давайте добавим запятую перед первым элементом списка чисел.Это позволяет нам использовать «, 0» для замены.

=Substitute(ref, "[", "[,")

Я использую 'ref' в качестве адреса ячейки, где находится строка.

Теперь давайте добавимЗаменить, чтобы избавиться от 0 элементов из списка:

=Substitute(Substitute(ref, "[", "[,"), ",0", ",")

Обратите внимание, что мы используем результаты первого (внутреннего) замещения в качестве входных данных для второго (внешнего) заменителя.

Теперь найдите число удаленных нулевых элементов, сравнив длину исходной строки с длиной вычисленной строки:

=Len(ref) - Len(Substitute(Substitute(ref, "[", "[,"), ",0", ",")) + 1

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

Прежде чем копировать формулу в Excel, не забудьте изменить 'ref' на фактическую ссылку на ячейку.Это происходит в двух местах в формуле.

0 голосов
/ 03 декабря 2018

очевидно, мой первоначальный ответ не помог ..

вот мой обновленный ответ:

Public Function NonZero(str As String) As Integer

    NonZero = 0
    str = Replace(Replace(Replace(str, " ", ""), "[", ""), "]", "") ' get rid of bracket & space, or whatever...


    Dim x As Integer
    Do While Len(str) > 0

        x = InStr(1, str, ",")
        If x = 1 Then       'start with ","
            str = Right(str, Len(str) - 1)
            x = InStr(1, str, ",")
        End If

        If x > 0 Then
            If Val(Left(str, x - 1)) <> 0 Then
                NonZero = NonZero + 1
            End If
            str = Right(str, Len(str) - x)
        Else
            If Val(str) <> 0 Then
                NonZero = NonZero + 1

            End If
            str = ""
        End If
    Loop

End Function

результат теста: enter image description here

0 голосов
/ 03 декабря 2018

Если ваши данные так строги, как показано:

  • не имеет пробелов между запятыми
  • не имеет ненулевых чисел с ведущими нулями, например 0180

тогда будет работать следующая очень неэффективная формула:

=(LEN(A1)-LEN(SUBSTITUTE(A1,",",""))) + 1 - (
   (LEN(A1)-LEN(SUBSTITUTE(A1,",0",",")))
  +(LEN(A1)-LEN(SUBSTITUTE(A1,"[0,","[,")))
  +(LEN(A1)-LEN(SUBSTITUTE(A1,",0]",",]")))
)

В противном случае вам, вероятно, следует использовать VBA:

Public Function CountNonZero(ByVal s As String) As Long
  Dim arr() As String
  arr = Split(Mid$(Trim$(s), 2, Len(s) - 2), ",")

  Dim i As Long
  For i = LBound(arr) To UBound(arr)
    If Trim$(arr(i)) <> "0" Then CountNonZero = CountNonZero + 1
  Next
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...