【问题标题】:How do I make an Access Form automatically open to a user's data?如何使访问表单自动打开用户数据?
【发布时间】:2010-11-16 15:39:45
【问题描述】:

我正在尝试编写 VB 代码,以允许 Access 识别打开数据库的人的计算机 ID、打开表单并过滤分配给用户的记录。有谁知道如何做到这一点?

【问题讨论】:

  • 您所要求的当然是可能的,但您可能无法在巨型问题中得到完整的答案。为什么不尝试将项目拆分为更小的问题?例如,您的第一个问题可能是:“如何在 Access 中编写 VBA 代码来识别一个人打开数据库时使用的计算机?”将您的问题分成更小的部分将帮助您获得更好的问题答案。

标签: ms-access vba


【解决方案1】:

API to get the user name 可能比使用Environ 更好。如果名称在表格中可用,您可以使用DLookUp 获取ID,该ID 可以与the Where argument of the OpenForm method of the DoCmd object 一起使用以打开过滤列表。

【讨论】:

    【解决方案2】:

    如果这就是您所说的 ComputerID,您可以使用 Environ$("ComputerName")。这是我做到的一种快速而肮脏的方式。请注意,用户通常可以关闭表单的过滤器。 正如其他人所说,PC 上的环境变量有可能被非管理员用户修改。

    如果您担心用户会修改计算机的环境变量(即通过 cmd 设置 COMPUTERNAME=MYBOSS),如果您知道用户不是无法通过注册表或 Windows 修改计算机名的管理员用户(见下文)。

    使用 API 的警告

    如果用户在 PC 上具有管理员权限并且他们能够编辑 HKLM 注册表值,那么他们可以创建以下注册表项:

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName]
    "ComputerName"="MyBossComputerName"
    

    如果他们重新启动 PC,Windows API 调用将使用错误的名称。然后他们可以将注册表项设置回正常并重新启动 PC。

    在我的场景中,我有多个用户在不同的日子从同一台 PC 和 Access 数据库工作。他们从 PC 上的共享文件夹位置打开数据库。当他们单击切换板项目并且表单打开表单的 Load 事件时运行。此表单绑定到具有名为 USERNAME 的列的表,该列只是 UserName 的环境变量值(例如 John.Smith)。

    这是我在加载事件中放入的 VBA:

    Private Sub Form_Load()
        Dim currUser As String
        DoCmd.Maximize
        currUser = Environ$("USERNAME")
        Me.Filter = "USERNAME = '" & currUser & "'"
        Me.FilterOn = True
    End Sub
    

    API 调用解决方案

    如果您希望通过 API 调用来获取 ComputerName,那么您可以执行以下操作:

    API 调用 GetComputerName 是从 Ken Getz(VBA 开发人员手册)或 Dan Appleman(Visual Basic Programmer's Guide to the Win32 API)的代码派生而来。 您还可以在互联网上找到它。首先将一个模块添加到您的项目中重命名它 API或有意义的东西。然后插入以下代码:

    Private Declare Function GetComputerName Lib "kernel32" _ 
       Alias "GetComputerNameA"(ByVal strBuffer As String, lngSize As Long) As Long
    
    Public Function ComputerNameValue() As String
       Dim strBuffer as String
       Dim retValApi as Long
       Dim bufferSize as Long
    
       bufferSize = 256
    
       strBuffer = Space(bufferSize)
    
       'bufferSize will be returned with ComputerName length less null character.'
    
       retValApi = GetComputerName(strBuffer, bufferSize) 
    
       If CBool(retValApi) Then
          ComputerNameValue = Left$(strBuffer, bufferSize)
       Else
         'Your Error Handler'
       End If
    
    End Function
    

    在表单加载事件中(修改为使用 API 包装函数而不是 Envrion$):

    Private Sub Form_Load()
        Dim PCName As String
        DoCmd.Maximize
        PCName = ComputerNameValue()
        Me.Filter = "COMPUTERNAME = '" & PCName & "'"
        Me.FilterOn = True
    End Sub
    

    【讨论】:

    • Environ$("ComputerName") 真的不是一个好主意。通过打开命令提示符,输入SET ComputerName=MyBossComputer 然后从同一命令提示符运行 Access,我可以轻松地假装在使用我老板的计算机。获取计算机名称的唯一可靠方法是通过@Remou 的答案中引用的 Windows API。
    • 我部分同意该说法,我将修改代码sn-p。如果工作场所没有锁定 PC 和/或用户具有能够修改 HKLM 配置单元的管理员权限,那么他们可以轻松地创建注册表项:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName]" ComputerName"="MyBossComputer" 重新启动操作系统。打开访问表单。当代码对 Kernel32::GetComputerNameA 进行 API 调用时,它将在启动时读取此注册表项。所以只要用户不能在PC上修改HKLM hive,这个API就是可靠的。
    • 该编辑会更改本地计算机的名称,如果它与同名计算机位于同一 LAN 上,则会导致某些类型的命名空间冲突(取决于名称解析的完成方式 - - 在对用户具有管理员权限的可能情况下,它将是点对点的,在这种情况下,可能通过 NETBios 广播解决,这将导致错误)。但是,重点。
    猜你喜欢
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多