单元格内容作为 Excel 中“WHERE”语句的一部分

Posted

技术标签:

【中文标题】单元格内容作为 Excel 中“WHERE”语句的一部分【英文标题】:Cell Contents as Part of a 'WHERE' Statement in Excel 【发布时间】:2017-08-28 17:05:08 【问题描述】:

我已经搜索了几个星期,但在找到以下问题的答案方面没有取得太大成功......

我能否在 Excel 中(在开发人员选项中)创建一个文本框,然后让用户输入的文本框内容成为 SQL (T-SQL) 中 WHERE 语句的一部分?理想情况下,我希望用户能够输入一个 3 位数的 ID 号码,然后点击搜索按钮以在相同或不同的工作表上显示结果列表。如果文本框不简单,那么我将满足于引用单元格的内容来代替文本框的内容。

类似这样的:

SELECT T.CustomerName, T.NetAmount, T.TransactionType

FROM TheDatabase.dbo.TransactionsTable T

WHERE T.ScheduledDate > '2016-01-01' AND 
     (T.Status = 'InProcess' OR T.Status = 'Completed') AND
      T.CustomerID = [textbox1.contents / cell(A1).. something]

我知道 SQL 不是为这样工作而设计的,但我希望它能说明我想要完成的工作。

一些背景:

我将一些职责转交给一位同事,因为我要换一个角色。我有一个定期运行的报告,它为我提供有关应付账款交易的统计信息。我必须在一夜之间学习一些基本的 SQL,并且在设计 SELECT 语句和边学习边学习方面非常成功。问题是,每当我需要将新客户(基本上是一个 3 位数字)添加到我的帐户列表中以进行审查时,我都必须修改查询。这对我来说没什么大不了的,我只是打开 PowerQuery,选择高级视图,然后编辑代码。我不能为下一个人修复工具,所以我需要一种方法,他们可以搜索他们想要的客户。

我可以加载所有客户,但主表中有超过 360 万笔交易,我们查看了 30 多个字段。另外,我将 3 个数据库中的至少 6 个表连接在一起以提取和计算所有信息。上次我尝试检索所有交易数据时,由于系统内存不足,我无法生产。我唯一一次成功查询到这么多数据花了将近 10 分钟。老实说,这对我来说不是问题,但是这个人必须一直运行它,我需要加快速度。如我所见,消除问题的唯一方法是只提取我需要的交易。当我现在这样做时,大约需要 3 秒。

我一直在使用的查询是在 Microsoft SQL Server Management Studio 中创建的,我基本上是在 Excel 中创建查询时复制查询并将其粘贴到“高级”框中。

任何关于这方面的建议都会对现在和未来的项目有所帮助!

【问题讨论】:

首先,您正在寻找IN 子句WHERE T.CustomerID IN (list of comma separated int values, or one column query resulset) 第二,不知道你是如何设法执行 SQL 语句的。是在 Excel 里面吗? 第三,它看起来像一个XY问题,试着描述你的实际需要而不是你的解决方法。 meta.stackexchange.com/questions/66377/what-is-the-xy-problem 【参考方案1】:

在 Excel VBA 中,您可以打开与数据库的 SQL 连接。但是您需要正确的权限和密码才能执行此操作。也许贵公司的技术人员可以提供帮助。

然后您需要构建您的 SQL 代码并发送它。然后检索结果。您可以通过多种方式显示结果。

这里有一些代码可以帮助您入门:

    Set objMyConn = New ADODB.Connection
    Set objMyRecordset = New ADODB.Recordset

    Dim strSQLText As String   ' Declare a string to build your SQL in

    'Open your connection
    objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=TheDatabase;User ID=xyz;Password=xyz;"
    objMyConn.Open

    strSQLText = "SELECT T.CustomerName, T.NetAmount, T.TransactionType " & _
                 "FROM TheDatabase.dbo.TransactionsTable T " & _
                 "WHERE T.ScheduledDate > '2016-01-01' AND " & _
                 "(T.Status = 'InProcess' OR T.Status = 'Completed') AND " & _
                 "T.CustomerID = '" & _
                 Me.textbox1.Value & "';"

    Set objMyRecordset.ActiveConnection = objMyConn

    objMyRecordset.Open strSQLText            

    ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

此代码假定您的 T.CustomerID 是 varchar。如果它是整数(或其他数据类型),则需要从 SQLText 中删除 textbox1.Value 周围的单引号

您可能还希望将结果保存在单元格“A1”以外的位置。显示结果的方式/位置很多。

此外,此代码假定 textbox1.Value 中只有一个 ID。首先让这个 SQL 只使用 1 个客户代码。如果您需要返回多个客户的数据,您可以稍后再做这件事,只需稍加努力即可。

希望你能开始。

【讨论】:

另请注意,此代码易受 SQL 注入攻击。我相当肯定,如果我输入'; drop table TheDatabase.dbo.TransactionsTable;--,您的整个 TransactionsTable 都会消失。 @Nzall:非常正确。每当您想构建快速的初学者级别的 SQL 以允许用户输入拼接到代码中的数据时,您都会将其开放给不良玩家造成破坏。为了缓解这个问题,您需要学习将变量作为参数传递的编码技术。希望他公司的初学者不要破坏他们的数据。但如果这是一个真正的问题,他们应该让公司的数据库程序员为他们编写代码。真正担心的 DBA 不会一开始就给他们连接字符串信息。指出 Nzall 是件好事。 @abraxascarab 恕我直言,最好在一开始就学习正确的习惯(参数化查询),而不是学习通过字符串连接进行查询,然后再取消学习。 @alroc:非常正确。然而,OP 声明他正在换工作,目前还不清楚他是否会成为一名程序员。理想情况下,公司应该有一个程序员为他做这个查询。再加上他的解释有点模糊。而且由于没有其他人在帮助他,我的回答将他引向了一个可行的简单答案。我实际上是希望有人能更无私地利用他们的时间,并为他写一个关于参数化查询的初学者解释。提示提示。 :) 我正在使用的数据库是我们每晚进行的只读备份。我们备份然后复制备份,这就是我们从中提取统计数据的数据库。除了只有少数人使用它的事实之外,drop 命令还会引发错误。如果确实出现问题,我们只需在当晚进行完整备份而不是差异备份 - 问题就解决了。

以上是关于单元格内容作为 Excel 中“WHERE”语句的一部分的主要内容,如果未能解决你的问题,请参考以下文章

excel两个单元格内容合并不了怎么办?

excel合并单元格内容的教程

Excel vba 执行时间与单元格内容长度呈指数关系

Excel技巧空单元格自动填充上一单元格内容

Excel技巧空单元格自动填充上一单元格内容

vb.net中如何获得DataGridView单元格内容