我有一个列可以是:
我可以使用表格中的验证规则字段来强制执行此操作吗?如果是这样我该怎么做?
答案 0 :(得分:1)
尝试在字段级别使用单个验证规则进行验证可能有点繁琐,但由于您使用的是Access 2010,因此您可以使用Before Change data macro进行验证:
该宏的XML源代码是
<?xml version="1.0" encoding="utf-16" standalone="no"?>
<DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application">
<DataMacro Event="BeforeChange">
<Statements>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">dateStringIsValid</Argument>
<Argument Name="Value">False</Argument>
</Action>
<ConditionalBlock>
<If>
<Condition>IsNull([dateString])</Condition>
<Statements>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">dateStringIsValid</Argument>
<Argument Name="Value">True</Argument>
</Action>
</Statements>
</If>
<ElseIf>
<Condition>UCase([dateString])="N/A"</Condition>
<Statements>
<Comment>force to uppercase for consistency</Comment>
<Action Collapsed="true" Name="SetField">
<Argument Name="Field">dateString</Argument>
<Argument Name="Value">UCase([dateString])</Argument>
</Action>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">dateStringIsValid</Argument>
<Argument Name="Value">True</Argument>
</Action>
</Statements>
</ElseIf>
<ElseIf>
<Condition>Len([dateString])=10</Condition>
<Statements>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">ddStr</Argument>
<Argument Name="Value">Mid([dateString],1,2)</Argument>
</Action>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">mmStr</Argument>
<Argument Name="Value">Mid([dateString],4,2)</Argument>
</Action>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">yyyyStr</Argument>
<Argument Name="Value">Mid([dateString],7,4)</Argument>
</Action>
<Action Collapsed="true" Name="OnError">
<Argument Name="GoTo">Next</Argument>
</Action>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">newDate</Argument>
<Argument Name="Value">DateSerial(Val([yyyyStr]),Val([mmStr]),Val([ddStr]))</Argument>
</Action>
<Action Collapsed="true" Name="OnError">
<Argument Name="GoTo">Fail</Argument>
</Action>
<ConditionalBlock>
<If>
<Condition>[MacroError].[Number]=0</Condition>
<Statements>
<Comment>make sure DateSerial() hasn't converted an invalid date to a valid one (e.g. 32/01/2014 ->
01/02/2014)</Comment>
<ConditionalBlock>
<If>
<Condition>(Year([newDate])=Val([yyyyStr])) And (Month([newDate])=Val([mmStr])) And
(Day([newDate])=Val([ddStr]))</Condition>
<Statements>
<Comment>reassemble to ensure consistent separators</Comment>
<Action Collapsed="true" Name="SetField">
<Argument Name="Field">dateString</Argument>
<Argument Name="Value">[ddStr] & "/" & [mmStr] & "/" &
[yyyyStr]</Argument>
</Action>
<Action Collapsed="true" Name="SetLocalVar">
<Argument Name="Name">dateStringIsValid</Argument>
<Argument Name="Value">True</Argument>
</Action>
</Statements>
</If>
</ConditionalBlock>
</Statements>
</If>
</ConditionalBlock>
</Statements>
</ElseIf>
</ConditionalBlock>
<ConditionalBlock>
<If>
<Condition>[dateStringIsValid]=False</Condition>
<Statements>
<Action Collapsed="true" Name="RaiseError">
<Argument Name="Number">1</Argument>
<Argument Name="Description">dateString is not valid.</Argument>
</Action>
</Statements>
</If>
</ConditionalBlock>
</Statements>
</DataMacro>
</DataMacros>
(有关如何将数据宏XML代码传入和传出Access数据库的信息,请参阅问题here。)
顺便说一下,在我对你之前的问题here的回答之后,以下几个原因只是为什么将日期/文本信息存储在单个(文本)字段中可能仍然不是很好想法,即使所有这些花哨的验证:
通过将日期值存储为文本,您可以随时将文本转换回实际日期值,只要您想将字段值用作日期(除了只是逐字打印)。这不仅令人讨厌,而且可能会产生重大的性能影响(见下文第3点)。
通过“硬连线”将日期格式设置为dd/mm/yyyy
,您将强制它在您的用户身上。这些天人们希望应用程序尊重他们的偏好,所以如果有人决定他们想要使用yyyy/mm/dd
格式 - 并且他们已经在Windows控制面板中指定了 - 那么他们希望他们的应用程序使用它。
也许最重要的是,通过将日期存储为dd/mm/yyyy
文字,您基本上可以保证您在单日文字dd/mm/yyyy
值之外进行的搜索不会是sargable需要进行表扫描。如果您已经确定yyyy/mm/dd
,则可以通过直接字符串比较至少完成日期范围搜索,但使用dd/mm/yyyy
(或甚至mm/dd/yyyy
)字符串,您的搜索效果将受到影响。