🔒 How to Build Password-Protected Excel Data Entry Forms With VBA

🔒 How to Build Password-Protected Excel Data Entry Forms With VBA

A finance coordinator needs colleagues to submit expense adjustments, but the underlying workbook contains formulas, reference tables, and prior records that nobody should casually overwrite. An open worksheet is convenient, yet it also invites accidental edits.

A VBA data entry form can give people a much safer path: they enter only the fields you intend, click Save, and VBA places the result in the correct location. Adding a password check can ensure that only approved users reach that form.

That sounds simple, but the details matter. A password prompt alone does not make an Excel file secure, and poorly designed VBA can expose data, leave sheets unprotected after an error, or save incomplete records.

This tutorial builds a practical pattern: authenticate a user, show a UserForm, validate entries, write to a protected worksheet, and close the process cleanly. It is a useful solution for controlled internal workflows. 🔐

🧭 1. Define What “Password-Protected” Means

Before writing code, separate access control from data protection. A password gate in VBA controls whether someone can use your form; it does not automatically prevent a determined person from opening or examining the workbook.

Excel offers several different protection features, each with a distinct purpose. Choosing the right one prevents a false sense of security.

  • Workbook file encryption: requires a password to open the file and is the appropriate choice for sensitive file contents.
  • Worksheet protection: limits actions such as editing locked cells, deleting rows, or changing formulas.
  • Workbook structure protection: limits actions such as adding, moving, hiding, or unhiding worksheets.
  • VBA form authentication: controls the workflow presented to ordinary users.

🎯 2. Choose a Suitable Use Case

This approach works well when a small group uses a shared template or an internal process workbook. Typical examples include issue logs, stock requests, service reports, training attendance, and monthly adjustments.

It is less suitable when you need organization-wide identity management, detailed audit trails, concurrent multi-user data entry, or strong security against malicious users. In those cases, a database, SharePoint list, Power Apps solution, or an approved business system may be more appropriate.

🛡️ 3. Understand VBA’s Security Limitations

Do not store highly sensitive information in a workbook merely because a VBA password form exists. VBA code is visible to users who can access the project unless additional measures are applied, and VBA project protection should not be treated as strong security.

A hard-coded password is especially weak because it exists in the code. For a modest internal control, it may be acceptable; for confidential material, use file encryption and follow your organization’s security policies.

The form password is a workflow barrier, not a replacement for secure file storage and permissions.

🗂️ 4. Plan the Workbook Layout First

Start with a clean workbook design. This makes the form code shorter, easier to maintain, and less likely to break when records grow.

Create a worksheet named Data. In row 1, add headers such as Record ID, Entry Date, Employee Name, Department, Request Type, Amount, and Notes.

Use one row per submitted record. Avoid merged cells, blank header names, and manually maintained ranges that stop after a fixed number of rows.

📋 5. Turn the Data Range Into an Excel Table

Select the headers and a few empty rows, then create a table from the Insert tab. Rename it tblEntries from the Table Design tab.

Tables expand automatically when VBA adds records. They also let you refer to meaningful column names instead of fragile cell addresses such as Cells(nextRow, 6).

In this tutorial, the Data sheet contains a table with these columns:

  • Record ID
  • Entry Date
  • Employee Name
  • Department
  • Request Type
  • Amount
  • Notes

🧰 6. Enable the Developer Tools

If the Developer tab is not visible, open Excel Options, choose Customize Ribbon, and enable Developer. This tab provides access to the Visual Basic Editor, macros, and form controls.

Save the workbook as an Excel Macro-Enabled Workbook with the .xlsm extension. A standard .xlsx file cannot retain VBA code.

🪟 7. Create the Login UserForm

Press Alt + F11 to open the Visual Basic Editor. Choose Insert, then UserForm. In the Properties window, rename the form frmLogin and set its Caption to Password Required.

Add the following controls and give them clear names. Meaningful names make code easier to read than default names such as TextBox1.

  • A Label explaining that authorization is required
  • A TextBox named txtPassword
  • A CommandButton named cmdLogin with Caption set to Sign In
  • A CommandButton named cmdCancel with Caption set to Cancel

🙈 8. Mask Password Characters

Select txtPassword in the UserForm designer. Set its PasswordChar property to *. The user’s typed characters will display as asterisks rather than readable text.

This protects against casual shoulder surfing. It does not encrypt the value in memory or make the password itself secure, so it should be treated as a usability feature.

🔑 9. Store the Demonstration Password Carefully

For a training workbook, place the expected password in a standard module as a private constant. Insert a module and rename it, if desired, to modSecurity.

The example below deliberately uses a placeholder. Replace it with an internal value only after considering who can access the workbook and its code.

Option Explicit

Private Const FORM_PASSWORD As String = "ReplaceThisPassword"

Public Function IsValidPassword(ByVal enteredPassword As String) As Boolean
    IsValidPassword = (enteredPassword = FORM_PASSWORD)
End Function

A private constant reduces accidental use elsewhere in the project, but it does not turn the value into a secret. Never describe this technique as encryption.

🚪 10. Code the Sign-In Button

Double-click the Sign In button on frmLogin and add the following procedure. It checks the entered text, opens the data entry form when the password matches, and clears the password field when it does not.

Private Sub cmdLogin_Click()
    If IsValidPassword(Me.txtPassword.Value) Then
        Me.txtPassword.Value = vbNullString
        Me.Hide
        frmEntry.Show
    Else
        MsgBox "The password is not correct.", vbExclamation, "Access denied"
        Me.txtPassword.Value = vbNullString
        Me.txtPassword.SetFocus
    End If
End Sub

Me.Hide keeps the login form loaded while the entry form is displayed. Clearing the field before hiding prevents the previous typed value from remaining in the control.

❎ 11. Give Users a Safe Way to Cancel

A cancel button should close the login form without opening anything else. Add this procedure to frmLogin.

Private Sub cmdCancel_Click()
    Me.txtPassword.Value = vbNullString
    Unload Me
End Sub

Cancellation is part of good interface design. Users should not have to force-close Excel simply because they opened a login form by mistake.

🧾 12. Build the Data Entry Form

Insert a second UserForm, rename it frmEntry, and set its Caption to New Data Entry. Add labels and controls corresponding to your table columns.

For this example, use a TextBox for dates, names, amounts, and notes; ComboBoxes for Department and Request Type; and buttons named cmdSave and cmdClose.

Suggested control names include txtEntryDate, txtEmployeeName, cboDepartment, cboRequestType, txtAmount, and txtNotes.

📦 13. Populate Controlled Drop-Down Lists

ComboBoxes reduce spelling variations and make later analysis more reliable. If every user types a department name freely, values such as “HR”, “Human Resources”, and “human resources” can become separate categories.

Add this initialization code to frmEntry. Adapt the listed values to your own process.

Private Sub UserForm_Initialize()
    Me.txtEntryDate.Value = Format(Date, "dd-mmm-yyyy")

    Me.cboDepartment.Clear
    Me.cboDepartment.List = Array("Finance", "Operations", "Sales", "Human Resources")

    Me.cboRequestType.Clear
    Me.cboRequestType.List = Array("Adjustment", "Request", "Correction")
End Sub

For a larger solution, load these lists from a controlled worksheet rather than embedding them in code. That lets an authorized workbook owner update options without editing VBA.

✅ 14. Validate Required Fields Before Saving

Validation is the form’s most valuable job. It stops incomplete or obviously invalid records before they reach the worksheet.

Create a function inside frmEntry that checks the fields your process requires.

Private Function FormIsValid() As Boolean
    If Not IsDate(Me.txtEntryDate.Value) Then
        MsgBox "Enter a valid date.", vbExclamation
        Me.txtEntryDate.SetFocus
        Exit Function
    End If

    If Trim(Me.txtEmployeeName.Value) = vbNullString Then
        MsgBox "Enter an employee name.", vbExclamation
        Me.txtEmployeeName.SetFocus
        Exit Function
    End If

    If Me.cboDepartment.Value = vbNullString Then
        MsgBox "Select a department.", vbExclamation
        Me.cboDepartment.SetFocus
        Exit Function
    End If

    FormIsValid = True
End Function

Keep validation messages specific. “Enter a valid date” tells the user what to fix; “Invalid input” does not.

💰 15. Validate Numeric Amounts Separately

Numbers deserve an additional check because text boxes accept almost any characters. Use IsNumeric before converting an amount with CDbl.

Private Function AmountIsValid() As Boolean
    If Not IsNumeric(Me.txtAmount.Value) Then
        MsgBox "Enter a numeric amount.", vbExclamation
        Me.txtAmount.SetFocus
        Exit Function
    End If

    If CDbl(Me.txtAmount.Value) < 0 Then
        MsgBox "The amount cannot be negative.", vbExclamation
        Me.txtAmount.SetFocus
        Exit Function
    End If

    AmountIsValid = True
End Function

Your own business rule may allow negative values, zero, or a maximum amount. Put that rule explicitly in code rather than assuming every numerical field follows the same logic.

🆔 16. Create a Simple Record Identifier

A record ID helps users and administrators discuss a specific submission. For an internal log, a time-based ID can be adequate, although it is not guaranteed to be unique if multiple users create entries at the same instant.

Add this function to a standard module:

Public Function NewRecordID() As String
    NewRecordID = "REC-" & Format(Now, "yyyymmdd-hhnnss")
End Function

For multi-user or high-volume systems, use an identifier generated by a database or another central system. Do not rely on a worksheet row number if records might be sorted or deleted.

🧱 17. Write Records Through the Table Object

Using a ListObject makes row insertion predictable. The next code adds a new table row and fills each named column, so it does not depend on the table beginning in a particular worksheet column.

Private Sub cmdSave_Click()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim newRow As ListRow

    If Not FormIsValid Then Exit Sub
    If Not AmountIsValid Then Exit Sub

    Set ws = ThisWorkbook.Worksheets("Data")
    Set tbl = ws.ListObjects("tblEntries")

    Set newRow = tbl.ListRows.Add

    With newRow.Range
        .Cells(1, tbl.ListColumns("Record ID").Index).Value = NewRecordID()
        .Cells(1, tbl.ListColumns("Entry Date").Index).Value = CDate(Me.txtEntryDate.Value)
        .Cells(1, tbl.ListColumns("Employee Name").Index).Value = Trim(Me.txtEmployeeName.Value)
        .Cells(1, tbl.ListColumns("Department").Index).Value = Me.cboDepartment.Value
        .Cells(1, tbl.ListColumns("Request Type").Index).Value = Me.cboRequestType.Value
        .Cells(1, tbl.ListColumns("Amount").Index).Value = CDbl(Me.txtAmount.Value)
        .Cells(1, tbl.ListColumns("Notes").Index).Value = Trim(Me.txtNotes.Value)
    End With

    MsgBox "Your entry has been saved.", vbInformation
    ClearEntryForm
End Sub

This code assumes the column headings match exactly. If you rename a table heading, update the matching VBA string as well.

🔒 18. Protect the Data Worksheet

Worksheet protection helps prevent users from casually changing the saved records, formulas, and layout. It should be applied after your table and formatting are ready.

The following procedure protects the Data sheet while allowing VBA operations to work during the current Excel session.

Public Sub ProtectDataSheet()
    With ThisWorkbook.Worksheets("Data")
        .Protect Password:="ReplaceThisSheetPassword", _
                 UserInterfaceOnly:=True, _
                 AllowFiltering:=True
    End With
End Sub

Important: the UserInterfaceOnly setting is not retained after the workbook closes. You must apply it again whenever the workbook opens.

🔄 19. Reapply Sheet Protection at Workbook Open

In the Visual Basic Editor, double-click ThisWorkbook and add the event procedure below. It runs when the workbook is opened and reapplies the user-interface-only protection setting.

Private Sub Workbook_Open()
    ProtectDataSheet
End Sub

If macros are disabled, this event cannot run. Design the workbook so that users understand macros must be enabled for the form workflow, but do not encourage users to enable macros in files they do not trust.

🧹 20. Clear the Form After a Successful Save

After saving, clear only the controls that should not carry forward. Usually the current date is useful as a default, while a person’s name or a monetary amount should be cleared.

Private Sub ClearEntryForm()
    Me.txtEntryDate.Value = Format(Date, "dd-mmm-yyyy")
    Me.txtEmployeeName.Value = vbNullString
    Me.cboDepartment.Value = vbNullString
    Me.cboRequestType.Value = vbNullString
    Me.txtAmount.Value = vbNullString
    Me.txtNotes.Value = vbNullString
    Me.txtEmployeeName.SetFocus
End Sub

Place this procedure in frmEntry. Clearing a form only after a confirmed save avoids losing information when validation fails.

🚶 21. Close the Entry Form Cleanly

Add a Close button so users can leave the form without adding another record. This is preferable to relying on the window close button alone, especially in a structured business template.

Private Sub cmdClose_Click()
    Unload Me
    Unload frmLogin
End Sub

Unloading both forms resets their controls. The next time the user opens the form, initialization runs again and the old login state is not reused.

▶️ 22. Create One Public Starting Macro

Users should have one obvious entry point. In a standard module, add a macro that displays the login form.

Public Sub StartDataEntry()
    frmLogin.Show
End Sub

Assign this macro to a button on a simple Home sheet. A clear label such as “Open Data Entry Form” is better than asking users to open the Macro dialog.

🏠 23. Design a Friendly Home Sheet

A Home sheet can explain the workbook’s purpose, give brief instructions, and contain the macro button. Keep it uncluttered so the intended workflow is obvious.

Consider including these items:

  • A short explanation of what the form records
  • A reminder to enable macros only if the workbook comes from a trusted source
  • An “Open Data Entry Form” button
  • Contact details or an internal process owner, where appropriate

Hide technical sheets only for convenience, not as a security measure. A hidden worksheet can be revealed by users with sufficient access and knowledge.

🧪 24. Test Normal and Error Paths

Testing should include more than one successful submission. Try each field empty, type letters into the amount field, enter an invalid date, cancel at login, and enter an incorrect password.

Also confirm that a valid save creates exactly one row and places each value under the correct header. Test after closing and reopening the workbook to confirm that protection is reapplied.

Useful test checklist

  • Correct password opens the entry form.
  • Incorrect password does not open the entry form.
  • Cancel returns the user to Excel without an error.
  • Required fields block saving when blank.
  • Each valid submission creates one complete table row.
  • Sheet protection does not block the intended VBA save operation.

⚠️ 25. Handle Errors Without Leaving a Weak State

A production workbook should anticipate unexpected errors, such as a renamed worksheet or a missing table. At minimum, show a useful message instead of allowing VBA to stop with a confusing error dialog.

Add an error handler to the save procedure before its main code:

Private Sub cmdSave_Click()
    On Error GoTo SaveError
    'Validation and save code goes here.
    Exit Sub

SaveError:
    MsgBox "The record could not be saved: " & Err.Description, _
           vbExclamation, "Save error"
End Sub

If your code explicitly unprotects sheets, use a cleanup path that attempts to restore protection even after an error. Better still, use UserInterfaceOnly when it fits the task and avoid repeatedly unprotecting a sheet.

👥 26. Consider Better Authentication Options

A single shared password provides limited accountability because everyone uses the same credential. If you need to know who submitted each record, capture a user identifier and consider how reliably it can be verified.

Windows usernames obtained through VBA can be convenient, but they are not a complete authentication system by themselves. For higher assurance, use an approved platform that integrates with your organization’s account management.

Approach Best for Main limitation
Hard-coded VBA password Simple internal workflow gate Password is stored in the workbook project
Protected worksheet Preventing routine edits Not a substitute for file encryption
Password to open Protecting workbook file contents Does not provide individual user identity
Central business application Stronger access control and auditing Requires a different platform and setup

📦 27. Distribute and Maintain the Workbook Responsibly

Keep a protected master copy and distribute controlled copies according to your team’s process. Document the sheet names, table name, column headings, and authorized maintenance steps so a future editor does not accidentally break the form.

When requirements change, update the table structure, UserForm controls, validation rules, and save code together. A data entry form is an interface to a data model; changing only one side causes errors.

🌟 28. Build Around the Core Principle

The strongest Excel form is not the one with the most code. It is the one that guides users into a narrow, understandable workflow, checks the data before saving, protects routine worksheet operations, and states its security limits honestly.

Use VBA password checks to improve internal process control, use worksheet protection to reduce accidental changes, and use proper file encryption and organizational access controls when confidentiality matters.

A password-protected VBA form should make correct data entry easier while never pretending to provide more security than Excel can deliver. 🔒✅📊