¿Cómo combino dos tablas en Excel que tienen columnas idénticas?

11

En Excel, tengo una hoja de cálculo que extrae datos de una base de datos SQL en una tabla y luego genera un informe basado en esos datos. Desafortunadamente, los datos en esta base de datos SQL están incompletos y quiero incluir filas adicionales en el conjunto de resultados que se ingresan manualmente en la hoja de cálculo.

Por mucho que quisiera, no puedo insertar manualmente estas filas adicionales en la tabla porque se eliminarían cada vez que Excel extraiga nuevos datos de la Base de datos SQL. Entonces, en cambio, estoy considerando crear una tabla separada con los mismos encabezados de columna en una nueva hoja e ingresar los datos allí, y luego crear una tercera tabla en otra hoja que de alguna manera combine las filas de la tabla que extrae datos de SQL y tabla donde ingreso datos manualmente. ¿Cómo puedo lograr esto? (O, alternativamente, ¿hay una mejor manera de hacer esto que de alguna manera me estoy perdiendo?)


Ejemplo:

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
fuente
¿Está bien si sus datos agregados manualmente están debajo de sus datos SQL? ¿O tienen que estar ordenados por fecha? Excel no sobrescribirá las filas que están justo debajo de las filas de datos SQL existentes. Pero si ambos tipos de datos tienen que ordenarse, entonces todo es más complicado.
nixda
Bueno, preferiría que se clasifiquen, pero eso no es completamente necesario. Lo importante es que puedo usar tablas dinámicas y otras herramientas de Excel para analizar todo el conjunto de datos (incluidas las tablas pobladas de forma manual y automática). También necesito poder continuar obteniendo nuevos datos de SQL automáticamente.
Ajedi32
¿Sería este comportamiento una solución? Después de la primera consulta y después de la segunda consulta . Y, por supuesto, Excel actualizará automáticamente su SQL cuando abra el libro.
nixda
Eso funcionaría, supongo. Prefiero tener los datos en una sola tabla para poder filtrar, ordenar, etc., pero como dije antes, eso no es del todo necesario.
Ajedi32
quizás encontremos una solución para su problema de clasificación. Pero para el primer paso, solo consulta tu SQL por primera vez en un nuevo libro de trabajo. Después de eso, agregue sus entradas manuales justo debajo de ellas. Ahora pruébelo con una segunda (y mayor) consulta. No se sobrescribirán. Es un comportamiento estándar. No hay nada especial que hacer.
nixda

Respuestas:

2

Aquí hay una solución pura de Excel sin VBA. Funciona mediante el uso de una función ÍNDICE para reducir las filas y las columnas de los datos SQL hasta que se agoten los valores y se produzca una condición de error. Una función IFERROR detecta el error y utiliza una segunda función INDICE para reducir las filas y las columnas de los datos ingresados ​​manualmente, nuevamente hasta que esos valores se agoten y se produzca una condición de error. Una segunda función IFERROR detecta el error y devuelve un guión ("-"). (Los datos SQL se deben actualizar a través de la cinta de opciones para que las fórmulas produzcan un resultado correcto).

Cree un rango dinámico con nombre SQLDB para los datos SQL en la Hoja1 utilizando la fórmula:

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

Cree un segundo rango dinámico con nombre EXCELRNG para los datos ingresados ​​manualmente en Sheet2 usando la fórmula:

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

Ambos rangos con nombre suponen que los nombres de las variables se ingresan en la fila 1 de cada una de las dos hojas.

Ingrese los nombres de las variables en la fila 1 de la Hoja3 (comenzando en la celda A1).

Ingrese la siguiente fórmula en la celda A2 de Sheet3:

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

Copie la fórmula en las columnas de nombre de la variable y luego hacia abajo en las filas hasta que los resultados de las fórmulas sean todos guiones ("-").

Es posible, como siguiente paso, crear una tabla dinámica en otra hoja para su análisis y organización.

Nuevamente, el primer paso sería crear un rango con nombre dinámico, por ejemplo, RESULTRNG, insertando la siguiente fórmula en el cuadro de entrada del Administrador de nombres para el rango con nombre:

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

Luego cree una tabla dinámica en una nueva hoja, estableciendo RESULTRNG como la tabla que desea analizar. Esto filtrará los guiones finales de la tabla de fórmulas en Sheet3.

Esto funciona porque la fórmula RESULTRNG cuenta el número total de filas en Sheet1 y Sheet2 (excluyendo el encabezado en Sheet2) y el número total de columnas en Sheet1, y establece su extensión en función de esos recuentos, excluyendo cualquier guión en las filas finales ( o columnas) en la tabla de fórmulas de Sheet3.

bagazo
fuente
Si lo hiciera de esta manera, ¿no tendría la tabla combinada un tamaño fijo? Y si hiciera la tabla más grande de lo que debería ser, ¿no me molestaría si intentara hacer una tabla dinámica que maneje los datos de la tabla combinada? (¿Porque algunos de los valores en la tabla serían caracteres '-'?) ¿O hay alguna forma de evitar estos problemas?
Ajedi32
(Por cierto, generalmente prefiero soluciones de Excel puras como esta porque no requieren que el usuario habilite macros antes de comenzar a trabajar).
Ajedi32
Requeriría un poco de mantenimiento manual para asegurarse de que las fórmulas capturaran todos los datos en las dos tablas. Para evitar los guiones, deberá copiar las fórmulas solo donde devolvieron los datos, no guiones.
chuff
¿Sería posible crear otro rango con nombre que incluya solo las filas de la tabla fusionada que no estén en blanco (llenas de caracteres '-')? De esa manera, podría configurar las tablas dinámicas para obtener sus datos de ese rango y no tendría que preocuparme por los guiones.
Ajedi32
He ampliado mi respuesta para explicar cómo puedes crear una tabla dinámica excluyendo los guiones. Intentar poner una tabla "sin guión" simplemente transferiría el problema del guión a otra hoja, con # N / A en las celdas del guión, a menos que la nueva tabla se dimensione a mano cada vez que cambie el número de filas en los datos de origen.
chuff
5

Encontré una manera de hacerlo. Esta solución es un poco complicada y requiere que ambas tablas tengan sus propias hojas separadas (sin nada más en ellas), pero aparte de eso, hace casi exactamente lo que quiero. (También parece haber mucho potencial aquí para realizar operaciones más complejas, como las uniones).

Vaya a la pestaña de datos en la cinta, haga clic en "De otras fuentes" y "De Microsoft Query". Luego haga clic en Archivos de Excel, seleccione el archivo en el que está trabajando actualmente y haga clic en Aceptar. Luego, presione cancelar y cuando se le promocione si desea continuar editando en Microsoft Query, presione "Sí". Desde aquí, puede hacer clic en el botón SQL y escribir una consulta SQL personalizada en cualquier hoja de la hoja de cálculo. En mi caso:

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

Nota: Para mí, este método deja de funcionar después de cerrar el archivo y volver a abrirlo. Lo publico aquí de todos modos, en caso de que sea solo un problema con mi computadora o alguien más pueda hacerlo funcionar.

Ajedi32
fuente
1
Funciona bien conectando dos libros de trabajo diferentes. Eso fue exactamente lo que necesito. ¡Gracias!
desde el
Este método me funciona muy bien. Ejecute la consulta, luego simplemente copie los datos y péguelos en Excel. Sin embargo, es importante tener en cuenta que eliminará las filas duplicadas de sus datos, espero que no le importe si edito un poco esta respuesta.
Some_Guy
Sumando que esto realmente me sucedió, casi lo usé para fusionar un montón de datos de ventas en 1 hoja de cálculo antes de hacer una tabla giratoria para obtener algunos totales, y habría cometido algunos errores donde el mismo volumen de un producto vendido varias veces habría ha sido extrañado
Some_Guy
@Some_Guy Solo usa UNION ALL en su lugar.
Ajedi32
3

Si está interesado en una solución VBA, pude hacer que funcione lo siguiente:

  • Establezca un rango dinámico con nombre para los datos que está extrayendo de SQL Server. Abra el Administrador de nombres, ingrese un nuevo nombre (por ejemplo, "SQLDB") y copie la siguiente fórmula en el cuadro de entrada Se refiere a. Supuse que sus datos extraídos están en la Hoja 1:

    =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1))
    
  • Establezca otro rango con nombre para el rango en el que se ingresan los datos manuales. Usé el nombre EXCELRNG y asumí que estaba en Sheet2. El rango con nombre comienza en la fila 2 para excluir una fila de encabezado. La fórmula aquí es idéntica a la primera, excepto por la hoja a la que se refiere:

    =OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))
    
  • Aquí está el primer conjunto de configuraciones que utilicé para la conexión a la tabla SQL. Se accede al cuadro de diálogo seleccionando Conexiones en la pestaña Datos en la cinta de opciones. Deshabilitar la actualización en segundo plano garantiza que la macro VBA se pause hasta que se complete una actualización de los datos en la hoja de Excel. Es posible que no sea necesario actualizar la conexión cuando se abre la hoja de trabajo, pero quería asegurarme de que cualquier autenticación se realizaría antes de ejecutar la macro.

ajustes de conexión

  • Aquí está el segundo conjunto de configuraciones. Estos se encuentran en la sección Propiedades de la pestaña Datos (mientras se selecciona una celda en la tabla SQL importada). Aunque elegí la opción "Insertar filas completas para nuevos datos, eliminar celdas no utilizadas", en realidad no tuve ningún problema con la opción "Insertar celdas ...".

propiedades de conexión

  • Finalmente, este es el código VBA. Para insertarlo, elija Visual Basic en la pestaña Desarrollador. Resalte el nombre de la hoja de trabajo en la lista a la izquierda. Se hará referencia como "Proyecto VBA (nombre de la hoja). Luego elija Insertar módulo en la barra de menú en la parte superior de la pantalla y pegue el código en el nuevo módulo. Tenga en cuenta que puse la tabla consolidada en la Hoja 3. Como está escrito, la macro no ordena la nueva tabla, aunque eso no sería difícil de agregar.

    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
    
bagazo
fuente
Esto parece una solución bastante sólida. Sin embargo, tengo un par de preguntas. ¿Qué desencadena esta macro? Simplemente se ejecuta automáticamente cuando actualiza las conexiones de datos, ¿o tiene que presionar un botón separado para ejecutarlo manualmente? En segundo lugar, esto funciona con tablas ¿verdad? (No solo rangos que no están formateados como tablas) Si ese es el caso, ¿no puede la tabla misma manejar la clasificación? (En lugar de la macro VBA haciendo la clasificación, como sugirió?)
Ajedi32
1
Tal como está, ejecutaría la macro seleccionando Macros en la pestaña Desarrollador y luego seleccionando y ejecutando la macro. Dos alternativas: asígnelo a un botón personalizado en la cinta de opciones y úselo para ejecutarlo; o incrustarlo como código de macro en un evento Worksheet_Activate. Esto lo ejecutaría cada vez que seleccionara la hoja de consolidación. Funcionará con tablas, que pueden hacer la clasificación. Sin embargo, no estoy seguro de si las tablas recurren automáticamente cuando se agregan datos.
chuff
3

Aquí hay una versión de la solución "Pure Excel" de @ chuff diseñada específicamente para trabajar con tablas. (IE Las dos fuentes de datos que desea fusionar son tablas).

La principal diferencia entre este método y el único contenido publicado en su respuesta es que no necesita definir rangos con nombre para los dos conjuntos de datos que está fusionando, ya que son tablas y ya tienen su propio rango con nombre. Así que adelante, nombra tu primera mesa Table1y tu segunda mesa Table2.

Ahora, cree una nueva tabla en la esquina superior izquierda de una nueva hoja y asígnele los mismos nombres de columna que las otras dos tablas. Luego ingrese la siguiente fórmula en la celda A2 de la hoja que acaba de crear:

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

Luego, copie esta fórmula en todas las columnas de la tabla y luego hacia abajo en las filas hasta que los resultados de las fórmulas sean todos guiones ("-"). Nota: Ordenar esta nueva tabla no hará nada, ya que el contenido de cada celda es realmente idéntico (todos contienen la misma fórmula).

Si las columnas de la tabla combinada muestran 0 cuando deberían mostrar una celda en blanco, puede ajustar la fórmula en esa columna con la función de sustitución, como esta:

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

Si desea crear una tabla dinámica que utilice datos de esta nueva tabla, deberá crear un rango con nombre. Primero, nombra la mesa Table3. Ahora, vaya a la pestaña de fórmulas y haga clic en "Definir nombre". Dé un nombre a la referencia, ingrese la siguiente ecuación para su valor ("Se refiere a"):

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

Luego puede usar esta referencia con nombre como el rango para su tabla dinámica.

Ajedi32
fuente
0

Si solo desea obtener un resultado por única vez, hay un sitio web que combinará dos tablas para usted: https://office-tools.online/table/merge/

Pega las tablas en la página web y selecciona los parámetros relevantes. Aquí hay una captura de pantalla del ejemplo incorporado que indica cómo usarlo:

ingrese la descripción de la imagen aquí

Hvg Hng
fuente