Jak scalić dwie tabele w programie Excel, które mają identyczne kolumny?


11

W programie Excel mam arkusz kalkulacyjny, który pobiera dane z bazy danych SQL do tabeli, a następnie generuje raport na podstawie tych danych. Niestety dane w tej bazie danych SQL są niekompletne i chcę uwzględnić dodatkowe wiersze w zestawie wyników, które są wprowadzane ręcznie do arkusza kalkulacyjnego.

Tak bardzo, jak chciałbym, nie mogę po prostu ręcznie wstawić tych dodatkowych wierszy do tabeli, ponieważ zostaną one usunięte, gdy Excel pobierze nowe dane z bazy danych SQL. Zamiast tego rozważam utworzenie osobnej tabeli z tymi samymi nagłówkami kolumn na nowym arkuszu i wprowadzenie tam danych, a następnie utworzenie trzeciej tabeli na innym arkuszu, który w jakiś sposób łączy wiersze z tabeli pobierającej dane z SQL i tabela, w której ręcznie wprowadzam dane. Jak mogę to osiągnąć? (Lub na przemian, czy istnieje lepszy sposób na zrobienie tego, którego w jakiś sposób brakuje?)


Przykład:

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     |

Czy dla Ciebie jest ok, jeśli ręcznie dodane dane znajdują się poniżej danych SQL? A może muszą być posortowane według daty. Excel nie nadpisze wierszy znajdujących się bezpośrednio pod istniejącymi wierszami danych SQL. Ale jeśli oba typy danych muszą zostać posortowane, cała sprawa jest bardziej skomplikowana.
nixda

Cóż, wolałbym je posortować, ale nie jest to całkowicie konieczne. Ważne jest to, że jestem w stanie używać tabel przestawnych i innych narzędzi programu Excel do analizowania całego zestawu danych (w tym tabel ręcznie i automatycznie wypełnianych). Muszę też móc nadal automatycznie pobierać nowe dane z SQL.
Ajedi32

Czy takie zachowanie byłoby rozwiązaniem? Po pierwszym zapytaniu i po drugim zapytaniu . Oczywiście program Excel automatycznie zaktualizuje kod SQL po otwarciu skoroszytu.
nixda

Chyba zadziałałoby. Wolę mieć dane w jednej tabeli, aby móc filtrować, sortować itp., Ale jak powiedziałem wcześniej, nie jest to całkowicie konieczne.
Ajedi32,

może znajdziemy rozwiązanie twojego problemu z sortowaniem. Ale w pierwszym kroku po prostu zapytaj SQL po raz pierwszy w nowym skoroszycie. Następnie dodaj swoje ręczne wpisy bezpośrednio pod nimi. Teraz przetestuj za pomocą drugiego (i większego) zapytania. Nie zostaną nadpisane. To standardowe zachowanie. Nie ma nic specjalnego do roboty.
nixda

Odpowiedzi:


2

Oto czyste rozwiązanie Excel bez VBA. Działa przy użyciu funkcji INDEKS, aby obniżyć wiersze i kolumny kolumn danych SQL, aż wartości zostaną wyczerpane i wystąpi warunek błędu. Funkcja IFERROR wychwytuje błąd i wykorzystuje drugą funkcję INDEKS, aby obniżyć wiersze i kolumny kolumn ręcznie wprowadzonych danych, aż do wyczerpania tych wartości i pojawienia się błędu. Druga funkcja IFERROR wychwytuje błąd i zwraca myślnik („-”). (Dane SQL muszą zostać odświeżone za pomocą Wstążki, aby formuły mogły uzyskać poprawny wynik).

Utwórz dynamiczny nazwany zakres SQLDB dla danych SQL w Arkuszu 1, korzystając ze wzoru:

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

Utwórz drugi dynamiczny nazwany zakres EXCELRNG dla ręcznie wprowadzonych danych w arkuszu 2, korzystając ze wzoru:

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

Oba te nazwane zakresy zakładają, że nazwy zmiennych są wprowadzane w wierszu 1 każdego z dwóch arkuszy.

Wprowadź nazwy zmiennych w wierszu 1 arkusza 3 (zaczynając od komórki A1).

Wprowadź następującą formułę w komórce A2 arkusza3:

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

Skopiuj formułę do kolumn z nazwami zmiennych, a następnie w dół wierszy, aż wszystkie wyniki formuł staną się myślnikami („-”).

Następnym krokiem jest utworzenie tabeli przestawnej w innym arkuszu do analizy i organizacji.

Ponownie pierwszym krokiem byłoby utworzenie dynamicznego nazwanego zakresu, powiedzmy RESULTRNG, wstawienie następującej formuły w polu wejściowym Menedżera nazw dla nazwanego zakresu:

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

Następnie utwórz tabelę przestawną w nowym arkuszu, ustawiając RESULTRNG jako tabelę, którą chcesz analizować. Spowoduje to odfiltrowanie końcowych myślników z tabeli formuł w Arkuszu3.

Działa to, ponieważ formuła RESULTRNG zlicza całkowitą liczbę wierszy w Arkuszu 1 i Arkuszu 2 (z wyłączeniem nagłówka w Arkuszu 2) i całkowitą liczbę kolumn w Arkuszu 1 i ustawia swój zasięg na podstawie tych liczb, z wyłączeniem myślników w dowolnych końcowych wierszach ( lub kolumny) w tabeli z formułą Sheet3.


Gdybym to zrobił w ten sposób, czy połączony stół nie musiałby mieć ustalonego rozmiaru? A jeśli sprawi, że tabela będzie większa, niż powinna być, czy to mnie nie zepsuje, jeśli spróbuję stworzyć tabelę przestawną, która obsługuje dane z połączonej tabeli? (Ponieważ niektóre wartości w tabeli miałyby znaki „-”?) Czy istnieje sposób na obejście tych problemów?
Ajedi32,

(Przy okazji, ogólnie wolę rozwiązania w
formacie

Wymagałoby to ręcznej konserwacji, aby upewnić się, że formuły przechwytują wszystkie dane w dwóch tabelach. Aby uniknąć myślników, musisz skopiować formuły tylko tam, gdzie zwracają dane, a nie myślniki.
chuff

Czy byłoby możliwe utworzenie innego nazwanego zakresu, który zawiera tylko wiersze ze scalonej tabeli, które nie są puste (wypełnione znakami „-”)? W ten sposób mogłem po prostu ustawić tabele przestawne, aby uzyskać ich dane z tego zakresu i nie musiałbym się martwić o myślniki.
Ajedi32,

Rozszerzyłem swoją odpowiedź, aby wyjaśnić, w jaki sposób można utworzyć tabelę przestawną bez myślników. Próba umieszczenia tabeli „bez kreski” po prostu przeniosłaby problem kreski na inny arkusz, z # nie dotyczy w komórkach kreski, chyba że nowa tabela była ręcznie zmieniana ręcznie za każdym razem, gdy zmienia się liczba wierszy w źródłowych danych.
chuff

5

Znalazłem sposób na zrobienie tego. To rozwiązanie jest trochę trudne i wymaga, aby obie tabele miały własne oddzielne arkusze (bez żadnych innych elementów), ale poza tym robi prawie dokładnie to, czego chcę. (Wydaje się również, że istnieje tutaj duży potencjał do wykonywania bardziej złożonych operacji, takich jak przyłączenia.)

Przejdź do karty danych na wstążce, kliknij „Z innych źródeł” i „Z zapytania Microsoft”. Następnie kliknij Pliki Excel, wybierz plik, w którym obecnie pracujesz i kliknij OK. Następnie kliknij przycisk Anuluj, a kiedy pojawi się informacja, czy chcesz kontynuować edycję w Microsoft Query, kliknij „Tak”. Stąd możesz kliknąć przycisk SQL i napisać niestandardowe zapytanie SQL na dowolnym arkuszu w arkuszu kalkulacyjnym. W moim przypadku:

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

Uwaga: dla mnie ta metoda przestaje działać po zamknięciu pliku i ponownym otwarciu. W każdym razie zamieszczam go tutaj, na wypadek gdyby był to tylko problem z moim komputerem lub ktoś inny może go uruchomić.


1
Działa dobrze, łącząc dwa różne skoroszyty. Właśnie tego potrzebowałem. Dziękuję Ci!
DaVe

Ta metoda działa dla mnie bardzo dobrze. Wykonaj zapytanie, a następnie po prostu skopiuj dane i przeszłość do programu Excel. Należy jednak pamiętać, że spowoduje to usunięcie wszelkich zduplikowanych wierszy z Twoich danych. Mam nadzieję, że nie masz nic przeciwko, jeśli trochę zmienię tę odpowiedź.
Some_Guy 14.09.16

Dodając, że tak się naprawdę stało, prawie wykorzystałem to do scalenia wielu danych sprzedaży w 1 arkuszu kalkulacyjnym, zanim utworzyłem tabelę przestawną, aby uzyskać pewne sumy, i popełniłbym kilka błędów, w których ten sam wolumen produktu sprzedawanego wiele razy miałby został pominięty
Some_Guy

@Some_Guy Zamiast tego użyj UNION ALL.
Ajedi32

3

Jeśli jesteś zainteresowany rozwiązaniem VBA, udało mi się uzyskać następujące działania:

  • Ustaw dynamiczny nazwany zakres dla danych, które pobierasz z SQL Server. Otwórz Menedżera nazw, wprowadź nową nazwę (powiedz „SQLDB”) i skopiuj następującą formułę w polu wejściowym Odnosi się do. Zakładam, że twoje pobrane dane są w Arkuszu1:

    =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1))
    
  • Ustaw inny nazwany zakres dla zakresu, w którym wprowadzane są dane ręczne. Użyłem nazwy EXCELRNG i założyłem, że była w Arkuszu 2. Nazwany zakres rozpoczyna się w wierszu 2, aby wykluczyć wiersz nagłówka. Wzór tutaj jest identyczny z pierwszym, z wyjątkiem arkusza, do którego się odnosi:

    =OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))
    
  • Oto pierwszy zestaw ustawień, których użyłem do połączenia z tabelą SQL. Dostęp do okna dialogowego można uzyskać, wybierając Połączenia na karcie Dane na Wstążce. Wyłączenie odświeżania w tle powoduje, że makro VBA zatrzymuje się do czasu zakończenia odświeżania danych w arkuszu Excel. Odświeżenie połączenia po otwarciu arkusza roboczego może nie być potrzebne, ale chciałem się upewnić, że uwierzytelnienie zostanie wykonane przed uruchomieniem makra.

ustawienia połączenia

  • Oto drugi zestaw ustawień. Można je znaleźć w sekcji Właściwości karty Dane (gdy wybrana jest komórka w importowanej tabeli SQL). Chociaż wybrałem opcję „Wstaw całe wiersze dla nowych danych, usuń nieużywane komórki”, tak naprawdę nie miałem żadnych problemów z opcją „Wstaw komórki ...”.

właściwości połączenia

  • Wreszcie jest to kod VBA. Aby wstawić, wybierz Visual Basic na karcie Deweloper. Podświetl nazwę arkusza na liście po lewej stronie. Będzie on oznaczony jako „Projekt VBA (nazwa arkusza). Następnie wybierz Wstaw moduł na pasku menu u góry ekranu i wklej kod w nowym module. Pamiętaj, że umieściłem skonsolidowaną tabelę w arkuszu 3. Jak napisano, makro nie sortuje nowej tabeli, choć nie byłoby to trudne do dodania.

    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
    

To wygląda na całkiem solidne rozwiązanie. Mam jednak kilka pytań. Co wyzwala to makro? Po prostu automatycznie działa, gdy odświeżasz połączenia danych, czy musisz nacisnąć osobny przycisk, aby uruchomić go ręcznie? Po drugie, to działa z tabelami, prawda? (Nie tylko zakresy, które nie są sformatowane jako tabele). W takim przypadku sama tabela nie może obsłużyć sortowania? (Zamiast makra VBA wykonującego sortowanie, jak sugerowałeś?)
Ajedi32,

1
Na obecnym etapie makro należy uruchomić, wybierając makra z karty Deweloper, a następnie wybierając i uruchamiając makro. Dwie alternatywy: przypisz go do niestandardowego przycisku na wstążce i użyj go, aby go uruchomić; lub osadzić go jako kod makra w zdarzeniu Worksheet_Activate. Spowoduje to uruchomienie go za każdym razem, gdy wybierzesz arkusz konsolidacji. Będzie działać z tabelami, które mogą wykonywać sortowanie. Nie jestem jednak pewien, czy tabele automatycznie uciekają się po dodaniu danych.
chuff

3

Oto wersja rozwiązania „Pure Excel” @ chuff zaprojektowanego specjalnie do pracy z tabelami. (IE Dwa źródła danych, które chcesz scalić, to tabele).

Główną różnicą między tą metodą a tym, co napisano w jego odpowiedzi, jest to, że nie trzeba definiować nazwanych zakresów dla dwóch zestawów danych, które scalasz, ponieważ są to tabele i mają już swój własny nazwany zakres. Więc idź naprzód i nazwij swój pierwszy stół Table1i drugi stół Table2.

Teraz utwórz nową tabelę w lewym górnym rogu nowego arkusza i nadaj jej takie same nazwy kolumn, jak pozostałe dwie tabele. Następnie wprowadź następującą formułę w komórce A2 właśnie utworzonego arkusza:

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

Następnie skopiuj tę formułę we wszystkich kolumnach tabeli, a następnie w dół wierszy, aż wszystkie wyniki formuł staną się myślnikami („-”). Uwaga: Sortowanie tej nowej tabeli nic nie da, ponieważ zawartość każdej komórki jest w rzeczywistości identyczna (wszystkie zawierają tę samą formułę).

Jeśli kolumny w scalonej tabeli wyświetlają 0, kiedy powinny wyświetlać pustą komórkę, możesz owinąć formułę w tej kolumnie za pomocą funkcji zastępczej, jak poniżej:

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

Jeśli chcesz utworzyć tabelę przestawną, która wykorzystuje dane z tej nowej tabeli, musisz utworzyć nazwany zakres. Najpierw nazwij tabelę Table3. Teraz przejdź do karty formuł i kliknij „Zdefiniuj nazwę”. Nadaj referencji nazwę, wprowadź następujące równanie jej wartości („Odnosi się do”):

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

Następnie można użyć tego nazwanego odwołania jako zakresu dla tabeli przestawnej.


0

Jeśli chcesz otrzymać wynik jednorazowo, istnieje strona internetowa, która połączy dwie tabele: https://office-tools.online/table/merge/

Wklej tabele do strony internetowej i wybierz odpowiednie parametry. Oto zrzut ekranu z wbudowanego przykładu, który wskazuje, jak go używać:

wprowadź opis zdjęcia tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.