Excelで範囲(C2:C2080)の一意の値をカウントする必要があります。 Googled式:
=SUM(IF(FREQUENCY(MATCH(C2:C2080;C2:C2080;0);MATCH(C2:C280;C2:C2080;0))>0;1))
不正な値を返します。
UPD:ラメソリューション:
Sub CountUnique()
Dim i, count, j As Integer
count = 1
For i = 1 To 470
flag = False
If count > 1 Then
For j = 1 To count
If Sheet1.Cells(i, 3).Value = Sheet1.Cells(j, 11).Value Then
flag = True
End If
Next j
Else
flag = False
End If
If flag = False Then
Sheet1.Cells(count, 11).Value = Sheet1.Cells(i, 3).Value
count = count + 1
End If
Next i
Sheet1.Cells(1, 15).Value = count
End Sub
=SUM(IF(FREQUENCY(IF(LEN(A2:A10)>0,MATCH(A2:A10,A2:A10,0),""), IF(LEN(A2:A10)>0,MATCH(A2:A10,A2:A10,0),""))>0,1))
http://office.Microsoft.com/en-us/Excel/HP030561181033.aspx
VBAマクロを作成することもできます(ただし、それが目的であるかどうかはわかりません)。
効果のあるもの(A1-A11が入力され、B1-B11が空のスプレッドシートがある場合):
Sub CountUnique()
Dim count As Integer
Dim i, c, j As Integer
c = 0
count = 0
For i = 1 To 11
Sheet1.Cells(i, 2).Value = Sheet1.Cells(i, 1).Value
c = c + 1
For j = 1 To c
If CDbl(Sheet1.Cells(i, 1).Value) = CDbl(Sheet1.Cells(j, 2).Value) Then
c = c - 1
Exit For
End If
Next j
Next i
' c now equals the unique item count put in the 12'th row
Sheet1.Cells(12, 1).Value = c
End Sub
ここに私のために働くVBA機能があります。
ワークシート関数 として使用できます。たとえば、「= CountUnique(N8:O9)」など、任意の範囲を参照します。
テキストと数値を処理し、空白のセルを1つの値として扱います
配列関数を扱う必要はありません。
dictionary object の場合、Microsoft Scripting Libraryへの参照が必要です。
Public Function CountUnique(rng As Range) As Integer
Dim dict As Dictionary
Dim cell As Range
Set dict = New Dictionary
For Each cell In rng.Cells
If Not dict.Exists(cell.Value) Then
dict.Add cell.Value, 0
End If
Next
CountUnique = dict.Count
End Function
試してください:
=SUM(IF(FREQUENCY(C2:C2080,C2:C2080)>0,1))
編集:上記は、列の空白のエントリを処理します
JustinGの機能は、Excelのなんらかの制限のために一意のアイテムの数が32,767を超えるまで、非常に適切に(そして高速に)機能します。
あなたが彼のコードを変更した場合、私は見つけました
Public Function CountUnique(rng As Range) As Integer
そしてそれを...
Public Function CountUnique(rng As Range) As Long
その後、よりユニークなアイテムを処理します。
@JustinGのディクショナリメソッドを引き続き使用しようとしている人は、新しいバージョンのVBAを使用している場合はコードを少し変更する必要があります。
次のように、「Microsoft Scripting Runtime」を参照し、Dictionary
の前にScripting
を付ける必要があります。
Public Function CountUnique(rng As Range) As Long
Dim dict As Scripting.Dictionary
Dim cell As Range
Set dict = New Scripting.Dictionary
For Each cell In rng.Cells
If Not dict.Exists(cell.Value) Then
dict.Add cell.Value, 0
End If
Next
CountUnique = dict.Count
End Function
これを読んでさらに調査した結果、私がここで目にするものよりもうまく機能するものが1つあります。
配列入力:
(Ctrl + Shift + Enter、中括弧は含めない)
{=SUM(IFERROR(1/COUNTIF(C2:C2080,C2:C2080),0))}
またはVBAで:
MyResult = MyWorksheetObj.Evaluate("=SUM(IFERROR(1/COUNTIF(C2:C2080,C2:C2080),0))")
数値とテキストの両方で機能し、空白のセルを処理し、参照されたセルのエラーを処理し、VBAで機能します。これは、私が見た中で最もコンパクトなソリューションの1つでもあります。 VBAで使用すると、配列数式である必要性が自動的に処理されるようです。
エラーを処理する方法は、一意の数にエラーを含めるだけです。たとえば、#DIV/0!を返す2つのセルがあるとします。 3つのセルが#VALUE!を返す場合、これらの5つのセルは一意の値の最終的なカウントに2を追加します。エラーを完全に除外したい場合は、修正する必要があります。
私のテストでは、上記のジェイコブのものはテキストではなく数値に対してのみ機能し、参照セルのエラーを処理しません(参照セルのいずれかがエラーを返す場合はエラーを返します)。
=SUM(IF(FREQUENCY(G4:G29,G4:G29)>0,1))
また、単純に フィルターを使用して一時的に一意の値を表示 し、フィルターされた値をカウントすることもできます。
これは、多数の行を処理するより効率的な方法かもしれません。これは、一度に各セルを循環するのではなく、組み込みのAdvancedFilterコマンドを使用します。
Public Function UniqueValues(oRange As Range) As Variant
' Uses the built-in AdvancedFilter Excel command to return the unique values onto the Worksheet
' and then populate and retuns an array of unique values
' Note: The index:0 element in the returned array will be the header row.
' You can ignore this element unless the first row in your oRange is a unique value
' in which case the header will be that value.
Dim oTarget As Range
Dim r As Long, numrows As Long
Dim vs1, vs2 As Variant
' Get the first unused cell on the first row where the unique vaues will be temporarily populated
Set oTarget = oRange.SpecialCells(xlLastCell) ' the last cell on the worksheet
Set oTarget = oTarget.Parent.Cells(1, oTarget.Column + 1) ' the first unused cell on the first row
' Copy the unique values from your oRange to the first unused cell on row 1
oRange.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=oTarget, Unique:=True
' Get the number of rows including the first row which is the header
numrows = WorksheetFunction.CountA(oTarget.EntireColumn)
' create an 2-dim array of the rows
vs1 = oTarget.Resize(numrows)
' Prepare a second 1-dim array for the result
ReDim vs2(numrows)
' Transfer the 2-dim array into the 1-dim array
For r = 1 To UBound(vs1, 1)
vs2(r - 1) = vs1(r, 1)
Next
' Return the 1-dim array as the function result
UniqueValues = vs2
' Clean up the extra column on the worksheet
oTarget.EntireColumn.Delete
End Function
https://excelchamps.com/blog/count-unique-values-Excel/ を見てください。あなたの答えがあります。
入力する必要がある数式は次のとおりです。
=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))
この数式を配列として入力すると、次のようになります。
{=SUMPRODUCT(1/COUNTIF(C2:C2080,C2:C2080))}
式は私のために働きます。これが機能しない原因はいくつかあります。まず、すべてのターゲットセルに値が必要です。これが機能しないもう1つの例は、値が31のセルとテキスト値が「31」の別のセルがある場合です。これらは異なる値として認識されます。
あなたはこれを試すことができます:
=SUM(IF(FREQUENCY(IF(LEN(B2:B11)>0,MATCH(B2:B11,B2:B11,0),""), IF(LEN(B2:B11)>0,MATCH(B2:B11,B2:B11,0),""))>0,1))
これはarray数式です。 Enterキーを押して確認する代わりに、Ctrl + Shift + Enterキーを押す必要があります。
からです:
これを行う別の方法はこれです:
Sub CountUnique()
Dim Count, x, a, lastRow, Values(), StringValues
a = ActiveCell.Column
a = GetLetterFromNumber(a)
lastRow = Range(a & Rows.Count).End(xlUp).row
Count = 0
For Each c In Range(Range(a & "1"), Range(a & Rows.Count).End(xlUp))
If c.row = 1 Then
ReDim Values(lastRow)
Values(Count) = c.Value
Count = Count + 1
End If
StringValues = Join(Values, "#")
StringValues = "#" + StringValues
If InStr(1, StringValues, c.Value) = 0 Then
Values(Count) = c.Value
Count = Count + 1
End If
Next c
MsgBox "There are " & Count & " unique values in column " & a
End Sub
カウントしている列の行1にアクティブセルがある必要があります。