使用来自excel的VBA模块的访问存储查询出错

时间:2011-09-21 22:19:02

标签: ms-access vba

我正在尝试使用VBA从excel运行存储的MS访问查询。我已经创建了一个通用函数来执行此任务(使用ADODB)。我可以使用或不使用参数获得结果。

但是当我尝试运行一个引用Access vba模块的存储查询时,excel barfs运行时错误“未定义函数MissCat”(这是存储查询使用的自定义函数的名称)。

我原本希望这可以工作,因为访问知道函数的定义,但现在我感觉ADODB接口试图在存储的查询中插入SQL而不借助于我创建的VBA模块访问。

我正在跳过这些箍,因为我的大多数用户都没有在他们的机器上安装访问权限。

我是否可以按原样使用存储的查询(可能更改查询界面)?或者是阻力最小的路径改变查询,使得它不需要自定义函数(正如你在下面看到的那样很简单,我用它作为拐杖因为我不太熟悉SQL) / p>

这是函数

Function MissCat(ProShip As Date, TargetDate As Date) As String

If TargetDate >= ProShip Then
    MissCat = "Meets target"
    Exit Function
End If

If TargetDate < Date Then
    MissCat = "Unrecoverable"
    Exit Function
End If

Select Case ProShip - TargetDate
    Case 1 To 6
        MissCat = "Less than one week"
    Case 7 To 14
        MissCat = "1-2 Weeks"
    Case Else
        MissCat = "Greater than 2 Weeks"
End Select
End Function

这是SQL

TRANSFORM Count(Shipset.ID) AS CountOfID
SELECT Calendar.[Week Of]
FROM Calendar INNER JOIN Shipset ON Calendar.DateSerial = Shipset.ShipDate
WHERE (((Calendar.[Week Of])>Date()-(13*7)) AND ((Shipset.ShipDate) Is Not Null) AND   ((Shipset.ReqOut)=False) AND ((Shipset.TwoTier)=False))
GROUP BY Calendar.[Week Of]
ORDER BY IIf(MissCat([Shipset]![ShipDate],[Shipset]![TargetDate])="Meets Target","Meets Target","Hit") DESC 
PIVOT IIf(MissCat([Shipset]![ShipDate],[Shipset]![TargetDate])="Meets Target","Meets Target","Hit");

感谢,

2 个答案:

答案 0 :(得分:2)

基于@ HansUp出色的分析,我想知道SWICH()陈述是否更容易阅读,例如

SELECT ProShip,
       TargetDate,
       SWITCH
       (
          TargetDate >= ProShip,      "Meets target",
          TargetDate < Date,          "Unrecoverable", 
          ProShip - TargetDate < 7,   "Less than one week", 
          ProShip - TargetDate < 14,  "1-2 Weeks", 
          TRUE,                       "Greater than 2 Weeks" 
       )
  FROM YourTable;

我也想知道使用DATEDIFF('D', TargetDate, ProShip)是否比使用DATETIME值上的算术更容易阅读(即解密意图)。

答案 1 :(得分:1)

除非在Access会话中运行,否则您的查询将无法使用自定义VBA功能。

您可以将嵌套的IIf()函数语句替换为MissCat函数。当嵌套很复杂时,这种方法面临两个挑战:很难遵循逻辑;搞砸语法很容易。

一般形式是IIf(condition,truepart,falsepart)

因此,对于第一个条件,请在您在Access中创建的临时过程中尝试此操作。

Debug.Print IIf(TargetDate >= ProShip, "Meets target", "else")

下一步,将“else”替换为第二个条件的IIf表达式。

Debug.Print IIf(TargetDate >= ProShip, "Meets target", _
    IIf(TargetDate < Date, "Unrecoverable", "else"))

等等。这就是我最后的大混乱。

Debug.Print IIf(TargetDate >= ProShip, "Meets target", _
    IIf(TargetDate < Date, "Unrecoverable", _
    IIf(ProShip - TargetDate < 7, "Less than one week", _
    IIf(ProShip - TargetDate < 15, "1-2 Weeks", "Greater than 2 Weeks"))))

使程序正常工作后,复制嵌套的IIf表达式并在新的Access查询中对其进行测试。

SELECT
    ProShip,
    TargetDate,
    IIf(TargetDate >= ProShip, "Meets target", 
    IIf(TargetDate < Date, "Unrecoverable", 
    IIf(ProShip - TargetDate < 7, "Less than one week",
    IIf(ProShip - TargetDate < 15, "1-2 Weeks", "Greater than 2 Weeks")))) AS MissCat 
FROM YourTable;

再次查看您在原始查询中如何使用MissCat函数后,我认为我不会尝试直接替换此方法。我将创建一个单独的查询来转换基础数据,然后调整原始查询以使用新查询作为其数据源之一。