You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不通过CMD使用VBA获取Windows用户账户的当前用户全名?

问题描述

我们团队在域环境下使用Windows设备协作处理Excel文件,无法通过OneDrive实现协作。为了跟踪文件编辑记录,我写了一段VBA代码,在每次保存文件时记录时间戳和当前用户。目前用Environ("Username")只能获取类似ID1234的Windows用户名,但所有用户账户都配置了更实用的全名(格式如(Company) Flash Steel)。之前通过调用CMD的net user命令解析输出的方式虽然可行,但希望用更优雅的原生VBA实现来替代。

原代码片段:

' When saving, append the user ID and timestamp
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    ...
    Worksheets("Front Cover").Range(nextTimestampCell).Value = Format(Now(), "yy/mm/dd - HH:nn:ss")
    ' Build string for command
    cMDcommand = "cmd /c net user """ & Environ("Username") & """ /DOMAIN | find /I ""Full name"""
    ' Execute command and read top line
    result = Trim(CreateObject("Wscript.Shell").Exec(cMDcommand).StdOut.readline)
    ' Trim result and output User
    Worksheets("Front Cover").Range(nextUserCell).Value = Right(result, Len(result) - 29)
End Sub

原生VBA解决方案

在域环境中,可以通过**ADSI(Active Directory Service Interfaces)**直接访问Active Directory获取用户全名,无需调用外部命令,更稳定高效。以下是两种实现方式:

方法1:使用ADsNameTranslate转换并获取用户信息

该方法先将用户名转换为LDAP路径,再绑定到用户对象读取全名:

Private Function GetDomainUserFullName() As String
    Dim objTrans As Object
    Dim objUser As Object
    Dim strUserName As String
    Dim strLDAPPath As String
    
    strUserName = Environ("Username")
    
    ' 初始化ADsNameTranslate对象
    Set objTrans = CreateObject("ADsNameTranslate")
    objTrans.Init 1, "" ' 1代表ADS_NAME_INITTYPE_DOMAIN,空字符串使用当前域
    objTrans.Set 3, strUserName ' 3代表ADS_NAME_TYPE_NT4格式(DOMAIN\用户名)
    
    ' 转换为LDAP路径格式
    strLDAPPath = objTrans.Get(1) ' 1代表ADS_NAME_TYPE_LDAP
    
    ' 绑定到用户对象并读取全名
    Set objUser = GetObject("LDAP://" & strLDAPPath)
    GetDomainUserFullName = objUser.FullName
    
    ' 释放对象
    Set objUser = Nothing
    Set objTrans = Nothing
End Function

方法2:直接通过用户Principal Name绑定

如果需要兼容本地账户,也可以直接构造用户路径读取信息:

Private Function GetDomainUserFullName() As String
    Dim objUser As Object
    Dim strDomain As String
    Dim strUserName As String
    
    strUserName = Environ("Username")
    strDomain = Environ("USERDOMAIN") ' 获取当前域
    
    ' 绑定到用户对象
    Set objUser = GetObject("WinNT://" & strDomain & "/" & strUserName & ",user")
    GetDomainUserFullName = objUser.FullName
    
    Set objUser = Nothing
End Function

整合到保存事件中

将上述函数替换原代码中调用CMD的部分,修改后的Workbook_BeforeSave如下:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    Dim nextTimestampCell As Range
    Dim nextUserCell As Range
    Dim userFullName As String
    
    ' 假设此处已定义nextTimestampCell和nextUserCell的位置
    ' ...
    
    ' 记录时间戳
    Worksheets("Front Cover").Range(nextTimestampCell).Value = Format(Now(), "yy/mm/dd - HH:nn:ss")
    
    ' 获取用户全名
    userFullName = GetDomainUserFullName()
    
    ' 记录用户信息(获取失败时回退到用户名)
    Worksheets("Front Cover").Range(nextUserCell).Value = IIf(userFullName <> "", userFullName, Environ("Username"))
End Sub

注意事项

  • 域环境下普通用户默认具备访问Active Directory的权限,无需额外配置
  • 方法2兼容本地账户和域账户,适用性更广
  • 原生ADSI方法避免了命令输出格式变化导致的解析错误,稳定性更强

内容的提问来源于stack exchange,提问作者Flash_Steel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:35:12