0

我正在运行 Access 2003。我正在使用 Switch 根据布尔标准选择日期字段:

Switch(<criterion>, Date1, 1, Date2)

即,如果“标准”为真,则返回Date1,否则返回Date2。

Date1 和 Date2 是表中的日期/时间类型列。

问题是,Switch 将它们作为文本返回——而不是日期/时间!

有没有办法强迫他们进入约会状态?我试过了

Switch(<criterion>, #Date1#, 1, #Date2#)

Switch(<criterion>, Val(Date1), 1, Val(Date2))

两者都失败并显示一条或另一条错误消息。

有任何想法吗?

4

3 回答 3

2

我认为 Immediate If [IIf()] 函数更适合您尝试执行的操作:

IIf(<criterion>, Date1, Date2)

但 Switch() 函数不应破坏数据类型,并且与日期/时间数据类型不兼容。考虑这个函数:

Public Function trySwitch(ByVal pWhichDay As String) As Variant
    Dim varOut As Variant
    varOut = Switch(pWhichDay = "yesterday", Date - 1, _
        pWhichDay = "today", Date, _
        pWhichDay = "tomorrow", Date + 1)
    trySwitch = varOut
End Function

trySwitch("today")返回10/6/2009TypeName(trySwitch("today"))返回日期

于 2009-10-07T00:36:27.590 回答
1

你的例子有些奇怪。

Switch 接受表达式对,如果第一个计算结果为 True,则返回其配对值,否则,它传递给第二个,并计算该参数。

您似乎将 1 视为 True,这是因为它不是 Fales,但您最好使用:

  Switch(<criterion>, Date1, True, Date2)

但这只是对 Immediate If 函数 IIf() 的功能的复制,而 IIf() 需要更少的参数。

但它有同样的问题,因为它返回一个变体。但是您应该能够将其强制转换为可以格式化为日期的数据类型。

但是,该变体是否会被隐式强制或您需要显式执行,取决于您在哪里使用它。在查询结果中,您可以将 IIf([criterion], Date1, Date2) 的输出排序为日期,因为该列被强制转换为日期类型。

如果您必须显式进行强制转换,则 CDate() 是要使用的函数——您可以使用 CDate() 函数包装产生 Variant 输出的外部函数,以确保变体输出被显式强制转换为日期类型:

  CDate(IIf(<criterion>, Date1, Date2))

但我很可能在这里遗漏了一些重要的东西,因为我似乎走上了一条完全不同的轨道……

于 2009-10-07T02:46:28.110 回答
1

你能发布一些代码和数据来重现这个问题吗?因为这是SWITCH()在 SQL 代码中,所以我认为 SQL DDL(CREATE TABLE等)和 DML(INSERT INTO添加数据)是最合适的:)

[挑剔点:Access 数据库 SQL 没有“布尔”数据类型。它有一个YESNO可以是NULL值的数据类型;三值逻辑不是布尔值。]

这是一些 SQL DML(ANSI-92 查询模式语法)来演示它如何按我的预期工作:

SELECT TYPENAME
       (
          SWITCH
          (
             NULL, #2009-01-01 00:00:00#, 
             FALSE, #2009-06-15 12:00:00#, 
             TRUE, #2009-12-31 23:59:59#
          )
       );

更改任何“标准”值,该值始终返回为“日期”,即类型DATETIME


更新:

TYPENAME功能是一个很棒的工具... Access 似乎以不同的方式解释了结果集的整个“列”

的确。因为一列只能是一种数据类型TYPENAME(),所以行的结果可能会产生误导。混合类型的行值必须“提升”为更高的数据类型。与 Access 数据库引擎一样,该过程是完全不透明的,并且完全没有关于该主题的文档,因此您只需要吸吮它并查看例如

SELECT #2009-01-01 00:00:00# AS row_value, 
       TYPENAME(#2009-01-01 00:00:00#) AS row_type
  FROM Customers
UNION ALL
SELECT 0.5, 
       TYPENAME(0.5) AS row_type
  FROM Customers

分别返回“日期”和“十进制”,但该列是什么?显然,答案是:

SELECT DT1.row_value, TYPENAME(DT1.row_value) AS column_type
  FROM (
        SELECT DISTINCT #2009-01-01 00:00:00# AS row_value 
          FROM Customers
        UNION ALL
        SELECT DISTINCT 0.5
          FROM Customers
       ) AS DT1;

'细绳'?!

...当然,这甚至不是 Access 数据库引擎 SQL 数据类型。因此TYPENAME(),令人讨厌的是,使用了“最合适”的 VBA 类型的名称。例如:

SELECT TYPENAME(CBOOL(0));

返回“布尔”,尽管如上所述,Access 数据库引擎 SQL 中没有布尔数据类型。和

SELECT TYPENAME(my_binary_col)

返回“字符串”。请注意,相同的 VBA 映射限制适用于CAST函数(又一个烦恼),例如,没有“强制转换为BINARY”函数,并且CDEC()自 Jet 4.0 以来该函数仍然损坏:(

于 2009-10-07T08:11:15.367 回答