如何传递参数在SQL中查询(Excel)

我“连接”Excel到Sql,它工作正常 – 我写了一些SQL脚本,它运作良好。 我想要做的就是将parameter passing给查询。 像我每次刷新我想要能够传递参数(过滤条件)到SQL查询。 在“连接属性”参数button被禁用。 所以我不能做参数查询。 谁能帮我?

这取决于您尝试连接的数据库,创build连接的方法以及您使用的Excel版本。 (另外,最有可能的是,计算机上的相关ODBC驱动程序的版本。)

以下示例在我的本地计算机上都使用了SQL Server 2008和Excel 2007。

当我使用数据连接向导(在function区的“数据”选项卡上的“获取外部数据”部分的“从其他源”下)时,我看到了与之相同的事情:“参数”button被禁用,并向查询,就像select field from table where field2 = ? ,导致Excel抱怨参数的值没有被指定,并且更改没有被保存。

当我使用Microsoft Query(与数据连接向导相同的地方)时,我能够创build参数,为其指定显示名称,并在每次运行查询时input值。 调出连接的连接属性,参数…button被启用,参数可以修改和使用,因为我认为你想要的。

我也能够用Access数据库来做到这一点。 Microsoft Query可以用来创build参数化的查询来处理其他types的数据库,这似乎是合理的,但我现在不能轻易地进行testing。

这个post已经够老了,这个答案可能对OP没有多大用处,但是我花了很长时间来回答这个问题,所以我想我会用我的发现来更新它。

这个答案假设你已经有一个工作的SQL查询在你的Excel文档中。 有很多教程向您展示了如何在Web上实现这个function,并解释了如何向参数化查询添加参数化查询的大量教程,只是没有一个适用于现有的OLE DB查询。

所以,如果你像我一样,拿着一个有效的Excel文件来处理一个工作查询,但是用户希望能够根据其中一个数据库字段来筛选结果,如果你像我一样既不是Excel也不是一个SQL大师,这可能会帮助你。

大多数对这个问题的网页回应似乎表示,你应该在查询中添加一个“?”来让Excel提示你input一个自定义的参数,或者在参数应该是的地方放置提示或单元格参考。 这可能适用于ODBC查询,但它似乎不适用于OLE DB,在前一个实例中返回“没有给出一个或多个必需参数的值”,而“列名称无效xxxx”或“未知对象后两者中的“xxxx”。 同样,使用神话般的“参数…”或“编辑查询…”button也不是一个选项,因为它们在这种情况下似乎永久变灰。 (仅供参考,我使用Excel 2010,但使用Excel 97-2003工作簿(* .xls))

然而,我们可以做的是添加一个参数单元格和一个简单的例程button,以编程方式更新我们的查询文本。

首先,在你的外部数据表(或任何地方)的上面添加一行,在那里你可以在空单元格和button旁边放一个参数提示符(Developer-> Insert-> Button(Form Control)) – 你可能需要启用Developer选项卡,但你可以find如何做到这一点),如下所示:

[提示(标签)文本的单元格的图片,空单元格,然后是一个按钮。]

接下来,在外部数据(蓝色)区域中select一个单元格,然后打开数据 – >全部刷新(下拉) – >连接属性…查看您的查询。 下一节中的代码假定您的查询(连接属性 – >定义 – >命令文本)中已经有一个参数,forms为“WHERE(DB_TABLE_NAME.Field_Name ='Default Query Parameter')”(包括括号)。 显然,根据数据库表名,数据库值字段(列)名称以及某个缺省值,“DB_TABLE_NAME.Field_Name”和“缺省查询参数”需要在代码中有所不同,以便在文档打开时进行search你有自动刷新设置)。 请记下“DB_TABLE_NAME.Field_Name”值,因为您将在下一节中使用该值,以及查询的“连接名称”(可在对话框顶部find)。

closures连接属性,然后按Alt + F11打开VBA编辑器。 如果您尚未打开,请在“项目”窗口中右键单击包含button的工作表名称,然后select“查看代码”。 将以下代码粘贴到代码窗口中(build议复制,因为单引号和双引号是必需的)。

 Sub RefreshQuery() Dim queryPreText As String Dim queryPostText As String Dim valueToFilter As String Dim paramPosition As Integer valueToFilter = "DB_TABLE_NAME.Field_Name =" With ActiveWorkbook.Connections("Connection name").OLEDBConnection queryPreText = .CommandText paramPosition = InStr(queryPreText, valueToFilter) + Len(valueToFilter) - 1 queryPreText = Left(queryPreText, paramPosition) queryPostText = .CommandText queryPostText = Right(queryPostText, Len(queryPostText) - paramPosition) queryPostText = Right(queryPostText, Len(queryPostText) - InStr(queryPostText, ")") + 1) .CommandText = queryPreText & " '" & Range("Cell reference").Value & "'" & queryPostText End With ActiveWorkbook.Connections("Connection name").Refresh End Sub 

用你的值replace“DB_TABLE_NAME.Field_Name”和“连接名称”(在两个位置)(需要包括双引号,空格和等号)。

将“单元格引用”replace为参数所在的单元格(从开始处的空单元格) – 我是第一行中的第二个单元格,所以我放置了“B1”(同样需要双引号)。

保存并closuresVBA编辑器。

在相应的单元格中input您的参数。

右键单击您的button,将RefreshQuery分配为macros,然后单击您的button。 查询应该更新并显示正确的数据!

注意:只有在查询中有等号的连接或其他匹配时,才需要使用整个filter参数名称(“DB_TABLE_NAME.Field_Name =”),否则只需要等号就足够了,Len()多余。 如果您的参数包含在也用于连接表的字段中,则需要将代码中的“paramPosition = InStr(queryPreText,valueToFilter)+ Len(valueToFilter) – 1”行更改为“paramPosition = InStr( Right(.CommandText,Len(.CommandText) – InStrRev(.CommandText,“WHERE”)),valueToFilter)+ Len(valueToFilter) – 1 + InStr(.CommandText,“WHERE”)“,以便它只查找valueToFilter “WHERE”之后。

这个答案是在datapig的“BaconBits”的帮助下创build的,我find了查询更新的基本代码。