在 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 |
答案1
这是一个纯 Excel 解决方案,没有 VBA。它的工作原理是使用 INDEX 函数逐行逐列地处理 SQL 数据,直到值用尽并导致错误情况。IFERROR 函数捕获错误并使用第二个 INDEX 函数逐行逐列地处理手动输入的数据,直到这些值用尽并导致错误情况。第二个 IFERROR 函数捕获错误并返回破折号(“-”)。(必须通过功能区刷新 SQL 数据,公式才能产生正确的结果。)
创造使用以下公式为 Sheet1 中的 SQL 数据创建动态命名范围 SQLDB:
=OFFSET(Sheet1!$A$2,0,0,COUNTA(Sheet1!$A:$A)-1,COUNTA(Sheet1!$1:$1))
创造使用以下公式在 Sheet2 中手动输入数据的第二个动态命名范围 EXCELRNG:
=OFFSET(Sheet2!$A$1,1,0,COUNTA(Sheet2!$A:$A)-1,COUNTA(Sheet2!$1:$1))
这两个命名范围都假定变量名称在两张工作表的每一行的第 1 行中输入。
进入Sheet3 第 1 行(从单元格 A1 开始)中的变量名称。
进入在 Sheet3 的单元格 A2 中输入以下公式:
=IFERROR(INDEX(SQLDB,ROWS(A$2:A2),COLUMN(A2)),IFERROR(INDEX(EXCELRNG,ROWS(A$2:A2)-ROWS(SQLDB),COLUMN(A2)),"-"))
复制将公式沿着变量名称列移动,然后沿着行向下移动,直到公式的结果全部为破折号(“-”)。
下一步可以在另一张工作表中创建数据透视表以进行分析和组织。
同样,第一步是创建一个动态命名范围,例如 RESULTRNG,在命名范围的名称管理器输入框中插入以下公式:
=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 公式表中任何尾随行(或列)中的任何破折号。
答案2
我找到了一种方法。这个解决方案有点棘手,它要求两个表都有自己单独的工作表(上面没有其他内容),但除此之外,它几乎完全符合我的要求。(这里似乎还有很多潜力可以执行更复杂的操作,例如连接。)
转到功能区上的数据选项卡,单击“来自其他来源”和“来自 Microsoft Query”。然后单击 Excel 文件,选择您当前正在处理的文件并单击确定。然后,点击取消,当系统提示您是否要继续在 Microsoft Query 中编辑时,点击“是”。从这里,您可以单击 SQL 按钮并在电子表格中的任何工作表上编写自定义 SQL 查询。就我而言:
SELECT *
FROM `'Sheet1$'` `'Sheet1$'`
UNION ALL
SELECT *
FROM `'Sheet2$'` `'Sheet2$'`
笔记:对我来说,关闭文件并再次打开后,此方法就失效了。无论如何,我还是会在这里发布它,以防万一这只是我的电脑的问题,或者其他人可以让它工作。
答案3
以下是@chuff 的专为处理表格而设计的“纯 Excel”解决方案。(即,您要合并的两个数据源是表格。)
此方法与 chuff 在其答案中发布的方法的主要区别在于,您不需要为要合并的两个数据集定义命名范围,因为它们是表并且已经有自己的命名范围。因此,请继续命名您的第一个表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)
然后,您可以使用该命名引用作为数据透视表的范围。
答案4
如果您只是想要一次性获得结果,那么有一个网站可以为您合并两个表: https://office-tools.online/table/merge/
您将表格粘贴到网页中并选择相关参数。以下是内置示例的屏幕截图,显示了如何使用它: