【问题标题】:Translating MS Access SQL select query to VBA. Breaks when select with aggregation sum function将 MS Access SQL 选择查询转换为 VBA。使用聚合求和函数选择时中断
【发布时间】:2020-03-20 04:07:49
【问题描述】:

背景

我正在尝试使用 Excel VBA 从 Microsoft Office Access 数据库加载数据。 代码运行良好,我现在尝试添加一个额外的列 Position 从名为 EqBucket 的日期库中提取到最终结果表中

SQL 可以在 Access 中找到,但不能解析为 VBA。 添加时的代码中断

SUM(Eq_Buckets.Position) AS PositionOfSum

我猜这与围绕该列的聚合总和有关,因为此问题从未出现在其他直接引用的列中。

感谢任何指针。谢谢

'''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''

信息: 1、SQL字符串存储在Sheets("SQL").Range("A1").value中 2.数据库表Eq_SingleName_LBU,Eq_BucketsEq_Portfolio_Ref只是一个参考表,可以忽略

'''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''' **如果我删除“Sum(Eq_Buckets.Position) AS PositionOfSum”,则代码在 VBA 中有效

这是 MS Access 中完全可以使用的 SQL 代码:

SELECT Eq_SingleName_LBU.Identifier AS Identifier, Eq_SingleName_LBU.Issuer AS Issuer, Eq_SingleName_LBU.MV_USD AS MV, Sum(Eq_Buckets.Position) AS PositionOfSum, Eq_SingleName_LBU.Issuer_Weight AS [Issuer Weight], Eq_SingleName_LBU.Test_Limit AS Limit, Eq_SingleName_LBU.Room_Limit AS [Remaining Limit], Eq_SingleName_LBU.Data_Date
FROM Eq_SingleName_LBU INNER JOIN (Eq_Buckets INNER JOIN Eq_Portfolio_Ref ON Eq_Buckets.Composite_Portfolio = Eq_Portfolio_Ref.BBG_Account_Codes) ON Eq_SingleName_LBU.Identifier = Eq_Buckets.BB_UniqueID
Where Eq_Buckets.Data_Date = (#03/12/2020#) and Eq_SingleName_LBU.UnderTest="Y"
GROUP BY Eq_SingleName_LBU.Identifier, Eq_SingleName_LBU.Issuer, Eq_SingleName_LBU.MV_USD, Eq_SingleName_LBU.Issuer_Weight, Eq_SingleName_LBU.Test_Limit, Eq_SingleName_LBU.Room_Limit, Eq_SingleName_LBU.Data_Date
HAVING (((Eq_SingleName_LBU.Data_Date) In (#03/12/2020#)))
ORDER BY Eq_SingleName_LBU.Data_Date;

'''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''

这是 SQL 字符串需要通过的 VBA 代码

Sub ADOImportFromAccessTable()

'On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.Calculation = xlManual
Sheets("EQ1_SQL").Visible = True

    Dim con As Object
    Dim rst As Object
    Dim dbPath As String

    dbPath = "\\Db\Asset_db.accdb"
    Set con = CreateObject("ADODB.Connection")
    con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
    con.Open

    Set rst = CreateObject("ADODB.Recordset")

'This is where the SQL code will be referenced.
strSql = ThisWorkbook.Sheets("SQL").Range("A1").Value
Debug.Print strSql
strSql = Replace(strSql, "{date1}", Date_1)
Debug.Print strSql
strSql = Replace(strSql, "{date2}", Date_2)

rst.Open strSql, con, adOpenDynamic, adLockOptimistic

    rst.Close
    Set rst = Nothing
    con.Close
    Set con = Nothing

End sub

'''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''

这是我从 Excel VB 编辑器收到的错误消息

Here is the error I get from VB editor.
Run-tme error '-2147467259 (80004005);: 
Method 'Open' of object' _ Recordset' failed

【问题讨论】:

  • 如果您从 Excel 中调用它,为什么不将您的 SQL 存储在工作表单元格中呢?比所有这些串联要容易得多。
  • 我需要将 sql 设为字符串以使其成为动态变量(不同的日期),但我如何准确调用存储在工作表中的 SQL?
  • sql = Thisworkbook.sheets("SQL").Range("A1").Value 如果您需要更改某些部分,请使用标记并在从单元格中获取文本后替换它们。以sql = Replace(sql, "{date1}", Date_1) 为例
  • 我尝试将工作 SQL 代码粘贴到一个单元格中并让 VBA 调用该 cell.value,但我认为它不起作用。通过直接在单元格中粘贴 SQL 代码,字符串本身仍然是 SQL 格式,VBA 不会理解它。字符串本身需要采用正确的格式并通过调用 access.db 记录的 VBA 代码进行解析。我在原始问题中添加了 VBA 调用访问代码以进行澄清。还有其他想法吗?
  • 从单元格中获取字符串与将其硬编码到 VBA 中没有什么不同。当您运行该代码时会发生什么?首先尝试使用简单的 SQL 语句,以确保基本正确。

标签: sql excel vba ms-access


【解决方案1】:

尝试在Position 周围添加括号,即Sum(B.[Position])

您可以通过使用表名别名来缩短 SQL,例如

strSQL = " SELECT A.Identifier AS Identifier, A.Issuer AS Issuer, A.MV_USD AS MV," & _
             "   Sum(B.[Position]) AS PositionOfSum, " & _
             "   A.Issuer_Weight AS [Issuer Weight]," & _
             "   A.Test_Limit AS Limit, " & _
             "   A.Room_Limit AS [Remaining Limit]," & _
             "   A.Data_Date" & _
             " FROM Eq_SingleName_LBU AS A " & _
             " INNER JOIN Eq_Buckets AS B" & _
             " ON A.Identifier = B.BB_UniqueID" & _
             "   WHERE B.Data_Date = #2020/12/03# " & _
             "   AND A.UnderTest = 'Y' " & _
             " GROUP BY A.Identifier, A.Issuer," & _
             "   A.MV_USD, A.Issuer_Weight, A.Test_Limit," & _
             "   A.Room_Limit, A.Data_Date" & _
             " HAVING A.Data_Date IN (#2020/12/03#) " & _
             " ORDER BY A.Data_Date"

【讨论】:

  • 感谢它的位置,即 Sum(B.[Position])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 2019-03-16
相关资源
最近更新 更多