在EXCEL中VBA编程检验身份证号码有效性

简介: 在EXCEL中VBA编程检验身份证号码有效性

1.增加了过程clearB()用来清除B1:Bx原有的出错说明,在过程examIdentityCard() 开头调用

                   2.修改了过程examIdentityCard(),如果身份证号码包含多余的字符则提示"包括多余字符;"

参加数据治理工作,使用库表转换功能把excel表格数据上传到平台上的数据库,在进行数据质量检测时,有许多身份证号码数据被检测为“非身份证号码”,但没有更具体的说明,比如是数据位数不对(应为15位或18位),出生日期不对(1986-02-30),或者是末位校验码不对……等等。

把这些包含被检测为“非身份证号码”的异常数据导出为Excel表格,再用VBA写代码来校验分析。

网上的关于检验身份证号码的代码很多,但基本不能拿来就用,还得结合自己的实际应用情况进行修改完善。

编写过程中的体会主要有两点:

一是对于18位身份证号码,末位的x可能被写成乘号×、全角大写x、全角小写x,而我们用的数据库系统数据质量检测只认大写半角X,写成号×、全角大写x、小写半角x都会被认为“非身份证号码”。这些都要进行预处理,将它们转换为大写半角X。预处理代码如下:

v = Rng.text
        '检查是否包含×
        If InStr(v, "×") > 0 Then
            v = Replace(v, "×", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If
    
        '检查是否包含全角大写x
        If InStr(v, "X") > 0 Then
            v = Replace(v, "X", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If
    
        '检查是否包含全角小写x
        If InStr(v, "x") > 0 Then
            v = Replace(v, "x", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If

二是身份证号码可能包含非打印字符,不做处理的话,就会影响Len()返回值,进而影响到身份证位数的判断。而在实际处理中,发现VBA提供的Trim()、Application.WorksheetFunction.Clean()都清理不干净,网上的代码也不适合我的情况,于是自己DIY了一个:

Function DelUnprintChar(s) As String
    r = ""
    For iPosition = 1 To Len(s) Step 1
        c = Mid(s, iPosition, 1)
        If ((c >= "0") And (c <= "9")) Or ((c >= "a") And (c <= "z")) Or ((c >= "A") And (c <= "Z")) Then
            r = r & c
        End If
    Next
    DelUnprintChar = r
End Function

完整的代码如下(身份证号码数据在A1:Ax,数据错误显示在B1:Bx)。:

Function exam18(v) As String
    Dim cd1, r
    r = ""
    
    '下面检验出生日期是否正确
    cd1 = Mid(v, 7, 4) & "-" & Mid(v, 11, 2) & "-" & Mid(v, 13, 2)
    If Not IsDate(cd1) Then
        r = "出身日期" & cd1 & "无效;"
    Else
        r = examIdentityCardLastDigit(v)
    End If
        
    exam18 = r
End Function

Function exam15(v) As String
    '对15位身份证号码进行校验
    Dim a, r
    r = ""

    '是否全数字
    If Not IsNumeric(r) Then
       r = "15位身份证号码应全是数字;"
    Else
        '下面检验出生日期是否正确
        a = Mid(v, 7, 2) & "-" & Mid(v, 9, 2) & "-" & Mid(v, 11, 2)
        If Not IsDate(a) Then
            r = "出身日期" + a + "无效;"
        End If
    End If
    exam15 = r
End Function



Function examIdentityCardLastDigit(v) As String
    Dim i, arr1(), arr2(), r, s

    arr1 = Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2) '系数
    arr2 = Array("1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2") '对应的结果
    
    r = ""
    t = Left(v, 17)
    If Not IsNumeric(t) Then
       r = "身份证号码前17位应是数字;"
    Else
        s = 0
        For i = 1 To 17
            t = Mid(v, i, 1) '取出每位数
            s = s + t * arr1(i - 1) '求和
        Next i

        s = s Mod 11   '取余数
        t = Mid(v, 18, 1)
        
        'If t = "x" Then
        '    t = "X"
        'End If
        
        If arr2(s) <> t Then  '判断是否与最后一位相等
            r = "末位数应为" & arr2(s) & ";"
        End If
    End If
    examIdentityCardLastDigit = r
End Function

Function DelUnprintChar(s) As String
    r = ""
    For iPosition = 1 To Len(s) Step 1
        c = Mid(s, iPosition, 1)
        If ((c >= "0") And (c <= "9")) Or ((c >= "a") And (c <= "z")) Or ((c >= "A") And (c <= "Z")) Then
            r = r & c
        End If
    Next
    DelUnprintChar = r
End Function

Sub clearB()
    '清除B1:Bx原有的出错说明
    Range("b1", Cells(Rows.Count, "b").End(xlUp)).Clear
End Sub


Sub examIdentityCard()
    Dim r, s, v
    For Each Rng In Range("a1", Cells(Rows.Count, "a").End(xlUp))
        v = Rng.text

        '检查是否包含×
        If InStr(v, "×") > 0 Then
            v = Replace(v, "×", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If
    
        '检查是否包含全角大写x
        If InStr(v, "X") > 0 Then
            v = Replace(v, "X", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If
    
        '检查是否包含全角小写x
        If InStr(v, "x") > 0 Then
            v = Replace(v, "x", "X", 1, -1)
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "×应为X;"
        End If
    
        r = Len(v)
        v = DelUnprintChar(v)
        If Len(v) < r Then
            Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "包括多余字符;"
        End If

        If Len(v) = 15 Then
            r = exam15(v)
            If Len(r) <> 0 Then
                Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value + r
            End If
        ElseIf Len(v) = 18 Then
            If InStr(v, "x") > 0 Then
                v = UCase(v) '小写变大写
                Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value & "x应为X;"
            End If
        
            r = exam18(v)
            If Len(r) <> 0 Then
               Range("B" & Rng.Row).Value = Range("B" & Rng.Row).Value + r
            End If
        Else
            Range("B" & Rng.Row).Value = "身份证位数应为15或18位;"
        End If
Next


End Sub
相关文章
|
11天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2514 17
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
7天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1520 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
3天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
9天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
554 14
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19282 30
|
9天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
473 48
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18838 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17528 13
Apache Paimon V0.9最新进展
|
2天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
362 4
叮咚!您有一份六大必做安全操作清单,请查收