Obtendo valores exclusivos no Excel usando apenas fórmulas
-
07-07-2019 - |
Pergunta
Você sabe uma maneira no Excel para "calcular" por fórmula uma lista de valores exclusivos?
"red"
"blue"
"red"
"green"
"blue"
, "black"
e eu quero ter como resultado "red
, "blue"
, "green"
, "black"
+ eventualmente 2 outras células em branco .
Eu já encontrei uma maneira de obter uma lista ordenada calculada usando SMALL ou LARGE combinado com INDEX, mas eu gostaria de ter este tipo calculado bem, sem o uso VBA.
Solução
Este é um oldie, e há algumas soluções lá fora, mas eu vim com uma fórmula mais curta e mais simples do que qualquer outro que eu encontrei, e que poderia ser útil para qualquer pessoa passando.
Eu tenho chamado a lista de cores Colors
(A2: A7), ea fórmula array colocar na célula C2 é a seguinte ( fixa ) :
=IFERROR(INDEX(Colors,MATCH(SUM(COUNTIF(C$1:C1,Colors)),COUNTIF(Colors,"<"&Colors),0)),"")
Uso Ctrl+Shift+Enter
para inserir a fórmula em
Explicação com dados de amostra { "vermelho"; "azul"; "vermelho"; "verde"; "azul"; "Preto"}:
-
COUNTIF(Colors,"<"&Colors)
retorna uma matriz (# 1) com a contagem de valores que são menores, em seguida, cada item dos dados {4; 1; 4; 3; 1; 0} (preto = 0 artigos menor, azul = 1 ponto, vermelho = 4 itens). Isso pode ser traduzido para um valor sort para cada item. -
COUNTIF(C$1:C...,Colors)
retorna um array (# 2) com 1 para cada item de dados que já está no resultado de classificação. Em C2 ele retorna {0; 0; 0; 0; 0; 0} e em C3 {0; 0; 0; 0; 0; 1} porque "negro" é o primeiro na classificação e última nos dados. Em C4 {0; 1; 0; 0; 1; 1}. Indica "preto" e todas as ocorrências de "azul" já estão presentes - A
SUM
retorna ok-th valor de classificação, por contagem de todos os valores de ocorrências menores que já estão presentes (soma de matriz # 2). -
MATCH
encontra o primeiro índice do-th k valor sort (índice em ordem # 1). - O
IFERROR
é apenas para esconder o erro#N/A
nas células de fundo, quando o ordenado lista única é completa.
Para saber quantos itens exclusivos que você pode usar este fórmula regular :
=SUM(IF(FREQUENCY(COUNTIF(Colors,"<"&Colors),COUNTIF(Colors,"<"&Colors)),1))
Outras dicas
Ok, eu tenho duas idéias para você. Esperemos que um deles vai chegar onde você precisa ir. Note-se que a primeira ignora o pedido para fazer isso como uma fórmula, uma vez que a solução não é bonito. Achei que certifique-se o caminho mais fácil realmente não iria funcionar para você;. ^)
Use o comando Filtro avançado
- Selecione a lista (ou colocar o seu lugar selecção dentro da lista e clique em ok se o diálogo vem reclamando que Excel não sabe se a sua lista contém cabeçalhos ou não)
- Escolha Filtro de Dados / Avançado
- Escolha "Filtrar a lista, no local" ou "Copiar para outro local"
- Clique em "Único registra apenas"
- Clique em OK
- Está feito. Uma lista única é criada, quer no local ou em um novo local. Note que você pode gravar esta ação para criar uma linha de script VBA para fazer isso que então poderia possível ser generalizado para o trabalho em outras situações para você (por exemplo, sem as etapas manuais listados acima).
Usando fórmulas (note que eu estou construindo na solução Locksfree para acabar com uma lista sem buracos)
Esta solução irá trabalhar com as seguintes ressalvas:
Aqui está o resumo da solução:
- Para cada item na lista, calcular o número de duplicatas acima dele.
- Para cada lugar na lista única, calcular o índice do item exclusivo seguinte.
- Finalmente, use os índices para criar uma nova lista com apenas os itens únicos.
E aqui está um exemplo passo a passo:
- Abra uma nova planilha
- Na A1: A6 entrar no exemplo dado na pergunta original ( "vermelho", "azul", "vermelho", "verde", "azul", "negro")
- Ordenar a lista: colocou a seleção na lista e escolha o comando sort.
- Na coluna B, calcule as duplicatas:
- Em B1, digite "= IF (COUNTIF ($ A $ 1: A1, A1) = 1,0, COUNTIF (A1: $ A $ 6, A1))". Note que o "$" nas referências de células são muito importantes, uma vez que fará com que o próximo passo (preencher o resto da coluna) muito mais fácil. O "$" indica uma referência absoluta de modo a que quando o conteúdo da célula é cópia / colado a referência não irá actualizar (em oposição a uma referência relativa que irá actualizar).
- Use cópia inteligente para preencher o resto da coluna B: Select B1. Passe o mouse sobre o quadrado preto no canto inferior direito da seleção. Clique e arraste para baixo para a parte inferior da lista (B6). Quando você soltar, a fórmula será copiado para B2: B6 com as referências relativas atualizados.
- O valor de B1: B6 agora deve ser "0,0,1,0,0,1". Observe que o "1" entradas indicam duplicatas.
- Na coluna C, criar um índice de itens exclusivos:
- Na C1, introduzir "= Fila ()". Você realmente só quero C1 = 1, mas utilizando Row () significa que esta solução irá funcionar mesmo que a lista não começar na linha 1.
- Em C2, introduzir "= IF (C1 + 1 <= FILEIRA ($ B $ 6), C 1 + 1 + INDEX ($ B $ 1: $ B $ 6, C 1 + 1), C1 + 1) ". O "se" está a ser usado para parar um # ref seja produzido quando o índice de atingir o fim da lista.
- Use cópia inteligente para preencher C3: C6.
- O valor de C1: C6 deve ser "1,2,4,5,7,8"
- Na coluna D, crie a nova lista única:
- Em D1, introduzir "= IF (C1 <= FILEIRA ($ A $ 6), INDEX ($ A $ 1: $ A $ 6, C1), "")". E, o "se" está sendo usado para parar o caso # REF quando o índice vai além do fim da lista.
- Use cópia inteligente para preencher D2: D6.
- Os valores de D1: D6 agora deve ser "negro", "azul", "verde", "vermelho", "", "".
thi Esperanças ajuda ....
Solução
Eu criei uma função em VBA para você, então você pode fazer isso agora de uma forma fácil.
Criar um módulo de código VBA (macro), como você pode ver na este tutorial .
- Pressione Alt + F11
- Clique para
Module
emInsert
. - Colar código.
- Se Excel diz que o formato de arquivo não é macro amigável do que guardá-lo como
Excel Macro-Enabled
emSave As
.
O código-fonte
Function listUnique(rng As Range) As Variant
Dim row As Range
Dim elements() As String
Dim elementSize As Integer
Dim newElement As Boolean
Dim i As Integer
Dim distance As Integer
Dim result As String
elementSize = 0
newElement = True
For Each row In rng.Rows
If row.Value <> "" Then
newElement = True
For i = 1 To elementSize Step 1
If elements(i - 1) = row.Value Then
newElement = False
End If
Next i
If newElement Then
elementSize = elementSize + 1
ReDim Preserve elements(elementSize - 1)
elements(elementSize - 1) = row.Value
End If
End If
Next
distance = Range(Application.Caller.Address).row - rng.row
If distance < elementSize Then
result = elements(distance)
listUnique = result
Else
listUnique = ""
End If
End Function
Uso
Basta digitar =listUnique(range)
a uma célula. O único parâmetro é range
que é um intervalo do Excel comum. Por exemplo:. A$1:A$28
ou H$8:H$30
Condições
- O
range
deve ser uma coluna. - A primeira célula onde você chamar a função deve estar na mesma linha onde os
range
começa.
Exemplo
caso regular
- Digite dados e função de chamada.
- Grow-lo.
- Voilà.
caso célula vazia
Ele funciona em colunas que têm células vazias em si. Também a função de saídas de nada (não erros) se dar corda em excesso as células (chamando a função) em locais onde deveria haver saída, como eu fiz isso em do exemplo anterior "2. Crescer" parte.
A rotunda maneira é carregar sua planilha Excel em uma planilha do Google, utilize a função do Google UNIQUE (intervalo) - que faz exatamente o que você quer -. E, em seguida, salve a planilha de volta Google para o formato Excel
Eu admito isso não é uma solução viável para usuários do Excel, mas esta abordagem é útil para quem quer a funcionalidade e é capaz de usar uma planilha do Google.
notado é uma questão muito antiga, mas as pessoas ainda parecem ter problemas para usar uma fórmula para extrair itens exclusivos. aqui está uma solução que retorna os valores selfs.
Vamos dizer que você tem "vermelho", "azul", "vermelho", "verde", "azul", "branco" na coluna A2: A7
, em seguida, colocar este em B2 como uma fórmula de matriz e copiar para baixo =IFERROR(INDEX(A$2:A$7;SMALL(IF(FREQUENCY(MATCH(A$2:A$7;A$2:A$7;0);ROW(INDIRECT("1:"&COUNTA(A$2:A$7))));ROW(INDIRECT("1:"&COUNTA(A$2:A$7)));"");ROW(A1)));"")
então deve ser algo como isto;
Mesmo para obter um valor único classificado, que pode ser feito usando a fórmula. Esta é uma opção que você pode usar:
=INDEX($A$2:$A$18,MATCH(SUM(COUNTIF($A$2:$A$18,C$1:C1)),COUNTIF($A$2:$A$18,"<" &$A$2:$A$18),0))
dados de intervalo: A2:A18
fórmula em C2
célula
Esta é uma fórmula de matriz
Você pode usar COUNTIF para obter o número de ocorrência do valor no intervalo. Então, se o valor está em A3, o intervalo é de A1: A6, em seguida, na utilização seguinte coluna um IF (EXACT (COUNTIF (A3: $ A $ 6, A3), 1), A3, ""). Para o A4, seria IF (EXACT (COUNTIF (A4: $ A $ 6, A3), 1), A4, "")
Isto lhe daria uma coluna onde todos os valores originais são sem qualquer duplicado
Assumindo Coluna A contém os valores que você deseja encontrar única instância única de, e tem uma linha de título que eu usei a seguinte fórmula. Se você queria que escala com um número imprevisível de linhas, você pode substituir A772 (onde terminou os meus dados) com = ADDRESS (COUNTA (A: A), 1).
= IF (COUNTIF (A5: $ A $ 772, A5) = 1, A5, "")
Isto irá exibir o valor único na instância ÚLTIMA de cada valor na coluna e não assume qualquer classificação. Ela tira proveito da falta de absolutos, essencialmente, ter uma diminuição da "janela deslizante" de dados para contar. Quando o countif na janela reduzida é igual a 1, então essa linha é a última instância desse valor na coluna.
solução de Drew Sherman é muito bom, mas a lista deve ser contíguo (ele sugere classificar manualmente, e isso não é aceitável para mim). A solução da Guitarthrower é meio lento se o número de itens é grande e não respeita a ordem da lista original: ele gera uma lista ordenada independentemente.
Eu queria que a ordem original dos itens (que foram ordenadas pela data em outra coluna), e, adicionalmente, eu queria excluir um item da lista final não só se fosse duplicado, mas também para uma variedade de outras razões .
A minha solução é uma melhoria em solução de Drew Sherman. Da mesma forma, esta solução utiliza 2 colunas para cálculos intermédios:
Coluna A:
A lista com duplicatas e talvez espaços em branco que você deseja filtrar. Vou posicioná-lo na A11:. Intervalo A1100 como exemplo, porque eu tinha dificuldade para mover a solução de Drew Sherman para situações em que não começar na primeira linha
Coluna B:
Esta fórmula vontade de saída 0 se o valor desta linha é válida (contém um valor não duplicado). Note que você pode adicionar quaisquer outras condições de exclusão que você quer, em primeiro IF, ou como outra IF externa.
=IF(ISBLANK(A11);1;IF(COUNTIF($A$11:A11;A11)=1;0;COUNTIF($A11:A$1100;A11)))
Use cópia inteligente para preencher a coluna.
Coluna C:
Na primeira linha, vamos encontrar a primeira linha válido:
=MATCH(0;B11:B1100;0)
A partir dessa posição, buscamos o próximo valor válido com a seguinte fórmula:
=C11+MATCH(0;OFFSET($B$11:$B$1100;C11;0);0)
Coloque-o na segunda linha e usar cópia inteligente para preencher o resto da coluna. Esta fórmula saída vontade # N / D de erro, quando não há mais itens únicos para ponto. Vamos aproveitar este na próxima coluna.
Coluna D:
Agora só temos de obter os valores apontados pela coluna C:
=IFERROR(INDEX($A$11:$A$1100; C11); "")
Use inteligente copiar para preencher a coluna. Esta é a lista única saída.
Você também pode fazê-lo desta forma.
Crie os seguintes intervalos nomeados:
nList = the list of original values
nRow = ROW(nList)-ROW(OFFSET(nList,0,0,1,1))+1
nUnique = IF(COUNTIF(OFFSET(nList,nRow,0),nList)=0,COUNTIF(nList, "<"&nList),"")
Com estes 3 intervalos nomeados que você pode gerar a lista ordenada de valores exclusivos com a fórmula abaixo. Vai ser classificados em ordem crescente.
IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-?),nUnique,0)),"")
Você vai precisar de substituir o número da linha da célula logo acima do primeiro elemento da sua lista ordenada exclusivo para o '?' caráter.
por exemplo. Se a sua lista ordenada única começa na célula B5, em seguida, a fórmula será:
IFERROR(INDEX(nList,MATCH(SMALL(nUnique,ROW()-4),nUnique,0)),"")
Estou surpreso esta solução não veio ainda. Eu acho que é um dos mais fáceis
Dê seus dados um título e colocá-lo em um intervalo dinâmico chamado (ou seja, se os dados estiverem em A
col)
=OFFSET($A$2,0,0,COUNTA($A:$A),1)
E, em seguida, criar uma tabela dinâmica, tornando a fonte de seu intervalo nomeado.
Basta colocar o título para a seção de linhas e você terá os valores exclusivos, classificar como quiser com o recurso embutido.
Eu tenho colado o que eu uso no meu arquivo excel abaixo. A pega valores únicos de L11:L300
gama e preenchê-los a partir de coluna em V, V11 em diante. Neste caso eu tenho esta fórmula em v11 e arraste-a para baixo para obter todos os valores exclusivos.
=INDEX(L$11:L$300,MATCH(0,COUNTIF(V$10:V10,L$11:L$300),0))
ou
=INDEX(L$11:L$300,MATCH(,COUNTIF(V$10:V10,L$11:L$300),))
esta é uma fórmula de matriz
Eu corri para o mesmo problema recentemente e finalmente descobri-lo.
Usando sua lista, aqui é uma pasta do meu Excel com a fórmula.
Eu recomendo escrever o em algum lugar fórmula no meio da lista, como, por exemplo, em C6
célula do meu exemplo e, em seguida, copiá-lo e colá-lo para cima e para baixo sua coluna, a fórmula deve ajustar automaticamente, sem necessidade de redigitar isto.
A única célula que tem uma fórmula diferente é exclusivamente na primeira fileira.
Usando sua lista ( "vermelho", "azul", "vermelho", "verde", "azul", "branco"); aqui está o resultado: ( Eu não tenho um nível alto o suficiente para deixar uma imagem de forma espero que esta versão txt faz sentido )
- [Coluna A: Lista Original]
- [Coluna B: Unique Lista de resultados]
-
[Coluna C: Unique Lista Formula]
- vermelho, vermelho,
=A3
- azul, azul,
=IF(ISERROR(MATCH(A4,A$3:A3,0)),A4,"")
- vermelho,,
=IF(ISERROR(MATCH(A5,A$3:A4,0)),A5,"")
- verde, verde,
=IF(ISERROR(MATCH(A6,A$3:A5,0)),A6,"")
- azul,,
=IF(ISERROR(MATCH(A7,A$3:A6,0)),A7,"")
- preto, preto,
=IF(ISERROR(MATCH(A8,A$3:A7,0)),A8,"")
- vermelho, vermelho,
Isso só funciona se os valores estão em ordem ou seja todos os "vermelhos" estão juntos e todos os "azuis" estão juntos etc. assumir que os seus dados estão na coluna A partir de A2 - (não começar da linha 1) No tipo B2 em 1 No tipo b3 = se (A2 = A3, B2, B2 + 1) Arraste para baixo a fórmula até o fim de seus dados Todos os "Red" será 1, todos "azul" será de 2 all "verde" será de 3 etc.
C2 tipo em 1, 2, 3 etc. indo para baixo na coluna Em D2 = OFFSET ($ A $ 1, FÓSFORO (c2, $ B $ 2: $ B $ x, 0), 0) - em que x é a última célula Arraste para baixo, apenas os valores exclusivos serão exibidos. - colocar em algum verificação de erros
Para uma solução que funciona para valores em várias linhas e colunas, encontrei a seguinte fórmula muito útil, de http://www.get-digital-help.com/2009/03/16/unique-values-from-multiple -columns utilizando-matriz de fórmulas / Oscar pelo get-digital.help.com vai ainda através dele passo-a-passo e com um exemplo visualizado.
1) Dê o intervalo de valores a etiqueta tbl_text
2) Aplicar a seguinte fórmula de matriz com CTRL + SHIFT + ENTER, a célula B13 neste caso. Mudança $ B $ 12:. B12 para se referir à célula acima da célula que você entra esta fórmula em
=INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), MATCH(0, COUNTIF($B$12:B12, INDEX(tbl_text, MIN(IF(COUNTIF($B$12:B12, tbl_text)=0, ROW(tbl_text)-MIN(ROW(tbl_text))+1)), , 1)), 0), 1)
3) copiar / arraste para baixo até chegar de N / A.
Se um coloca todos os dados nas mesmas colunas e usa a seguinte fórmula
Exemplo Fórmula: =IF(C105=C104,"Duplicate","Not a Duplicate")
Passos
- Classificar os dados
- Adicionar coluna para a fórmula
- Verifica se a célula é igual a célula acima
- Em seguida, filtro
Not a Duplicate
- Opcional: Copie os dados calculados pela coluna de fórmula e cole como valores somente (dessa forma, se você começar a apagar os dados, você não começar a receber erros
- NOTA / AVISO: Isso só funciona se você classificar os dados primeiros
Exemplo Fórmula: =IF(C105=C104,"Duplicate","Not a Duplicate")
Optimized VBScript Solução
Eu usei código totymedli de mas achei atolar ao usar intervalos grandes (como apontado por outros) para que eu otimizado seu código um pouco. Se alguém estiver interessado em obter valores originais usando o VBScript, mas encontra o código do totymedli lento quando a atualização, tente o seguinte:
Function listUnique(rng As Range) As Variant
Dim val As String
Dim elements() As String
Dim elementSize As Integer
Dim newElement As Boolean
Dim i As Integer
Dim distance As Integer
Dim allocationChunk As Integer
Dim uniqueSize As Integer
Dim r As Long
Dim lLastRow As Long
lLastRow = rng.End(xlDown).row
elementSize = 1
unqueSize = 0
distance = Range(Application.Caller.Address).row - rng.row
If distance <> 0 Then
If Cells(Range(Application.Caller.Address).row - 1, Range(Application.Caller.Address).Column).Value = "" Then
listUnique = ""
Exit Function
End If
End If
For r = 1 To lLastRow
val = rng.Cells(r)
If val <> "" Then
newElement = True
For i = 1 To elementSize - 1 Step 1
If elements(i - 1) = val Then
newElement = False
Exit For
End If
Next i
If newElement Then
uniqueSize = uniqueSize + 1
If uniqueSize >= elementSize Then
elementSize = elementSize * 2
ReDim Preserve elements(elementSize - 1)
End If
elements(uniqueSize - 1) = val
End If
End If
Next
If distance < uniqueSize Then
listUnique = elements(distance)
Else
listUnique = ""
End If
End Function
Selecione a coluna com valores duplicados em seguida, vá para a guia dados, então Data Tools escolha Remove Duplicate seleccionar 1) "Continuar com a seleção atual" 2) Clique em Remover duplicado .... botão 3) Clique no botão "Select All" 4) Clique em OK
Agora você tem a lista de valor único.