Отображение количества для каждого уникального значения в столбце таблицы

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

Столбец состояния таблицы 1

**status**  
------  
itemA
itemA
itemB
itemC

желаемые результаты в одну ячейку:

Table 1 Status summary |2 itemA, 1 itemB, 1 itemC

Я бы согласился на простой список разделенных запятыми всех различных значений без подсчета.

СПРАВОЧНАЯ ИНФОРМАЦИЯ: У меня есть документ Excel, который мы используем для отслеживания приемочного тестирования нового приложения. Документ, который содержит несколько рабочих листов (каждый из которых представляет собой область кода, которую необходимо протестировать), и каждый рабочий лист имеет несколько таблиц (которые представляют собой тестовые примеры, где каждый случай должен быть протестирован несколько раз или разными способами и т. д.), а затем есть сводную таблицу, где я хочу получить снимок данных. На сводной странице есть строка для каждой таблицы на каждом листе и столбец состояния. В этом столбце статуса я хочу отобразить количество каждого статуса, выбранного в соответствующей таблице. Первоначально я создал длинную формулу, которая жестко закодировала значения и их количество, если количество было> 0, но по мере того, как мы тестируем, мы обнаруживаем необходимость добавлять новые значения состояния, и тогда формула становится слишком обременительной для обновления.

РЕДАКТИРОВАНИЕ: ДОБАВЛЕНИЕ ФОРМУЛЫ Вот формула, которая у меня была изначально

=IF(COUNTIF(Table1[Status],"itemA"),COUNTIF(Table1[Status],"itemA")&" itemA"," ") & IF(COUNTIF(Table1[Status],"itemB"), ", " &COUNTIF(Table1[Status],"itemB")&" itemB"," ") & IF(COUNTIF(Table1[Status],"itemC"), ", " &COUNTIF(Table1[Status],"itemC")&" itemC"," ")

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


person FishyStacy    schedule 30.03.2017    source источник
comment
re: 'Изначально я создал длинную формулу, в которой значения жестко закодированы, и...' Я не вижу формулы.   -  person    schedule 31.03.2017
comment
Я хочу избавиться от формулы, поэтому я не публиковал ранее, отредактировал, чтобы включить формулу.   -  person FishyStacy    schedule 31.03.2017


Ответы (2)


Если ваши ячейки находятся в A1:A4, поместите эту формулу массива в ячейки B1:B4:

{=$A$1:$A$4&": "&COUNTIF($A$1:$A$4,$A$1:$A$4)}

Это создаст ваши строки, которые будут выглядеть как itemA: 2 и itemB: 1, но будут повторения.

Затем вы должны использовать код VBA, который вы предложили в комментариях. Я помещаю это здесь для полноты картины:

Function ConcatUniq(ByRef rng As Range) As String
    Dim r As Range
    Static dic As Object
    If dic Is Nothing Then Set dic = CreateObject("Scripting.Dictionary")
    For Each r In rng
        If r.Value <> Empty Then
            dic(r.Value) = Empty
        End If
    Next
    ConcatUniq = Join$(dic.keys, ", ")
    dic.RemoveAll
End Function

Таким образом, формула ячейки вашей окончательной строки будет выглядеть так:

=ConcatUniq(B1:B4)
person lebelinoz    schedule 30.03.2017
comment
Спасибо за ответ, решение проблемы кажется логичным, но не очень масштабируемым. Сейчас в документе около 100 таблиц, и мне нужно будет сделать это для каждой из них. Кроме того, нежелательно иметь так много шагов, которые нам нужно было бы сделать для добавления новой таблицы. - person FishyStacy; 31.03.2017
comment
Подходит ли решение VBA? Мы можем кое-что выяснить, используя версию моего ответа COUNTIF в виде массива с этим скриптом VBA для объединения уникальных значений в массиве - person lebelinoz; 31.03.2017
comment
Да, VBA подойдет. На самом деле я работал над реализацией решения самостоятельно, но я должен признаться, что могу читать VBA благодаря своим знаниям в области программирования, но я совершенно не умею его писать. Мне удалось заставить его создать список уникальных значений, разделенных запятыми, но не количество для них. - person FishyStacy; 31.03.2017
comment
Function ConcatUniq(ByRef rng As Range) As String Dim r As Range Static dic As Object If dic Is Nothing Then _ Set dic = CreateObject("Scripting.Dictionary") For Each r In rng If r.Value <> Empty Then dic(r.Value) = Empty End If Next ConcatUniq = Join$(dic.keys, ", ") dic.RemoveAll End Function Извините, я не знаю, как здесь форматировать! - person FishyStacy; 31.03.2017
comment
Хорошо, я полностью изменил свой ответ. И я поместил ваш (отформатированный) код VBA как часть своего ответа - person lebelinoz; 31.03.2017

Это решение VBA использует определяемую пользователем функцию, которая:

.- Проверяет, что Target Range принадлежит ListObject (таблице Excel).

.- Использует Array для хранения всех значений статуса из таблицы.

.- Использует строку Control для проверки статуса уникальности.

.- Использует строку Output для хранения списка уникальных статусов с соответствующим количеством.

Примечание. Список будет иметь тот же порядок, что и в таблице. Сортировка не входит в объем вопроса, но если вы хотите, чтобы она была отсортирована, я предлагаю отсортировать ListObject по мере необходимости (не включено).

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

Private Function Lob_Status_Count(rTrg As Range) As String
Const kStt As String = "Status"
Dim lob As ListObject
Dim sControl As String, sOutput As String
Dim aStt As Variant, vStt As Variant, bStt As Byte
    Rem Validate Input
    On Error Resume Next
    Set lob = rTrg.ListObject               'Set ListObject
    On Error GoTo 0
    If lob Is Nothing Then GoTo ExitTkn     'Exit if Target range is not a ListObject

    With lob.ListColumns(kStt).DataBodyRange

        Rem Set Status Array
        aStt = WorksheetFunction.Transpose(.Value2)

        Rem Set Status Output
        For Each vStt In aStt
            If InStr(sControl, Chr(167) & vStt & Chr(167)) = 0 Then     'Validates uniqueness
                bStt = WorksheetFunction.CountIf(.Cells, vStt)          'Gets Status Count
                sOutput = sOutput & ", " & bStt & " " & vStt            'Adds to Results
                sControl = sControl & Chr(167) & vStt & Chr(167)        'Adds to Control
        End If: Next

        Rem Cleanup Output
        sOutput = Replace(sOutput, ", ", vbNullString, 1, 1)

    End With

    Rem Set Results
    Lob_Status_Count = sOutput

Exit Function
ExitTkn:
    Lob_Status_Count = "!Err ListObject"

End Function

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

Использование массивов, Члены ListObject (Excel), Объект WorksheetFunction (Excel),

Для каждого...следующего утверждения Функция InStr, Заявление об ошибке.

person EEM    schedule 31.03.2017