我正在运行Access 2003.我正在使用Switch根据布尔标准选择日期字段:
Switch(<criterion>, Date1, 1, Date2)
即,如果“criterion”为true,则返回Date1,否则返回Date2。
Date1和Date2是表格中的日期/时间类型列。
问题是,Switch将它们作为文本返回 - 而不是日期/时间!
有没有办法强迫他们进入日期?我试过了
Switch(<criterion>, #Date1#, 1, #Date2#)
和
Switch(<criterion>, Val(Date1), 1, Val(Date2))
两者都失败并出现一条错误消息。
有什么想法吗?
答案 0 :(得分:2)
我认为立即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(“今天”)返回 10/6/2009 和 TypeName(trySwitch(“今天”))返回日期强>
答案 1 :(得分:1)
你的例子有些奇怪。
Switch接受表达式对,如果第一个计算结果为True,则返回其配对值,否则,它将传递给第二个,并计算该参数。
你似乎把1视为真,这是因为它不是Fales,但你会更好:
Switch(<criterion>, Date1, True, Date2)
但这只是立即If函数的复制,IIf()和IIf()只需要较少的参数。
但它有同样的问题,因为它返回一个变体。但您应该能够将其强制转换为可以格式化为日期的数据类型。
但是,该变体是否会被隐式胁迫,或者您是否需要明确地执行它,取决于您使用它的位置。在查询结果中,您可以将IIf([criterion],Date1,Date2)的输出排序为日期,因为该列会被强制转换为日期类型。
如果必须显式执行强制,则CDate()是要使用的函数 - 您将使用CDate()函数包装生成Variant输出的外部函数,以确保变量输出是显式的被胁迫的日期类型:
CDate(IIf(<criterion>, Date1, Date2))
但我很可能会错过这里重要的事情,因为我似乎在完全不同的轨道上......
答案 2 :(得分:1)
你能发布一些代码和数据来重现这个问题吗?因为这是SQL代码中的SWITCH()
,所以我认为SQL DDL(CREATE TABLE
等)和DML(INSERT INTO
来添加数据)是最合适的:)
[挑剔点:Access数据库SQL没有'boolean'数据类型。它有一个YESNO
数据类型,可以是NULL
值;三值逻辑不是布尔值。]
这里有一些SQL DML(ANSI-92 Query Mode语法)来演示它如何按预期工作:
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
功能很棒 访问似乎解释了 结果集的整个“列” 不同
事实上。由于列只能是一种数据类型,因此行中TYPENAME()
的结果可能会产生误导。必须将混合类型的行值“提升”为更高的数据类型。与访问数据库引擎一样,该过程完全不透明,并且关于主题的文档完全不存在,因此您只需要吮吸它并查看例如
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
分别返回'Date'和'Decimal'但该列是什么?显然,答案是:
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;
'STRING'?!
...当然甚至不是Access数据库引擎SQL数据类型。所以TYPENAME()
令人讨厌地使用了“最适合”的VBA类型的名称。例如:
SELECT TYPENAME(CBOOL(0));
返回'Boolean',尽管如上所述,Access Database Engine SQL中没有布尔数据类型。和
SELECT TYPENAME(my_binary_col)
返回'String'。请注意,相同的VBA映射限制适用于CAST
函数(还有另一个烦恼),例如没有'强制转换为BINARY
'函数,自Jet 4.0以来CDEC()
函数仍然被破坏:(