Como mesclar duas tabelas no Excel que possuem colunas idênticas?

11

No Excel, tenho uma planilha que extrai dados de um banco de dados SQL para uma tabela e gera um relatório com base nesses dados. Infelizmente, os dados desse banco de dados SQL estão incompletos e quero incluir linhas adicionais no conjunto de resultados que são inseridas manualmente na planilha.

Tanto quanto eu gostaria, não posso apenas inserir manualmente essas linhas extras na tabela, pois elas seriam excluídas sempre que o Excel extrair novos dados do Banco de Dados SQL. Então, em vez disso, estou pensando em criar uma tabela separada com os mesmos títulos de coluna em uma nova planilha e inserir os dados nela e, em seguida, criar uma terceira tabela em outra planilha que de alguma forma combine as linhas da tabela que extrai dados do SQL e do tabela onde insiro dados manualmente. Como posso fazer isso? (Ou, alternativamente, existe uma maneira melhor de fazer isso que de alguma forma eu sinto falta?)


Exemplo:

Table 1 (From Database):

  | Person | Week Of | Task | Hours |
  | Bob    | 1/6/13  | Foo  | 12    |
  | Mary   | 1/6/13  | Foo  | 7     |
  | Mary   | 1/6/13  | Bar  | 5     |
  | John   | 1/6/13  | Foo  | 5     |
  | John   | 1/13/13 | Foo  | 13    |

-

Table 2 (Entered Manually): 
  | Person | Week Of | Task | Hours |
  | Bob    | 1/6/13  | Baz  | 3     |
  | Mary   | 1/6/13  | Baz  | 2     |
  | John   | 1/13/13 | Baz  | 5     |

-

Result:
  | Person | Week Of | Task | Hours |
  | Bob    | 1/6/13  | Foo  | 12    |
  | Mary   | 1/6/13  | Foo  | 7     |
  | Mary   | 1/6/13  | Bar  | 5     |
  | John   | 1/6/13  | Foo  | 5     |
  | John   | 1/13/13 | Foo  | 13    |
  | Bob    | 1/6/13  | Baz  | 3     |
  | Mary   | 1/6/13  | Baz  | 2     |
  | John   | 1/13/13 | Baz  | 5     |
Ajedi32
fonte
Tudo bem se os dados adicionados manualmente estiverem abaixo dos dados do SQL? Ou eles precisam ser classificados por data. O Excel não substituirá as linhas logo abaixo das linhas de dados SQL existentes. Mas se os dois tipos de dados tiverem que ser classificados, tudo será mais complicado.
Nixda
Bem, eu preferiria que eles fossem classificados, mas isso não é completamente necessário. O importante é que eu posso usar tabelas dinâmicas e outras ferramentas do Excel para analisar todo o conjunto de dados (incluindo as tabelas preenchidas manualmente e automaticamente). Também preciso continuar recebendo novos dados do SQL automaticamente.
Ajedi32
Esse comportamento seria uma solução? Após a primeira consulta e após a segunda consulta . E é claro que o Excel atualizará automaticamente seu SQL quando você abrir a pasta de trabalho.
Nixda
Isso funcionaria, eu acho. Prefiro ter os dados em uma única tabela para poder filtrar, classificar etc., mas, como eu disse antes, isso não é totalmente necessário.
Ajedi32
talvez encontremos uma solução para o seu problema de classificação. Mas, para a primeira etapa, basta consultar seu SQL pela primeira vez em uma nova pasta de trabalho. Depois disso, adicione suas entradas manuais logo abaixo delas. Agora teste-o com uma segunda (e maior) consulta. Eles não serão substituídos. É um comportamento padrão. Não há nada de especial para fazer.
Nixda

Respostas:

2

Aqui está uma solução pura do Excel sem VBA. Ele funciona usando uma função INDEX para descer as linhas e pelas colunas dos dados SQL até que os valores se esgotem e uma condição de erro resulte. Uma função IFERROR captura o erro e usa uma segunda função INDEX para descer as linhas e pelas colunas dos dados inseridos manualmente, novamente até que esses valores se esgotem e uma condição de erro resulte. Uma segunda função IFERROR captura o erro e retorna um traço ("-"). (Os dados SQL devem ser atualizados por meio da faixa de opções para que as fórmulas produzam um resultado correto.)

Crie um SQLDB de intervalo nomeado dinâmico para os dados SQL na Planilha1 usando a fórmula:

=OFFSET(Sheet1!$A$2,0,0,COUNTA(Sheet1!$A:$A)-1,COUNTA(Sheet1!$1:$1))

Crie um segundo intervalo nomeado dinâmico EXCELRNG para os dados inseridos manualmente na Planilha2 usando a fórmula:

=OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))

Ambos os intervalos nomeados assumem que os nomes das variáveis ​​são inseridos na linha 1 de cada uma das duas planilhas.

Digite os nomes das variáveis ​​na linha 1 da Planilha3 (começando na célula A1).

Digite a seguinte fórmula Na célula A2 da Sheet3:

=IFERROR(INDEX(SQLDB,ROWS(A$2:A2),COLUMN(A2)),IFERROR(INDEX(EXCELRNG,ROWS(A$2:A2)-ROWS(SQLDB),COLUMN(A2)),"-"))

Copie a fórmula nas colunas do nome da variável e desça as linhas até que os resultados das fórmulas sejam todos traços ("-").

É possível, como próximo passo, criar uma Tabela Dinâmica em outra planilha para análise e organização.

Novamente, a primeira etapa seria criar um intervalo nomeado dinâmico, por exemplo, RESULTRNG, inserindo a seguinte fórmula na caixa de entrada do Gerenciador de Nomes para o intervalo nomeado:

=OFFSET(Sheet3!$A$1,0,0,COUNTA(Sheet1!$A:$A)+COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet1!$1:$1))

Em seguida, crie uma tabela dinâmica em uma nova planilha, definindo RESULTRNG como a tabela que você deseja analisar. Isso filtrará todos os traços à direita da tabela de fórmulas na Planilha3.

Isso funciona porque a fórmula RESULTRNG conta o número total de linhas na Planilha1 e na Planilha2 (excluindo o cabeçalho na Planilha2) e o número total de colunas na Planilha1 e define sua extensão com base nessas contagens, excluindo traços nas linhas finais ( ou colunas) na tabela de fórmulas Sheet3.

chuff
fonte
Se eu fiz dessa maneira, a tabela combinada não teria que ter um tamanho fixo? E se a tabela fosse maior do que precisava, isso não me atrapalharia se eu tentasse criar uma Tabela Dinâmica que lida com dados da tabela combinada? (Como alguns dos valores da tabela conteriam caracteres '-'?) Ou existe uma maneira de contornar esses problemas?
precisa saber é o seguinte
(Btw, eu geralmente preferem soluções Excel puros como este porque eles não exigem que o usuário ativar macros antes de começar a trabalhar.)
Ajedi32
Seria necessária alguma manutenção manual para garantir que as fórmulas capturassem todos os dados nas duas tabelas. Para evitar os traços, você precisaria copiar as fórmulas apenas para onde eles retornaram dados, não traços.
chuff
Seria possível criar outro intervalo nomeado que inclua apenas as linhas da tabela mesclada que não estejam em branco (preenchidas com caracteres '-')? Dessa forma, eu poderia simplesmente definir as tabelas dinâmicas para obter os dados desse intervalo e não precisaria me preocupar com os traços.
precisa saber é o seguinte
Expandi minha resposta para explicar como você pode criar uma tabela dinâmica excluindo os traços. Tentar colocar uma tabela "sem traços" apenas transfere o problema do traço para outra planilha, com # N / D nas células do traço, a menos que a nova tabela seja dimensionada manualmente sempre que o número de linhas nos dados de origem for alterado.
chuff
5

Eu encontrei uma maneira de fazer isso. Essa solução é um pouco complicada e exige que as duas tabelas tenham suas próprias folhas separadas (sem mais nada), mas, além disso, faz quase exatamente o que eu quero. (Também parece haver muito potencial aqui para operações mais complexas, como junções.)

Vá para a guia dados na faixa de opções, clique em "De outras fontes" e "Em Microsoft Query". Em seguida, clique em Arquivos do Excel, selecione o arquivo em que você está trabalhando no momento e clique em OK. Em seguida, pressione cancelar e, quando promovido, se você deseja continuar editando no Microsoft Query, pressione "Sim". A partir daqui, você pode clicar no botão SQL e escrever uma Consulta SQL personalizada em qualquer planilha da planilha. No meu caso:

SELECT *
FROM `'Sheet1$'` `'Sheet1$'`
UNION ALL
SELECT *
FROM `'Sheet2$'` `'Sheet2$'`

Nota: Para mim, esse método para de funcionar depois que eu fecho o arquivo e o abro novamente. Estou postando aqui de qualquer maneira, no caso de ser apenas um problema no meu computador ou alguém pode fazê-lo funcionar.

Ajedi32
fonte
1
Ele funciona bem ao conectar duas pastas de trabalho diferentes. Era exatamente disso que eu precisava. Obrigado!
daVe 26/01
Este método funciona muito bem para mim. Execute a consulta e simplesmente copie os dados e o passado para o Excel. No entanto, é importante observar que ele removerá todas as linhas duplicadas dos seus dados. Espero que você não se importe se eu editar essa resposta um pouco.
Some_Guy
Além disso, porque isso realmente aconteceu comigo, quase usei isso para mesclar um monte de dados de vendas em uma planilha antes de fazer uma tabela dinâmica para obter alguns totais, e eu teria cometido alguns erros em que o mesmo volume de um produto vendido várias vezes teria foi esquecido.
Some_Guy
@Some_Guy Basta usar UNION ALL.
precisa saber é o seguinte
3

Se você estiver interessado em uma solução VBA, consegui que o seguinte funcionasse:

  • Defina um intervalo nomeado dinâmico para os dados que você está obtendo do SQL Server. Abra o Gerenciador de nomes, insira um novo nome (por exemplo, "SQLDB") e copie a seguinte fórmula na caixa de entrada Referências a. Eu assumi que seus dados extraídos estão na Planilha1:

    =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1))
    
  • Defina outro intervalo nomeado para o intervalo no qual os dados manuais são inseridos. Eu usei o nome EXCELRNG e assumi que estava na Planilha2. O intervalo nomeado inicia na linha 2 para excluir uma linha de cabeçalho. A fórmula aqui é idêntica à primeira, exceto na planilha a que se refere:

    =OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))
    
  • Aqui está o primeiro conjunto de configurações que usei para a conexão com a tabela SQL. A caixa de diálogo é acessada selecionando Conexões na guia Dados na faixa de opções. A desativação da atualização em segundo plano garante que a macro do VBA seja pausada até que uma atualização dos dados na planilha do Excel seja concluída. A atualização da conexão quando a planilha é aberta pode não ser necessária, mas eu queria garantir que qualquer autenticação fosse feita antes da execução da macro.

configurações de conexão

  • Aqui está o segundo conjunto de configurações. Eles são encontrados na seção Propriedades da guia Dados (enquanto uma célula na tabela SQL importada está selecionada). Embora eu tenha escolhido a opção "Inserir linhas inteiras para novos dados, excluir células não utilizadas", na verdade não tive nenhum problema com a opção "Inserir células ...".

propriedades de conexão

  • Finalmente, este é o código VBA. Para inseri-lo, escolha Visual Basic na guia Desenvolvedor. Destaque o nome da planilha na lista à esquerda. Ele será referenciado como "Projeto VBA (nome da planilha). Em seguida, escolha Inserir módulo na barra de menus na parte superior da tela e cole o código no novo módulo. Observe que eu coloquei a tabela consolidada na Planilha3. Como está escrito, a macro não classifica a nova tabela, embora isso não seja difícil de adicionar.

    Sub StackTables()
    
       Dim Rng1 As Range, Rng2 As Range
    
       Set Rng1 = ThisWorkbook.Names("SQLDB").RefersToRange
       Set Rng2 = ThisWorkbook.Names("EXCELRNG").RefersToRange
    
       ' refresh the SQL table
       ThisWorkbook.Connections(1).Refresh
    
       ' clear the consolidated table range  
       Sheet3.Cells.ClearContents
    
       ' copy the SQL data into the consolidation range
       Rng1.Copy
       Sheet3.Range("A1").PasteSpecial xlPasteValues
    
       'copy the manually entered data into the consolidate range
       Rng2.Copy
       Sheet3.Range("A1").Offset(Rng1.Rows.Count, 0).PasteSpecial xlPasteValues
       Application.CutCopyMode = False
    
       Sheets("Sheet3").Activate
       ActiveSheet.Range("A1").Select
    
    End Sub
    
chuff
fonte
Parece uma solução bastante sólida. Eu tenho algumas perguntas, no entanto. O que aciona essa macro? Ele é executado automaticamente quando você atualiza as conexões de dados ou precisa pressionar um botão separado para executá-lo manualmente? Em segundo lugar, isso funciona com tabelas, certo? (Não apenas intervalos que não são formatados como tabelas) Se for esse o caso, a própria tabela não pode lidar com a classificação? (Em vez da macro VBA fazendo a triagem, como você sugeriu?)
Ajedi32
1
Tal como está, você executaria a macro selecionando Macros na guia Desenvolvedor e, em seguida, selecionando e executando a macro. Duas alternativas: atribua-o a um botão personalizado na faixa de opções e use-o para executá-lo; ou incorpore-o como código de macro em um evento Worksheet_Activate. Isso o executaria sempre que você selecionasse a folha de consolidação. Funcionará com tabelas, que podem fazer a classificação. No entanto, não tenho certeza se as tabelas recorrem automaticamente quando os dados são adicionados.
chuff
3

Aqui está uma versão da solução "Pure Excel" do @ chuff, projetada especificamente para trabalhar com tabelas. (IE As duas fontes de dados que você deseja mesclar são tabelas.)

A principal diferença entre esse método e o chuff publicado em sua resposta é que você não precisa definir intervalos nomeados para os dois conjuntos de dados que você está mesclando, pois são tabelas e já possuem seu próprio intervalo nomeado. Então vá em frente e nomeie sua primeira mesa Table1e sua segunda mesa Table2.

Agora, crie uma nova tabela no canto superior esquerdo de uma nova planilha e atribua os mesmos nomes de coluna que as outras duas tabelas. Em seguida, insira a seguinte fórmula na célula A2 da planilha que você acabou de criar:

=IFERROR(INDEX(Table1,ROWS(A$2:A2),COLUMN(A2)), IFERROR(INDEX(Table2,ROWS(A$2:A2)-ROWS(Table1),COLUMN(A2)), "-"))

Em seguida, copie esta fórmula em todas as colunas da tabela e, em seguida, desça as linhas até que os resultados das fórmulas sejam todos traços ("-"). Nota: A classificação desta nova tabela não fará nada, pois o conteúdo de cada célula é realmente idêntico (todos eles contêm a mesma fórmula).

Se as colunas na tabela mesclada exibirem 0 quando deveriam exibir uma célula em branco, você poderá quebrar a fórmula nessa coluna com a função substituta, da seguinte maneira:

=SUBSTITUTE(<old expression here>, 0, "")

Se você deseja criar uma tabela dinâmica que usa dados dessa nova tabela, precisará criar um intervalo nomeado. Primeiro, nomeie a tabela Table3. Agora, vá para a guia fórmulas e clique em "Definir nome". Dê um nome à referência, digite a seguinte equação para seu valor ("Refere-se a"):

=OFFSET(Table3[#All],0,0,ROWS(Table1)+ROWS(Table2)+1)

Em seguida, você pode usar essa referência nomeada como o intervalo para sua tabela dinâmica.

Ajedi32
fonte
0

Se você deseja apenas um resultado único, há um site que mesclará duas tabelas para você: https://office-tools.online/table/merge/

Você cola as tabelas na página da web e seleciona os parâmetros relevantes. Aqui está uma captura de tela do exemplo interno que indica como usá-lo:

insira a descrição da imagem aqui

Hvg Hng
fonte