簡體   English   中英

VBA Excel中的登錄嘗試和錯誤處理

[英]Login attempts and error handling in VBA Excel

我一直在嘗試解決登錄問題,但是找不到解決方案。 當登錄和傳遞均失敗時,錯誤消息將開始倒計時,而不會讓用戶表明其他意見。

問題1:任何人都可以進行必要的更正,而無需過多更改給定的代碼結構並進行解釋嗎?

問題2:在授予訪問權限時,什么代碼會將“ User1”文本變成粗體?

問題3:哪些命令將禁用msg表單右上角的“ X”? 先感謝您

這就是我能做的
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨

Private Sub BtOK_Click()
Dim User1 As String
Dim count As Integer
count = 3

MM:

If EDBoxlogin.Value = "admin" And EDBoxpass.Value = "1234" Then
   User1 = Application.UserName

   MsgBox "welcome" & User1 & " !", vbExclamation, "Access Granted"
   Sheets("Plan1").Visible = xlSheetVisible
   Unload Me
Else
    If EDBoxlogin.Value = "" Or EDBoxpass.Value = "" Then
       MsgBox "Please, fill in the fiels 'login' and 'pass'", vbExclamation + vbOKOnly, "Access denied : incomplete information"
    Else
        If count >= 0 Then
           MsgBox "Login and pass are incorrect! You have " & count & " more trial(s)", vbExclamation + vbOKOnly, "Access denied"
           EDBoxlogin.Value = "" And EDBoxpass.Value = ""
           ' I want to delete previous text in the editbox fields
           count = count - 1
           GoTo MM
        Else
        ThisWorkbook.Close
        End If
    End If
End If
End Sub

如果您真的不需要知道哪個用戶正在打開工作簿,請考慮使用Excel的內置密碼安全功能。 另外,您還應該使用Excel的內置功能對文件的內容進行加密,否則任何人都可以使用文本編輯器打開文件並找到代碼中列出的用戶ID和密碼。

如果您必須使用登錄表單,並且在過去也必須這樣做,那么以下代碼將通過向隱藏的工作表Users添加用戶列表而建立。 該工作表中的A列需要為用戶名,B列應包含密碼。 此工作表還使用單元格D1跟蹤失敗的登錄嘗試。 在代碼中使用變量來做這種事情很困難……您必須將它們設置為Public並且在運行代碼時如果有任何錯誤,它將失去其值,那么可能會發生不好的事情。

該代碼還引用了另一個工作表SplashPage 這使您可以在用戶退出工作簿時隱藏Project1 當文件打開或關閉時,我編寫的代碼處理隱藏/取消隱藏過程。

我不知道在用戶表單中關閉關閉框的方法。 如果用戶這樣做,我已經添加了拒絕登錄的代碼。

快樂的編碼。

'Module: frmLogin
Private Sub BtOK_Click()
    Dim User1 As String
    Dim Passwd As Variant

    Sheets("Users").Range("D2").Value = False
    User1 = EDBoxlogin.Value
    Passwd = getPassword(User1)

        If User1 <> "" And Passwd <> "" And EDBoxpass.Value = Passwd Then
            Sheets("Users").Range("D2").Value = True
            MsgBox "Welcome " & User1 & "!", vbExclamation, "Access Granted"
            With Sheets("Plan1")
                .Visible = xlSheetVisible
                .Activate
            End With
            Sheets("SplashPage").Visible = xlSheetVeryHidden
            Unload Me
            Exit Sub
        Else
            Sheets("Users").Range("D1").Value = Sheets("Users").Range("D1").Value - 1
            If Sheets("Users").Range("D1").Value > 0 Then
                MsgBox "Login and pass are incorrect! You have " & Sheets("Users").Range("D1").Value & _
                    " more trial(s)", vbExclamation + vbOKOnly, "Access denied"
                EDBoxpass.Value = ""
                With EDBoxlogin
                    .Value = ""
                    .SetFocus
                End With
                ' I want to delete previous text in the editbox fields
                Exit Sub
            End If
        End If

    UserForm_Terminate
End Sub
Private Sub UserForm_Terminate()
    If Sheets("Users").Range("D2").Value <> True Then
        MsgBox "Login cancelled, goodbye!"
        doWorkbookClose
    End If
End Sub

'Module: ThisWorkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    doWorkbookClose
End Sub
Private Sub Workbook_Open()
    On Error Resume Next
    Sheets("Users").Range("D1").Value = 3
    With Sheets("SplashPage")
        .Visible = xlSheetVisible
        .Activate
    End With
    Sheets("Plan1").Visible = xlSheetVeryHidden
    Sheets("Users").Visible = xlSheetVeryHidden
    ThisWorkbook.Save
    frmLogin.Show
End Sub

'Module: Module1
Function getPassword(strVarib As String) As Variant
    Dim r As Long
    Dim sht As Worksheet
    Dim rng As Range

    On Error GoTo ErrorHandler

    Set sht = Sheets("Users")
    Set rng = sht.Range("A:A")

    r = WorksheetFunction.Match(strVarib, rng, 0)
    getPassword = sht.Cells(r, 2).Value
    Exit Function

ErrorHandler:
    getPassword = Empty
End Function
Sub doWorkbookClose()
    On Error Resume Next
    With Sheets("SplashPage")
        .Visible = xlSheetVisible
        .Activate
    End With
    Sheets("Plan1").Visible = xlSheetVeryHidden
    Sheets("Users").Visible = xlSheetVeryHidden
    ThisWorkbook.Save
End Sub

[開始問答]

路易斯,我在下面回答了您的修改。

問:Passwd做什么?

'Module: frmLogin
....
Passwd = getPassword(User1)

答:它獲取與User1值匹配的密碼值。 這是上下文的整個功能:

Function getPassword(strVarib As String) As Variant
    Dim r As Long
    Dim sht As Worksheet
    Dim rng As Range

    On Error GoTo ErrorHandler

    Set sht = Sheets("Users")
    Set rng = sht.Range("A:A")

    r = WorksheetFunction.Match(strVarib, rng, 0)
    getPassword = sht.Cells(r, 2).Value
Exit Function

ErrorHandler:
    getPassword = Empty

如果User1不存在,則WorksheetFunction.Match會引發錯誤,並且代碼執行將跳至ErrorHandler:

問:“空”是否表示該單元格不包含零或空格,而是完全空白?

答: Empty是指設置為默認值的Variant變量類型。 getPassword可以很容易地返回布爾False或整數0因為這些是這些類型的默認值。 實際上,在這里沒有嚴格要求將getPassword設置為任何東西……這只是我個人的做法。

由於IsEmpty(celFoo)是對單元格是否為空的有效測試,因此您可能需要返回False而不是Empty以避免產生歧義。

問:你能在下面詳細解釋這兩行嗎?

Set sht = Sheets("Users")
Set rng = sht.Range("A:A")

答:這只是習慣。 替代方法是消除這些變量分配並重寫此行:

r = WorksheetFunction.Match(strVarib, rng, 0)

如:

r = WorksheetFunction.Match(strVarib, Sheets("Users").Range("A:A"), 0)

鍵入起來比較麻煩。 尤其是如果我們要在同一例程中在該范圍內執行該表上的其他操作。 我們在下一個代碼塊中...

問:同樣重要的是,下面還要詳細解釋這三行[為什么是0?,(r,2)指向何處?]

r = WorksheetFunction.Match(strVarib, rng, 0)
getPassword = sht.Cells(r, 2).Value
Exit Function

答:要查看,工作表Users在A列中包含用戶ID,在B列中包含其密碼。工作表中的行數可以與用戶數一樣多。 rng是上面設置的A列。 0表示找到strVarib的完全匹配項,如果找不到則拋出錯誤。 -如果找到匹配項,則將r設置為行號,其中A列中的值等於我們的輸入參數strVarib -因此, sht.Cells(r, 2).Value是B列(第2列)中UserID的密碼值。

問:為什么需要呼叫啟動? 它包含什么?

答:您不一定需要一個,但是如果您確實想保護您的工作簿,這是一個好習慣。 假設其中包含您不希望未經授權的用戶查看的敏感信息。 至少您會:

  • 使用本機Excel功能對工作簿進行加密。
  • 使用本機功能通過密碼保護您的VBA項目。 這使精明的用戶無法閱讀您的代碼並使xlSheetVeryHidden表的UsersPlan1可見。
  • 現在,您不能同時隱藏工作簿中的所有工作表,在任何給定時間都至少需要一個可見的工作表...
  • ...因此,我創建了名為SplashPage的第三張表,其中不包含任何敏感信息。 這意味着我可以隱藏所有其他工作表,直到用戶在frmLogin輸入有效的UserID和密碼frmLogin

SplashPage可以包含您想要的任何內容。 您可以隨便叫它。 通常,我會說:

Welcome to the Enemies List Application!
Only authorized users may access this workbook.

If you're seeing this page and no login form is visible
it means you've disabled the macros in this workbook.
Please make sure macro security is set to "Medium"
then close Excel entirely, reopen this file
and select "Enable Macros" when prompted.

If you attempt to view or modify this file without proper 
authorization you will be added to the list herein.

-[Signed] Richard M. Nixon

真正安全的工作簿不會在隱藏的工作表中包含用戶和密碼。 實際上,我從來沒有這樣做。 我的大多數應用程序都是數據庫驅動的,我同時通過域和應用程序數據庫中的自定義表對用戶進行身份驗證。 這可以有效地阻止任何人使用它,除非他們在現場並連接到網絡。 當用戶關閉工作簿時,我通常還會刷新相關工作表中的所有數據,以使a)保持文件大小較小,b)防止敏感數據存儲在其中並移走。 但這超出了您問題的原始范圍。

“為什么[以下]是必要的? 正在保存什么? 目的?

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    ThisWorkbook.Save

答:有兩種關閉應用程序的方案:1)登錄嘗試失敗和2)完成更改的用戶成功登錄。

首先處理情況(2)。 我們想要在關閉之前隱藏所有敏感信息,以便下一個打開文件的人只能看到SplashPage和登錄表單。 我們知道用戶正在關閉工作簿,因為在ThisWorkbook模塊的BeforeClose事件腳本中有以下代碼:

'Module: ThisWorkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    doWorkbookClose
End Sub

它所做的只是在Module1調用此子例程:

Sub doWorkbookClose()
    On Error Resume Next
    With Sheets("SplashPage")
        .Visible = xlSheetVisible
        .Activate
    End With
    Sheets("Plan1").Visible = xlSheetVeryHidden
    Sheets("Users").Visible = xlSheetVeryHidden
    ThisWorkbook.Save
End Sub

由於我們的關閉例程會更改工作簿以隱藏敏感信息,因此需要保存這些更改。 如果沒有ThisWorkbook.Save ,Excel將提示用戶是否要保存“他們”的更改。 最好的情況是令人討厭,最糟糕的情況是令人困惑,因為大多數用戶在關閉之前已經按了“保存”。 並且,如果我們現在給他們選擇關閉而不保存的選項,那么我們冒着所有敏感工作表的風險,我們已經使xlVeryHidden對下一個用戶可見。 下一個用戶可能是一個壞人,他知道如何禁用宏(或者任何在Medium設置了宏安全性的用戶),這意味着以下代碼將無法運行:

Private Sub Workbook_Open()
    On Error Resume Next
    Sheets("Users").Range("D1").Value = 3
    With Sheets("SplashPage")
        .Visible = xlSheetVisible
        .Activate
    End With
    Sheets("Plan1").Visible = xlSheetVeryHidden
    Sheets("Users").Visible = xlSheetVeryHidden
    ThisWorkbook.Save
    frmLogin.Show
End Sub

這是我半偏執的自我,試圖確保下一個打開此文件的用戶看不到我不希望他們看到的東西。

請注意,這種安全性都不是防彈的。 它會鎖定您不希望使用的大多數普通Excel用戶,但是比我更了解VBA的人可能無法找到解決方法。

是的,那是一個邀請。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM