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     |

5 ответов5

5

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

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

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

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

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)

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

3

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

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

    =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(название листа). Затем выберите "Вставить модуль" в строке меню в верхней части экрана и вставьте код в новый модуль. Обратите внимание, что я поместил сводную таблицу в Лист3. Как написано, макрос не сортирует новую таблицу, хотя это не составит труда добавить.

    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
    
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 листа 3:

=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.

0

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .