Как объединить две таблицы в Excel с одинаковыми столбцами?

11

В Excel у меня есть электронная таблица, которая извлекает данные из базы данных SQL в таблицу, а затем генерирует отчет на основе этих данных. К сожалению, данные в этой базе данных SQL неполны, и я хочу включить в набор результатов дополнительные строки, которые вводятся вручную в электронную таблицу.

Как бы мне ни хотелось, я не могу просто вставить эти дополнительные строки в таблицу вручную, потому что они будут удалены, когда Excel извлекает новые данные из базы данных SQL. Поэтому вместо этого я рассматриваю создание отдельной таблицы с такими же заголовками столбцов на новом листе и ввод данных в нее, а затем создание третьей таблицы на другом листе, которая каким-то образом объединяет строки из таблицы, которая извлекает данные из SQL и таблица, куда я ввожу данные вручную. Как я могу сделать это? (Или поочередно, есть ли лучший способ сделать это, что я как-то скучаю?)


Пример:

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
источник
Это нормально для вас, если ваши вручную добавленные данные ниже ваших данных SQL? Или они должны быть отсортированы по дате. Excel не будет перезаписывать строки, которые находятся прямо под существующими строками данных SQL. Но если оба типа данных должны быть отсортированы, то все сложнее.
августа
Ну, я бы предпочел, чтобы они были отсортированы, но в этом нет необходимости. Важно то, что я могу использовать сводные таблицы и другие инструменты Excel для анализа всего набора данных (включая таблицы, заполненные вручную и автоматически). Мне также нужно иметь возможность автоматически получать новые данные из SQL.
Ajedi32
Будет ли это поведение решением проблемы? После первого запроса и после второго запроса . И, конечно, Excel автоматически обновит ваш SQL при открытии книги.
августа
Это будет работать, я думаю. Я бы предпочел хранить данные в одной таблице, чтобы я мог фильтровать, сортировать и т. Д., Но, как я уже говорил, в этом нет необходимости
Ajedi32
может быть, мы найдем решение вашей проблемы с сортировкой. Но для первого шага просто запросите ваш SQL впервые в новой книге. После этого добавьте свои ручные записи прямо под ними. Теперь проверьте это с помощью второго (и большего) запроса. Они не будут перезаписаны. Это стандартное поведение. Там нет ничего особенного, чтобы сделать.
августа

Ответы:

2

Вот чистое решение Excel без VBA. Он работает с помощью функции INDEX для перехода по строкам и по столбцам данных SQL до тех пор, пока значения не будут исчерпаны и не возникнет ошибка. Функция IFERROR улавливает ошибку и использует вторую функцию INDEX, чтобы шагать вниз по строкам и по столбцам введенных вручную данных, снова, пока эти значения не будут исчерпаны и не возникнет условие ошибки. Вторая функция IFERROR отлавливает ошибку и возвращает тире ("-"). (Для получения правильных результатов данные SQL должны обновляться через ленту.)

Создайте динамический именованный диапазон SQLDB для данных SQL в Sheet1, используя формулу:

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

Создайте второй динамический именованный диапазон EXCELRNG для введенных вручную данных в Sheet2, используя формулу:

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

Оба этих именованных диапазона предполагают, что имена переменных вводятся в строке 1 каждого из двух листов.

Введите имена переменных в строке 1 листа 3 (начиная с ячейки A1).

Введите следующую формулу в ячейку A2 Sheet3:

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

Скопируйте формулу в столбцы с именами переменных, а затем вниз по строкам, пока результаты формул не станут черточками («-»).

В качестве следующего шага можно создать сводную таблицу на другом листе для анализа и организации.

Опять же, первым шагом будет создание динамического именованного диапазона, скажем, RESULTRNG, вставка следующей формулы в поле ввода Name Manager для именованного диапазона:

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

Затем создайте сводную таблицу на новом листе, установив RESULTRNG в качестве таблицы, которую вы хотите проанализировать. Это отфильтровывает любые конечные тире из таблицы формул в Sheet3.

Это работает, потому что формула RESULTRNG подсчитывает общее количество строк в Sheet1 и Sheet2 (исключая заголовок в Sheet2) и общее количество столбцов в Sheet1, и устанавливает его экстент на основе этих подсчетов, исключая любые тире в любых конечных строках ( или столбцы) в таблице формул Sheet3.

пыхтеть
источник
Если бы я сделал это таким образом, разве комбинированная таблица не должна быть фиксированного размера? И если сделать таблицу больше, чем нужно, разве это не испортит мне ситуацию, если я попытаюсь создать сводную таблицу, которая будет обрабатывать данные из объединенной таблицы? (Потому что некоторые значения в таблице будут символами '-'?) Или есть способ обойти эти проблемы?
Ajedi32
(Кстати, я обычно предпочитаю чистые решения Excel, такие как это, потому что они не требуют, чтобы пользователь
включил
Требуется некоторое ручное обслуживание, чтобы убедиться, что формулы захватили все данные в двух таблицах. Чтобы избежать штрихов, вам нужно будет копировать формулы только туда, куда они возвращали данные, а не штрихам.
Чафф
Можно ли создать еще один именованный диапазон, включающий только те строки из объединенной таблицы, которые не являются пустыми (заполнены символами «-»)? Таким образом, я мог просто установить сводные таблицы, чтобы получить их данные из этого диапазона, и мне не пришлось бы беспокоиться о тире.
Ajedi32
Я расширил свой ответ, чтобы объяснить, как можно создать сводную таблицу, исключая дефисы. Попытка поместить таблицу «без черты» просто перенесет проблему с чертой на другой лист, с # N / A в ячейках тире, если только новая таблица не была изменена вручную каждый раз, когда изменяется число строк в исходных данных.
Чафф
5

Я нашел способ сделать это. Это решение немного сложнее и требует, чтобы у обеих таблиц были свои собственные отдельные листы (на них больше ничего нет), но кроме этого оно делает почти то, что я хочу. (Здесь также, кажется, есть большой потенциал для выполнения более сложных операций, таких как соединения.)

Перейдите на вкладку данных на ленте, нажмите «Из других источников» и «Из Microsoft Query». Затем нажмите «Файлы Excel», выберите файл, в котором вы сейчас работаете, и нажмите «ОК». Затем нажмите «Отмена» и, когда появится вопрос о том, хотите ли вы продолжить редактирование в Microsoft Query, нажмите «Да». Отсюда вы можете нажать кнопку SQL и написать собственный запрос SQL на любом листе электронной таблицы. В моем случае:

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

Примечание: для меня этот метод перестает работать после того, как я закрываю файл и открываю его снова. В любом случае я публикую его здесь, но на случай, если это просто проблема с моим компьютером или кто-то другой может заставить его работать.

Ajedi32
источник
1
Он отлично работает, соединяя две разные книги. Это было именно то, что мне нужно. Спасибо!
Дэйвом
Этот метод работает очень хорошо для меня. Выполните запрос, затем просто скопируйте данные и перейдите в Excel. Однако важно отметить, что он удалит все дублирующиеся строки из ваших данных, надеюсь, вы не возражаете, если я немного отредактирую этот ответ.
Some_Guy
Добавляя, потому что это на самом деле произошло со мной, я почти использовал это, чтобы объединить данные о продажах в одну электронную таблицу, прежде чем сделать сводную таблицу для получения некоторых итогов, и я бы получил несколько ошибок, когда один и тот же объем продукта, проданного несколько раз, имел бы были пропущены.
Some_Guy
@Some_Guy Просто используйте UNION ALL вместо этого.
Ajedi32
3

Если вы заинтересованы в решении VBA, я смог заставить работать следующее:

  • Установите динамический именованный диапазон для данных, которые вы извлекаете из SQL Server. Откройте диспетчер имен, введите новое имя (скажем, «SQLDB») и скопируйте следующую формулу в поле «Относится к». Я предположил, что ваши данные находятся в Sheet1:

    =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1))
    
  • Установите другой именованный диапазон для диапазона, в который вводятся данные вручную. Я использовал имя EXCELRNG и предположил, что оно было в Sheet2. Именованный диапазон начинается со строки 2, чтобы исключить строку заголовка. Формула здесь идентична первой, за исключением листа, к которому она относится:

    =OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))
    
  • Вот первый набор настроек, которые я использовал для подключения к таблице SQL. Доступ к диалоговому окну можно получить, выбрав Подключения на вкладке Данные на ленте. Отключение фонового обновления гарантирует, что макрос VBA приостанавливается до тех пор, пока не завершится обновление данных в листе Excel. Обновление соединения при открытии рабочего листа может не понадобиться, но я хотел убедиться, что любая аутентификация будет выполнена до запуска макроса.

Настройки соединения

  • Вот второй набор настроек. Они находятся в разделе «Свойства» на вкладке «Данные» (когда выбрана ячейка в импортированной таблице SQL). Хотя я выбрал опцию «Вставить целые строки для новых данных, удалить неиспользуемые ячейки», у меня фактически не было никаких проблем с опцией «Вставить ячейки ...».

свойства соединения

  • Наконец, это код VBA. Чтобы вставить его, выберите Visual Basic на вкладке «Разработчик». Выделите имя листа в списке слева. На него будет ссылаться как «VBA Project (имя листа)». Затем выберите «Вставить модуль» в строке меню в верхней части экрана и вставьте код в новый модуль. Обратите внимание, что я поместил сводную таблицу в Sheet3. Как написано, макрос не сортирует новую таблицу, хотя это не составит труда добавить.

    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
    
пыхтеть
источник
Это выглядит как довольно твердое решение. У меня есть пара вопросов, хотя. Что вызывает этот макрос? Он просто автоматически запускается при обновлении подключений к данным, или вам нужно нажать отдельную кнопку, чтобы запустить его вручную? Во-вторых, это работает с таблицами, верно? (Не только диапазоны, которые не отформатированы в виде таблиц). Если это так, не может ли сама таблица обрабатывать сортировку? (Вместо того, чтобы макрос VBA делал сортировку, как вы предложили?)
Ajedi32
1
В действующем режиме вы можете запустить макрос, выбрав «Макросы» на вкладке «Разработчик», а затем выбрав и запустив макрос. Две альтернативы: назначьте ее пользовательской кнопке на ленте и используйте ее для запуска; или вставьте его как код макроса в событие Worksheet_Activate. Это будет запускаться всякий раз, когда вы выбрали лист консолидации. Он будет работать с таблицами, которые могут выполнять сортировку. Тем не менее, я не уверен, что таблицы добавляются автоматически при добавлении данных.
Чафф
3

Вот версия решения @ chuff «Pure Excel», которое разработано специально для работы с таблицами. (IE Два источника данных, которые вы хотите объединить - это таблицы.)

Основное различие между этим методом и тем, что он написал в своем ответе, состоит в том, что вам не нужно определять именованные диапазоны для двух наборов данных, которые вы объединяете, поскольку они являются таблицами и уже имеют свой собственный именованный диапазон. Так что давай и назови свой первый стол Table1, и ваш второй стол Table2.

Теперь создайте новую таблицу в верхнем левом углу нового листа и присвойте ей те же имена столбцов, что и двум другим таблицам. Затем введите следующую формулу в ячейку A2 только что созданного листа:

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

Затем скопируйте эту формулу по всем столбцам таблицы, а затем вниз по строкам, пока результаты формул не станут черточками («-»). Примечание. Сортировка этой новой таблицы ничего не даст, поскольку содержимое каждой ячейки фактически идентично (все они содержат одну и ту же формулу).

Если столбцы в объединенной таблице показывают 0, когда они должны отображать пустую ячейку, вы можете заключить формулу в этом столбце с помощью функции замены, например так:

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

Если вы хотите создать сводную таблицу, которая использует данные из этой новой таблицы, вам придется создать именованный диапазон. Во-первых, назовите таблицу Table3. Теперь перейдите на вкладку формул и нажмите «Определить имя». Дайте ссылку имени, введите следующее уравнение для ее значения («Относится к»):

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

Затем вы можете использовать эту именованную ссылку в качестве диапазона для вашей сводной таблицы.

Ajedi32
источник
0

Если вы просто хотите получить результат один раз, есть веб-сайт, который объединит две таблицы для вас: https://office-tools.online/table/merge/

Вы вставляете таблицы в веб-страницу и выбираете соответствующие параметры. Вот скриншот встроенного примера, который показывает, как его использовать:

введите описание изображения здесь

Hvg Hng
источник