通过VBA和regex验证Access项目编号字段

通过VBA和regex验证Access项目编号字段,regex,ms-access,vbscript,vba,Regex,Ms Access,Vbscript,Vba,我想验证访问表单中文本框中的条目。文本框后面的字段存储标识每个项目记录的项目编号。我们目前在文本框的before_update事件中有一个非常复杂的Do-While循环,它成功地验证了一些东西,但我正在加紧我们的代码,并希望了解如何进行更优雅的正则表达式验证。以下是技术细节 项目编号具有标准格式,如PJ17-14-000,分为三个块,用破折号分隔。以下是每个街区的规则 第一个块是项目类型/会计年度块。前两个字符始终是alpha字符,它们会更改以反映不同的高级项目类型。PJ、EL、RM、ER是一些

我想验证访问表单中文本框中的条目。文本框后面的字段存储标识每个项目记录的项目编号。我们目前在文本框的before_update事件中有一个非常复杂的Do-While循环,它成功地验证了一些东西,但我正在加紧我们的代码,并希望了解如何进行更优雅的正则表达式验证。以下是技术细节

项目编号具有标准格式,如PJ17-14-000,分为三个块,用破折号分隔。以下是每个街区的规则

第一个块是项目类型/会计年度块。前两个字符始终是alpha字符,它们会更改以反映不同的高级项目类型。PJ、EL、RM、ER是一些例子,但它们可以是任意两个阿尔法字符。接下来的两个字符始终是数字,反映项目开始的会计年度。例如,PJ17-14-000始于2017财年

第二个块只是一个数字,指示项目建立的顺序。因此,PJ17-1-000是2017财年启动的第一个PJ项目。PJ17-2-000是第二个。等等这个数字的位数在理论上没有限制,但实际上它从不超过四位数。但是,这很重要,前导数字永远不能为零。因此,我们永远不会使用PJ17-01-000这样的项目编号,验证应拒绝使用此类编号。相反,分析员只需输入PJ17-1-000即可

最后,最后一个块始终正好是表示子项目的三个数字字符。大多数项目只有一个部分(没有子项目),因此最后一个块就是000。但有些项目有许多子项目,因此它们可能有PJ17-1-001、PJ17-1-002、PJ17-1-003(等等)记录。对于第三个块,数字可以(通常是)有前导零

这些是项目编号本身的规则。有趣的是:我们的数据库允许分析师在项目字段中输入多个以空格分隔的项目编号。(我知道有一种更好的设计使用链接表和子表单,但这是我们的传统系统。)为什么一个项目会有两个数字是一个很复杂的故事,但有时(通常)会有,我们必须考虑到这一点。因此,项目编号字段可能需要(因此应允许)聚合项目编号,如“PJ17-1-000 ER16-143-000 PI16-23-000”

因此,对于任何单个项目编号,验证都应该遵循上述规则,并且应该允许任何数量的项目编号正好由一个空格分隔。我该怎么做

我开始使用vbscript.regexp,但不知道如何解决这个复杂的问题。非常感谢您对如何使其工作的任何帮助,或者您认为比我们当前的beast更优雅、更易于阅读/维护的任何其他方法。

使用

^[A-Z]{2}\d{2}-[1-9]\d*-\d+(?: [A-Z]{2}\d{2}-[1-9]\d*-\d+)*$

单个项目代码模式是
[A-Z]{2}\d{2}-[1-9]\d*-\d+

  • [A-Z]{2}
    -2个大写ASCII字母(注意:如果
    objRegEx.IgnoreCase=True
    ,则这也将匹配小写ASCII字母)
  • \d{2}
    -2位数字
  • -
    -连字符
  • [1-9]\d*
    -从
    1
    9
    的数字,然后是0+任意数字
  • -
    -连字符
  • \d+
    -1个或多个数字
整个模式是
^
(?:
)*$

  • ^
    -字符串的开头
  • -如上所述的项目代码模式
  • (?:
    )*
    -零个或多个序列:
    • -空格
    • -如上所述的项目代码模式
  • $
    -字符串结束
VBA代码:

Function IsProjCodeValid(s As String) As Boolean
    Dim objRegEx As Object
    Set objRegEx = CreateObject("VBScript.RegExp")
    objRegEx.IgnoreCase = True
    objRegEx.Pattern = "^[A-Z]{2}\d{2}-[1-9]\d*-\d+(?: [A-Z]{2}\d{2}-[1-9]\d*-\d+)*$"

    IsProjCodeValid = objRegEx.Test(s)
End Function

哇,太快了!我认为可能需要调整的一件事是子项目编号的代码。这不仅仅是“一个或多个数字”,而是三个数字。因此,我认为调整方法是简单地将\d+更改为\d{3}。似乎有效。听起来正确吗?@EmilyFTW:如果位数始终为3,则使用
\d{3}