Excel

Excel VBAで複数人で別々のID、パスワードでブックを開くようにしてみた

Excelの便利な機能の1つ、パスワード。

このパスワード機能は、読み取り用パスワード設定、書き込み用パスワード設定、読み取り専用推奨にしたり、パスワードを忘れても大丈夫なようにバックアップ機能があったり、めちゃくちゃ便利な機能です。

でも、複数人で使う場合は、全員に同じパスワードを教えなければいけません。

「システムを使う時のように、複数人で全員違うID、パスワードでブックを開けるようにしたいな」と思ったので、VBAを駆使して作ってみました。

投稿者「みか」自己紹介

  • パソコンとデータベースが大好き
  • 自社でネットワーク・システム・機器管理、Webサイト構築
  • 自社向けのシステムをMicrosoft AccessやPHPで多数構築
  • Excelでの作業はVBAを使って効率化
  • ロックバンド「VARS」でベース担当
  • 「VARS」のWebサイト、ブログも構築
  • 「VARS」のライブを観に来てね!https://vasofatum.jp/live/

シートを作る

ユーザー情報保存用シートを作る

ユーザー情報(ID、パスワード)を保存するシートを作成します。シート名は「user」にしました。

ユーザー情報保存用シート「user」は、パスワード付でシートの保護をかけ、シートを非表示にします。

パスワードは管理者(admin)のパスワードにしました。

そして、「user」シートを再表示されて、ID、パスワードが見られないように、ロックされたセルは選択不可になるようにするのと、背景色と文字の色を白にしました。

ここまですると、管理者のパスワードがバレない限り、ID、パスワードは閲覧できません。

ブック起動時のシートを作る

ブックを開いたと同時にログイン用のフォームを表示し、その間は何も入力していない真っ白なシートを表示しておくようにします。シート名は「start」にしました。

ログイン後に表示するシートを作る

ログインに成功したら、表示するシートを作成します。シート名は「メニュー」にしました。

フォームを作る

ログイン用フォームを作る

ログイン用のID、パスワードを入力するフォームを作ります。フォーム名は「F_login」にしました。

ユーザーID、パスワードを入力するテキストボックスとログイン用ボタンを配置しています。

VBA

標準モジュール

標準モジュールを追加し、色々マクロを書き込みます。

ユーザー情報取得するプロシージャ

user」シートから入力されたユーザーIDとヒットした場合、パスワードを返すプロシージャを書きます。

プロシージャ名は「Get_UserInfo」にしました。

Function Get_UserInfo(user_id As String) As Variant
    
    '検索結果用
        '0 = パスワード
        '1 = ヒットしたセル
    Dim result_array(1) As Variant
    
    'ユーザーを探す
    Set result_array(1) = ThisWorkbook.Worksheets("user").Range("A:A").Find(user_id, LookAt:=xlWhole, MatchCase:=True)
    
    'ヒットした場合、パスワードを返す
    If Not result_array(1) Is Nothing Then
        result_array(0) = result_array(1).Offset(0, 1).Value
    'ヒットしなかった場合
    Else
        result_array(0) = ""
    End If
    
    Get_UserInfo = result_array
    
End Function

「user」シートを再度保護するプロシージャ

user」シートを起動時やユーザー情報を登録した後など再度保護するようにプロシージャを書きます。

保護用パスワードは「user」シートに記録されている管理者「admin」のパスワードを利用します。

プロシージャ名は「shUser_ReProtect」にしました。

Sub shUser_ReProtect()

    '管理者(admin)パスワード用
    Dim admin_info As Variant
    
    '管理者(admin)パスワード取得
    admin_info = Get_UserInfo("admin")

    'シート保護解除
    If admin_info(0) <> "" Then
        ThisWorkbook.Worksheets("user").Protect Password:=admin_info(0), UserInterfaceOnly:=True
    End If

End Sub

ログイン中かどうかチェックするプロシージャ

ログイン後は「user」シートのC列に「〇」を入力しておき、誰かログイン中かを判定します。誰かがログイン中かを取得するプロシージャを書きます。

プロシージャ名は「User_LoginCheck」にしました。

Function User_LoginCheck() As Boolean
    'ログインチェック
    User_LoginCheck = False
    '「user」シートのC列に○があるか
    If WorksheetFunction.CountIf(ThisWorkbook.Worksheets("user").Range("C:C"), "○") > 0 Then
        User_LoginCheck = True
    End If
End Function

「Thisworkbook」VBA

「Thisworkbook」にブック起動時のマクロを書きます。

ブック起動に動作させる

  1. user」シートを再度保護
  2. user」シートのC列の値を消去
  3. user」シートの背景色を透明(ユーザー情報が見えないように)
  4. user」シートの文字を白(ユーザー情報が見えないように)
  5. user」シートのA1セルをアクティブ(ユーザー情報登録後にパスワード等がアクティブになっていてもいいように)
  6. user」シート非表示
  7. ログイン用フォームを開く

Private Sub Workbook_Open()
    'このブック操作
    With ThisWorkbook
        '「user」シート操作
        With .Worksheets("user")
            'シート再度保護
            shUser_ReProtect
            'ログイン状態列消去
            .Range("C:C").Value = ""
            '背景色を透明
            .Cells.Interior.ColorIndex = 0
            '文字の色を白に
            .Cells.Font.Color = RGB(255, 255, 255)
            'A1をselect
            .Activate
            .Range("A1").Select
            'シート非表示
            .Visible = False
        End With
        '「start」シートアクティブ
        .Worksheets("start").Activate
    End With
    
    'ログインフォームを開く
    F_Login.Show
End Sub

ブックを閉じる時に動作させる

ブックを起動した時にログイン用フォームを表示しますが、真っ白なシートを表示させるために「start」シートをアクティブにし、保存した後に閉じます。

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    'このブック操作
    With ThisWorkbook
        '「start」シートをアクティブ
        .Worksheets("start").Activate
        '上書き保存
        .Save
    End With
End Sub

ログインフォームの動作

ログインボタンクリック時の動作

入力されたユーザーID、パスワードが「user」シートにあるかどうかチェックして、ある場合は、「user」シートのC列に「〇」入力し、「メニュー」シートをアクティブにします。

Option Explicit

'このブック用
Dim wb As Workbook

Private Sub LoginButton_Click()
    If user_id_txt.Value = "" Or password_txt.Value = "" Then
        MsgBox "ユーザーID、パスワード未入力"
        Exit Sub
    End If
    
    '検索結果用
    Dim get_user As Variant
    
    'フォームで入力されたユーザーID用
    Dim user_txt As String
    'フォームで入力されたパスワード用
    Dim pass_txt As String
    '登録されているパスワード用
    Dim pass_txt_touroku As String
    
    'このブック
    Set wb = ThisWorkbook
    
    'フォームで入力されたユーザーIDを代入
    user_txt = user_id_txt.Value
    'フォームで入力されたパスワードを代入
    pass_txt = password_txt.Value

    'ユーザー情報取得
    get_user = Get_UserInfo(user_txt)

    'ユーザー情報がない場合
    If get_user(1) Is Nothing Then
        MsgBox "ユーザーIDまたはパスワードが違います"
        user_id_txt.SetFocus
    'ユーザー情報がある場合
    Else
        'パスワードが一致した場合
        If pass_txt = get_user(0) Then
            '「user」シート再度保護
            shUser_ReProtect
            'ログイン者に○
            get_user(1).Offset(0, 2).Value = "〇"
            '「メニュー」シートをアクティブ
            wb.Worksheets("メニュー").Activate
            'ログインフォームを閉じる
            F_Login.Hide
        'パスワードが一致しない場合
        Else
            MsgBox "ユーザーIDまたはパスワードが違います"
            user_id_txt.SetFocus
        End If
    End If

End Sub

フォームを閉じる時の動作

フォームを閉じる時に「user」シートのC列に「〇」がなかったら(ログインしていなかったら)ブック自体を閉じるようにします。

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Dim user_login As Boolean
    
    'このブック
    Set wb = ThisWorkbook
    
    'ログインしていなかったらブックを閉じる
    user_login = User_LoginCheck
    If user_login = False Then
        wb.Close savechanges:=False
    End If
End Sub

これで完成です!

このブックを作っている間に、パスワードを忘れたりして、2度と開けないようになったりしたので、完成するまでは、フォームを閉じる時の動作の10行目はコメントにしておくことをオススメします。

-Excel
-, , , ,