Quero fazer um Vlookup para nomes que tenham várias linhas para a mesma chave primária:
Deal ID (Primary Key) | Name
437 | Tom Jones
437 | Frank Thomas
437 | Mary Smith
O Vlookup retornará apenas o 1º Nome do registro (Tom Jones). O que eu gostaria que fosse assim: Tom Jones, Frank Thomas, Mary Smith, todos na mesma linha.
Responder1
Parece que você está tentando usar o Excel como um banco de dados relacional, no qual ele não é muito bom. Para completar, a menos que tenha havido uma mudança nos últimos anos (não tive o prazer de usar nada posterior ao Excel 2010), não há função de planilha para transformar um intervalo ou array em uma string delimitada. Você terá que criar uma função de planilha VBA que faça isso.
Você pode usar uma combinação de fórmula de matriz e VBA para fazer o que quiser. Antes de prosseguir, eu sugiro fortemente que você use um programa de banco de dados real se você faz coisas assim regularmente. Eu abusei do Excel para realizar tarefas simples semelhantes a bancos de dados relacionais no passado, mas apenas tarefas simples. Se eu tivesse que fazer algo mais complexo, teria sido extremamente doloroso.
Supondo que seu ID a ser pesquisado esteja na célula F1
e sua tabela seja chamada Table1
, você insere o seguinte como umfórmula de matriz(use control-shift-enter, em vez de enter). SimpleCat
é a sua função de planilha de concatenação VBA.
=SimpleCat(IF(Table1[Deal ID (Primary Key)]=$F$1, Table1[Name], ""))
Um SimpleCat
que funcionará para esta instância específica é o seguinte:
Function SimpleCat(Args() As Variant) As Variant
Dim a As Variant
SimpleCat = ""
For Each a In Args
If a <> "" Then SimpleCat = SimpleCat & a & ", "
Next
If Len(SimpleCat) > 0 Then SimpleCat = Left$(SimpleCat, Len(SimpleCat) - 2)
End Function
Deixo isso como um exercício para você expandir e SimpleCat
torná-lo mais geral, já que ter uma função de concatenação genérica mais completa é útil na caixa de ferramentas de qualquer pessoa.
Explicação:
Quando avaliada como uma fórmula de matriz, comparar uma coluna inteira da tabela com um único valor produzirá uma matriz de TRUE
s e FALSE
s. Usar an IF
construirá uma nova matriz, extraindo valores da posição correta da matriz que você está usando no lado valor se for verdadeiro de IF
e preenchendo a string vazia que você está usando no lado valor se falso de IF
. A SimpleCat
função coloca todos os valores não vazios neste novo array junto com vírgulas entre eles.
Responder2
Dois problemas. Primeiro, essa não é uma chave primária; segundo, não há nenhuma funcionalidade integrada no Excel que forneça o resultado que você procura.
Uma chave primária deve ser um identificador exclusivo vinculado a um único registro e que nunca, jamais se repete. É para isso que a maioria das funções de pesquisa do Excel foram projetadas para funcionar, e é por isso que elas param quando encontram uma correspondência - isso economiza recursos para não ter que procurar todo o intervalo sempre que uma correspondência já foi encontrada.
A única maneira que encontrei de fazer o tipo de consolidação que você está procurando aqui, reunindo vários valores em uma única string, seria usar uma macro ou uma função personalizada. Exatamente o código que você precisa dependerá do resultado exato que você procura e, infelizmente, está fora do escopo desta resposta.
Responder3
eu pegaria essa função...
Function ConcatRange(inputRange As Range, Optional delimiter As String) As String
Dim oneCell As Range
Dim usedRange As Range
Set usedRange = Application.Intersect(inputRange.Parent.usedRange, inputRange.Cells)
If Not (usedRange Is Nothing) Then
For Each oneCell In usedRange
If oneCell.Text <> vbNullString Then
ConcatRange = ConcatRange & delimiter & Trim(oneCell.Text)
End If
Next oneCell
ConcatRange = Mid(ConcatRange, Len(delimiter) + 1)
End If
End Function
e modifique-o para criar uma nova função que seria algo como:
Function ConcatIf(KeyRange as Range, KeyValue as Variant, DataColumnOffset As Integer)
onde ele percorreria cada célula dentro do KeyRange e, somente se seu valor fosse igual a KeyValue, concatenaria o valor deoneCell.Offset(0, DataColumnOffset)