无法通过具有长定义的 vba 在 Access 中运行查询

Posted

技术标签:

【中文标题】无法通过具有长定义的 vba 在 Access 中运行查询【英文标题】:Can't run query in Access via vba with a long definition 【发布时间】:2015-06-26 23:18:32 【问题描述】:

我得到了一个很长的查询定义,当它在 Access GUI 中运行时它可以工作。我不想将它保存为最终用户可能会意外运行的 Query 对象,因此我想通过 VBA 运行它。当我尝试使用 DoCmd.RunSQL 运行它时,它会抛出一个错误:

“RunSQL 操作需要一个由 SQL 语句组成的参数。”

当我尝试使用 mydatabase.Execute 时,我得到:

“Microsoft Access 引擎找不到输入表或查询 ''。请确保它存在并且其名称拼写正确。”

我做了一个 Debug.Print 并将输出复制到 Access GUI 中的一个查询中,在清理线路制动器后,立即窗口添加了查询运行良好。查询字符串的长度为 5,293 个字符。任何帮助将不胜感激。

Dim dBase As Database
Set dBase = CurrentDb()
Dim stringSQL_3 As String
stringSQL_3 = _
"INSERT INTO Measurement_Period_History ( EMPLOYEE_NUMBER, PERIOD_START, PERIOD_END, DATE_REVIEWED, AVERAGE_HOURS, PERIOD_YEAR, PERIOD_TYPE_ID,  FIRST_PAY_WEEK, LAST_PAY_WEEK ) " & _
"SELECT FinalData.EMPLOYEE_NUMBER " & _
    ",FinalData.START_PERIOD " & _
    ",FinalData.END_PERIOD " & _
    ",Now() AS DATE_REVIEWED " & _
    ",IIF(FinalData.FLSA = 2, 40.00, SUM(FinalData.HOURS) / 52) AS AVERAGE_HOURS " & _
    ",Cint(FinalData.PERIOD_YEAR) AS PERIOD_YEAR " & _
    ",FinalData.PERIOD_TYPE_ID " & _
    ",FinalData.FIRST_PAY_WEEK " & _
    ",FinalData.LAST_PAY_WEEK "

stringSQL_3 = stringSQL_3 & _
"FROM ( " & _
    "SELECT MeasurementData.EMPLOYEE_NUMBER " & _
        ",MeasurementData.FLSA " & _
        ",MeasurementData.STARTING_HIRE_DATE " & _
        ",MeasurementData.VARIABLE_EMPLOYEE " & _
        ",MeasurementData.START_PERIOD " & _
        ",MeasurementData.END_PERIOD " & _
        ",MeasurementData.PERIOD_TYPE_ID " & _
        ",MeasurementData.PRIOR_PERIOD_START " & _
        ",MeasurementData.PERIOD_YEAR " & _
        ",MeasurementData.FIRST_PAY_WEEK " & _
        ",MeasurementData.LAST_PAY_WEEK " & _
        ",IIf(IsNull(Payroll_History.HOURS), 0, Payroll_History.HOURS) AS HOURS "

stringSQL_3 = stringSQL_3 & _
    "FROM Payroll_History " & _
    "RIGHT JOIN ( " & _
        "SELECT BaseData.EMPLOYEE_NUMBER " & _
            ",BaseData.FLSA " & _
            ",BaseData.STARTING_HIRE_DATE " & _
            ",BaseData.VARIABLE_EMPLOYEE " & _
            ",BaseData.START_PERIOD " & _
            ",BaseData.END_PERIOD " & _
            ",BaseData.PERIOD_TYPE_ID " & _
            ",BaseData.PRIOR_PERIOD_START " & _
            ",BaseData.PERIOD_YEAR " & _
            ",DateAdd('d', 3, DateAdd('ww', - 52, DateAdd('d', - 2, DateAdd('ww', DateDiff('ww', 0, DateAdd('ww', IIf(DatePart('w', " & _
            "BaseData.END_PERIOD) >= 5, 0, - 1), BaseData.END_PERIOD)), 0)))) AS FIRST_PAY_WEEK " & _
            ",DateAdd('d', - 2, DateAdd('ww', DateDiff('ww', 0, DateAdd('ww', IIf(DatePart('w', BaseData.END_PERIOD) >= 5, 0, - 1), " & _
            "BaseData.END_PERIOD)), 0)) AS LAST_PAY_WEEK "

stringSQL_3 = stringSQL_3 & _
        "FROM ( " & _
            "SELECT ElgEmployees.EMPLOYEE_NUMBER " & _
                ",ElgEmployees.FLSA " & _
                ",ElgEmployees.STARTING_HIRE_DATE " & _
                ",ElgEmployees.VARIABLE_EMPLOYEE " & _
                ",IIF(ElgEmployees.VARIABLE_EMPLOYEE = No, DateSerial(" & DatePickerYear & " - 1, 4, 1), " & _
                "IIF(PeriodInfo.PRIOR_PERIOD_START IS NOT NULL, DateSerial(" & DatePickerYear & " - 1, DatePart('m', " & _
                "PeriodInfo.PRIOR_PERIOD_START), 1), DateSerial(" & DatePickerYear & " - 1, DatePart('m', ElgEmployees.STARTING_HIRE_DATE), 1))) AS START_PERIOD " & _
                ",IIF(ElgEmployees.VARIABLE_EMPLOYEE = No, DateAdd('d', - 1, DateSerial(" & DatePickerYear & ", 4, 1)), DateAdd('d', - 1, " & _
                "IIF(PeriodInfo.PRIOR_PERIOD_START IS NOT NULL, DateSerial(" & DatePickerYear & ", DatePart('m', PeriodInfo.PRIOR_PERIOD_START), 1), " & _
                "DateSerial(" & DatePickerYear & ", DatePart('m', ElgEmployees.STARTING_HIRE_DATE), 1)))) AS END_PERIOD " & _
                "," & DatePickerYear & " AS PERIOD_YEAR " & _
                ",PeriodInfo.PERIOD_TYPE_ID " & _
                ",PeriodInfo.PRIOR_PERIOD_START "

stringSQL_3 = stringSQL_3 & _
            "FROM ( " & _
                "SELECT Employee.EMPLOYEE_NUMBER " & _
                    ",Employee.FLSA " & _
                    ",Employee.VARIABLE_EMPLOYEE " & _
                    ",IIf(Day(Employee.CURRENT_HIRE_DATE) = 1, Employee.CURRENT_HIRE_DATE, DateSerial(DatePart('yyyy', DateAdd('m', 1, " & _
                    "Employee.CURRENT_HIRE_DATE)), DatePart('m', DateAdd('m', 1, Employee.CURRENT_HIRE_DATE)), 1)) AS STARTING_HIRE_DATE "

stringSQL_3 = stringSQL_3 & _
                "FROM Employee " & _
                "WHERE ( " & _
                        "((Employee.EMPLOYEE_NUMBER)" & EmployeeNumberText & ") " & _
                        "AND ((IIf(Day(Employee.CURRENT_HIRE_DATE) = 1, Employee.CURRENT_HIRE_DATE, DateSerial(DatePart('yyyy', DateAdd('m', 1, " & _
                        "Employee.CURRENT_HIRE_DATE)), DatePart('m', DateAdd('m', 1, Employee.CURRENT_HIRE_DATE)), 1))) < DateAdd('y', - 1, DATE ())) " & _
                        "AND ((Employee.CURRENT_TERMINATION_DATE) IS NULL) " & _
                        ") " & _
                ") AS ElgEmployees " & _
            "INNER JOIN ( " & _
                "SELECT Employee.EMPLOYEE_NUMBER " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, Measurement_Period_History.PERIOD_YEAR) AS PRIOR_PERIOD_YEAR " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, IIF(Employee.VARIABLE_EMPLOYEE = No, 2, 0), " & _
                    "IIF(Employee.VARIABLE_EMPLOYEE = No, 2, IIF(Measurement_Period_History.PERIOD_END < Employee.CURRENT_HIRE_DATE, 0, " & _
                    "IIF(Measurement_Period_History.AVERAGE_HOURS >= 30, 1, 0)))) AS PERIOD_TYPE_ID " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _
                    "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_END)) AS PRIOR_PERIOD_END " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _
                    "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_START)) AS PRIOR_PERIOD_START "

stringSQL_3 = stringSQL_3 & _
                "FROM Measurement_Period_History " & _
                "RIGHT JOIN Employee ON Measurement_Period_History.EMPLOYEE_NUMBER = Employee.EMPLOYEE_NUMBER " & _
                "WHERE ((Employee.CURRENT_TERMINATION_DATE) Is Null) AND (Employee.EMPLOYEE_NUMBER" & EmployeeNumberText & ") " & _
                "GROUP BY Employee.EMPLOYEE_NUMBER " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, Measurement_Period_History.PERIOD_YEAR) " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, IIF(Employee.VARIABLE_EMPLOYEE = No, 2, 0), " & _
                    "IIF(Employee.VARIABLE_EMPLOYEE = No, 2, IIF(Measurement_Period_History.PERIOD_END < Employee.CURRENT_HIRE_DATE, 0, " & _
                    "IIF(Measurement_Period_History.AVERAGE_HOURS >= 30, 1, 0)))) " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _
                    "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_END)) " & _
                    ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _
                    "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_START)) " & _
                ") AS PeriodInfo ON ElgEmployees.EMPLOYEE_NUMBER = PeriodInfo.EMPLOYEE_NUMBER " & _
            ") AS BaseData " & _
        ") AS MeasurementData ON Payroll_History.EMPLOYEE_NUMBER = MeasurementData.EMPLOYEE_NUMBER " & _
    "WHERE ((Payroll_History.PAY_DATE) Is Null) " & _
        "OR ( " & _
            "(Payroll_History.PAY_DATE) >= MeasurementData.FIRST_PAY_WEEK " & _
            "AND (Payroll_History.PAY_DATE) <= MeasurementData.LAST_PAY_WEEK " & _
            ") " & _
    ") AS FinalData "

stringSQL_3 = stringSQL_3 & _
"WHERE LAST_PAY_WEEK < Now() " & _
"GROUP BY EMPLOYEE_NUMBER " & _
    ",FLSA " & _
    ",STARTING_HIRE_DATE " & _
    ",VARIABLE_EMPLOYEE " & _
    ",START_PERIOD " & _
    ",END_PERIOD " & _
    ",PERIOD_TYPE_ID " & _
    ",PRIOR_PERIOD_START " & _
    ",PERIOD_YEAR " & _
    ",FIRST_PAY_WEEK " & _
    ",LAST_PAY_WEEK "


    Debug.Print stringSQL_3
    Debug.Print Len(stringSQL_3)
    dBase.Execute string_3

【问题讨论】:

当您收到来自dBase.Execute string_3 的错误时,string_3 中包含的字符串是什么? 并非没有,但我很确定这是保存查询存在的原因之一。有比字符串化更好的方法来保护您的 Access 对象。 罗伯特是对的。你让自己的生活变得困难。你应该重新考虑这个概念。 我必须将此传递给“高级用户”,他将在我完成后继续修改它。我知道他们不太可能摆弄 VBA 代码,但他们很可能会使用向导等添加报告和新表单。我知道这很糟糕,我不期待从现在起 3 年内保持这种状态,所以如果您有任何建议或可以指出我可以帮助我清理它的地方,我将不胜感激。 【参考方案1】:

你的 SQL 不是在 stringSQL_3 中吗?另一个字符串 (string_3) 中有什么?这可能是问题所在,您正在尝试执行错误的字符串?

【讨论】:

对。没有string_3。请声明Option Explicit 我不是 Access 程序员,不习惯使用变量定义如此松散的语言。我几乎完成了这个项目,但到处都添加了 Option Explicit。非常感谢!现在我只需要忍受一个愚蠢的错误,这个错误将在我的余生中出现在互联网上。 @Mrphin,我们所有人都曾有过这样的经历。不要出汗:)

以上是关于无法通过具有长定义的 vba 在 Access 中运行查询的主要内容,如果未能解决你的问题,请参考以下文章

编辑器中的 ms-access VBA 长 sql 查询字符串行拆分(内联双引号)

在 Excel VBA 中使用长 Access SQL 查询

使用 Access 2007 查询向导创建 SQL,仍然无法在 VBA 中运行

MS Access:导入规范无法通过 VBA

通过 VBA 在 MS Access 中自动链接/刷新 ODBC 链接表

通过 Access 2013 VBA 编辑后无法打开 Excel 2013 文件