使用SQL

时间:2017-08-16 17:11:05

标签: sql vba excel-vba integration excel

我正在处理一个使用VBA来处理数据的excel报告。

虽然没有理由不能将VBA用于我的目的,但我宁愿在SQL中这样做,因为我对这门语言更加精通。为了做到这一点,我面临着一些挑战,并将我的问题简化为一个更容易解决的问题。

假设我有一个Excel电子表格,单元格A1中的数字为1,单元格A2中为2,单元格A3中为3。在单元格A4中,我试图对这些进行求和,得到数字6。

SUM()函数会得到我想要的答案,但不是我想要的方式。

相反,这就是我想要做的......

1) read cells A1->A3 into a table object (call this x) using VBA
2) declare a string variable and set it to 'SELECT SUM(column1) FROM x'
3) execute that sql string
4) store the results in cell A4

这是一种可行的做事方式吗?如果是这样,可以发布一个例子吗?

1 个答案:

答案 0 :(得分:5)

是的,可以做到。不,它不应该完成。如果您需要3个单元格的总和,计算3个单元格的总和 - Excel具有专门为此制作的内置函数

=SUM(A1:A3)

[A4]中键入该内容,您就可以以最有效的方式获得而无需编写任何代码,并且毫不奇怪看到你所做的事情的任何人都会说出来。

还是不相信?好的。坐下来,抓一些爆米花,享受骑行。

  

使用VBA将单元格A1-> A3读入表格对象(调用此x)

Excel不是一个数据库,它没有 - 而不是你所说的单词" table"。但那并没有显示出来。

假设您的工作簿有3张,代号为Sheet1Sheet2Sheet3(无论如何都是默认值)。因此,Sheet1!A1:A3使用填充了一些您希望SUM向上的数字,因为......不重要的原因,只是因为

由于我们希望将总和写入Sheet1!A4,我们不会使用Sheet1作为我们的"表" - 而是我们将其视为我们的输出。

因此我们将Sheet1!A1:A3复制到Sheet2

Sheet2.Range("A1").Value = "Values" 'our column header
Sheet1.Range("A1:A3").Copy Sheet2.Range("A2") 'our values

接下来,我们需要一些可以将Sheet2视为&#34;表&#34;并对其执行SQL查询的内容。因此,我们将Sheet2设置ADODB / OLEDB连接,执行SQL查询,获取带有结果的Recordset对象,然后将值转储到Sheet1!A4。< / p>

执行此操作的邋late后期绑定代码如下所示:

Public Sub OverkillSum()

    Dim connection As Object
    Set connection = CreateObject("ADODB.Connection")
    connection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                    "Data Source=" & ThisWorkbook.FullName & ";" & _
                    "Extended Properties=""Excel 8.0;HDR=Yes;"";"

    Dim recordset As Object
    Set recordset = connection.Execute("SELECT SUM(Values) As Total FROM [Sheet2$]")

    Sheet1.Range("A4").Value = recordset.Fields("Total").Value
    recordset.Close
    connection.Close

End Sub

请注意,连接字符串需要ThisWorkbook.FullName,因此不会在您尚未保存的丢弃工作簿中工作。

在上面的内容和单元格=SUM(A1:A3)中的A4之间,设计决策 应该是明智的。

  • 延迟绑定的调用在运行时得到解决。这可以通过引用ADODB类型库并使用ADODB.ConnectionADODB.Recordset类型而不是使用Object接口来避免这种开销。
  • 与工作簿的连接也是无关的运行时开销。
  • 通过OLEDB查询工作表对于计算3个值的总和绝对不合理。
  • 您需要记住清理连接和记录集!
  • 不要这样做。
  • 只是不要。
  • Sheet1.Range("A4").Value = Application.WorksheetFunction.Sum(Sheet1.Range("A1:A3"))是本机Excel工作表功能解决方案的单行代码 - 这仍然有点过分,但至少它仍然属于Excel领域并且不涉及飞往月亮和背部。
  • 我是否说不这样做

此类解决方案 非常有用用于其他目的,例如当你有一个工作簿作为一个表格布局时,它包含应该存在于数据库中的信息但不知何故存在于Excel工作表中,有如此多的数据通过Workbooks.Open打开它并计算复杂的聚合(可能涉及{使用WHERE或其他非SQL方法,{1}}和GROUP BY子句效率低下。