[엑셀로그인시스템] 자동화 서식 만들기
사용자별 접근권한 제어 및 로그인기록 관리가 가능한 나만의 시스템 만들기
이 강의에서는 엑셀 매크로(VBA)를 활용해 사용자별 접근 권한을 제어하고 로그인 기록까지 관리할 수 있는 로그인 시스템을 직접 구축하는 방법을 다룹니다. 여러 부서가 하나의 파일을 공유하는 환경에서 시트 보호나 통합문서 보호만으로는 해결되지 않는 권한 분리 문제를, 로그인 유저폼 설계와 이벤트 명령문, 매크로 프로젝트 보안 설정까지 단계별로 알아봅니다.
실습자료를 준비했어요
수업에서 사용한 예제 파일과 보충 자료를 한 곳에 정리했습니다!👇
강의 요약
엑셀 파일 보안에 가장 보편적으로 사용되는 기능은 엑셀이 기본으로 제공하는 '통합문서 보호' 와 '시트 보호' 입니다. (필요에 따라 DRM 등 별도의 문서 보안 프로그램이 함께 사용되기도 합니다.) 다만 이 두 기능은 통합문서나 시트를 선택적으로 보호하지 못하고, 파일 또는 시트 전체를 일괄적으로 한 번에 암호화한다는 한계가 있습니다.
따라서 사용자별 또는 직급별로 파일을 다르게 보호해야 한다면 통합문서를 여러 개로 나누거나 시트마다 다른 암호를 설정하는 번거로운 절차가 필요했습니다. 이번 강의에서는 엑셀 매크로를 활용하여 사용자별 접근 권한을 제어하고 로그인 기록까지 관리할 수 있는 엑셀 로그인 시스템 구축 방법을 단계별로 알아봅니다.
엑셀은 기본적으로 파일 보안에 특화된 프로그램은 아닙니다. 파일의 원본을 공유해야 하는 엑셀의 특성상, 100% 완벽하게 파일을 보안하는 것은 현실적으로 불가능합니다. 보안 강도를 비교해 보면 엑셀 시트 보호 < 통합문서 보호 < 매크로 보호 < DRM(외부 보안 프로그램) 순으로 단계가 올라간다고 볼 수 있습니다.
따라서 아래와 같은 환경에서 엑셀 작업이나 업무 공유가 자주 발생한다면, 매크로를 활용한 로그인 시스템 도입을 적극적으로 검토할 수 있습니다.
- 하나의 파일로 여러 부서가 자료를 공유해야 하지만, 복잡한 함수나 기능이 포함된 엑셀 문서를 다뤄야 하는 경우
- 파일 수정이 1시간 이상 단위로 발생하며, 한 파일에 동시 접속이 거의 발생하지 않는 경우
- 사내 네트워크 드라이브에서 엑셀 파일을 공유하는 경우 (또는 드롭박스, 구글드라이브 등 클라우드 환경에서 공유하는 경우)
- 동일한 형식의 파일을 여러 부서나 매장으로부터 주기적으로 취합해야 하는 경우
frmLogin (로그인 유저폼) 명령문
Private Sub txtID_Enter() If Me.txtID.Value = "직원번호를 입력하세요" Then Me.txtID.Value = "" Me.txtID.ForeColor = RGB(51, 51, 51) ' HEX: #33333 End If End Sub Private Sub txtID_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.txtID.Value = "" Then Me.txtID.Value = "직원번호를 입력하세요" Me.txtID.ForeColor = RGB(128, 128, 128) ' HEX: #808080 End If End Sub Private Sub txtPW_Enter() If Me.txtPW.Value = "비밀번호를 입력하세요" Then Me.txtPW.Value = "" Me.txtPW.ForeColor = RGB(51, 51, 51) ' HEX: #33333 Me.txtPW.PasswordChar = "*" End If End Sub Private Sub txtPW_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.txtPW.Value = "" Then Me.txtPW.Value = "비밀번호를 입력하세요" Me.txtPW.ForeColor = RGB(128, 128, 128) ' HEX: #808080 Me.txtPW.PasswordChar = "" End If End Sub Private Sub btnLogin_Click() Login_Verification End Sub Sub Login_Verification() ' 아이디와 비밀번호가 사용자정보시트에 존재하는지 확인 (일치하는지) Dim EndRow As Long '마지막 행 Dim i As Long 'For문 변수 ' 오류처리 If Me.txtID.Value = "직원번호를 입력하세요" Then MsgBox "직원번호를 입력해주세요.": Exit Sub If Me.txtPW.Value = "비밀번호를 입력하세요" Then MsgBox "비밀번호를 입력해주세요.": Exit Sub ' 직원번호와 비밀번호 확인 With shtUser EndRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'https://www.oppadu.com/엑셀-vba-마지막-셀-찾기-마지막-행-찾기/ For i = 2 To EndRow If .Cells(i, 1).Value = Me.txtID.Value And .Cells(i, 2) = Me.txtPW.Value Then '로그인 성공 Login_Success MsgBox .Cells(i, 3).Value & "님 안녕하세요. 환영합니다." & vbNewLine & _ "접속시간 :" & Format(Now(), "yyyy년 mm월 dd일 hh시 mm분") Unload Me Exit Sub End If Next '-------------------- Attempt = Attempt - 1 If Attempt > 0 Then '로그인 실패 MsgBox "존재하지 않는 직원번호 또는 비밀번호가 잘못되었습니다." & vbNewLine & _ "남은 횟수 : " & Attempt & "회" Else MsgBox "직원번호 또는 비밀번호가 3회이상 잘못되어 프로그램을 종료합니다." blnClose = True '강제종료 CloseWB False End If End With End Sub Sub Login_Success() '변수설정 Dim WS As Worksheet Dim EndRow As Long ' 각 시트를 돌아가면서 시트를 보임/숨김 For Each WS In ThisWorkbook.Worksheets Select Case WS.Name '관라자일 경우 -> 사용자정보 시트를 표시 Case "로그인기록", "사용자정보" If Me.txtID.Value = "admin" Then WS.Visible = xlSheetVisible '로그인 시트는 숨김 Case "로그인" WS.Visible = xlSheetVeryHidden '나머지 시트는 표시 Case Else WS.Visible = xlSheetVisible End Select Next '로그인 기록시트에 기록 추가 With shtHistory EndRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 .Cells(EndRow, 1) = Now .Cells(EndRow, 2) = Me.txtID.Value End With Attempt = 3 End Sub
모듈에 추가된 명령문
Public blnClose As Boolean Public Attempt As Long Function CloseWB(Optional SaveChanges As Boolean = True, Optional DisplayAlert As Boolean = False) As Boolean Dim WB As Workbook Dim i As Long Dim vbYN As VbMsgBoxResult Application.DisplayAlerts = False Logout If blnClose = False Then If DisplayAlert = True Then vbYN = MsgBox("'" & ThisWorkbook.Name & "' 의 변경내용을 저장하시겠습니까?", vbYesNoCancel) If vbYN = vbNo Then SaveChanges = False: blnClose = True If vbYN = vbYes Then SaveChanges = True: blnClose = True If vbYN = vbCancel Then blnClose = False: GoTo Finally End If For Each WB In Application.Workbooks If WB.Name <> "PERSONAL.XLSB" Then i = i + 1 Next If i = 1 Then If SaveChanges = True Then ThisWorkbook.Save Application.EnableEvents = False Application.Quit Else ThisWorkbook.Saved = True Application.EnableEvents = False Application.Quit End If Else If SaveChanges = True Then ThisWorkbook.Save ThisWorkbook.Close Else ThisWorkbook.Saved = True ThisWorkbook.Close End If End If End If CloseWB = False Application.DisplayAlerts = True Exit Function Finally: Application.DisplayAlerts = True CloseWB = True End Function Sub Logout() Dim WS As Worksheet shtLogin.Visible = xlSheetVisible For Each WS In ThisWorkbook.Worksheets If WS.Name <> "로그인" Then WS.Visible = xlSheetVeryHidden Next End Sub Sub show_frmLogin() frmLogin.Show End Sub
현재_통합_문서 모듈에 추가된 명령문
Private Sub Workbook_BeforeClose(Cancel As Boolean) Cancel = CloseWB(, True) End Sub Private Sub Workbook_Open() Attempt = 3 show_frmLogin End Sub
기존 사용 중인 통합문서의 시트를 로그인 완성파일로 옮기는 방법
- 기존에 사용 중인 통합문서에서 옮길 시트를 선택합니다.

- 선택한 시트를 우클릭한 뒤 '이동/복사'를 클릭합니다.

- '로그인 완성' 파일을 대상으로 선택한 뒤 '복사본 만들기' 체크박스를 활성화합니다. '확인' 버튼을 누르면 시트 복사가 완료됩니다.

로그인 유저폼에 회사 로고를 추가하는 방법
- 개발도구 - Visual Basic 을 클릭하거나 단축키 Alt + F11 을 눌러 매크로 편집기로 이동합니다. 개발도구 탭이 보이지 않는다면 아래 포스트를 참고하여 엑셀 개발도구를 먼저 활성화합니다.
- 프로젝트 창에서 '폼' - 'frmLogin' 을 더블클릭합니다.

- 유저폼 안의 오빠두 로고를 클릭한 뒤, 속성 창에서 Picture - '...' 버튼을 클릭합니다.

- 회사 로고가 저장된 그림 파일을 선택하면 회사 로고 삽입이 완료됩니다.

로그인 시트에 로그인버튼을 추가하는 방법
- 로그인 시트로 이동한 뒤 '삽입' - '도형' 메뉴에서 사각형 도형을 삽입합니다.

- 도형의 색상과 크기를 적절히 꾸민 뒤, 도형을 우클릭하여 '매크로 지정'을 선택합니다.

- 매크로 목록에서 show_frmLogin 을 선택한 뒤 '확인' 버튼을 눌러 로그인 버튼 추가를 완료합니다.

엑셀 로그인 유저폼의 구성

| 이름 | 설명 |
| txtID [텍스트상자] |
직원번호를 입력하는 텍스트상자입니다. 아이디는 보통 영문을 사용하므로 IMEMode 속성을 'frmIMEModeAlpha' 로 설정합니다. 한글 아이디를 사용해야 한다면 'frmIMEModeHangul' 을 선택합니다. |
| txtPW [텍스트상자] |
비밀번호를 입력하는 텍스트상자입니다. 비밀번호는 반드시 IMEMode 속성을 'frmIMEModeAlpha' 로 설정합니다. 또한 비밀번호는 화면에 노출되지 않아야 하므로 PasswordChar 속성에 "*" 을 입력합니다. |
| btnLogin [버튼] |
직원번호와 비밀번호 입력 후 로그인 동작을 실행하기 위한 버튼입니다. |
로그인 유저폼 동작 설정
1. 아이디 및 비밀번호를 입력할 경우
아이디 입력 동작을 처리하기 위해 txtID 에 포커스가 들어오거나 빠져나갈 때 실행되는 명령문을 추가합니다.
' --------------------------------------------------------- ' frmLogin 유저폼 모듈에 추가합니다. ' --------------------------------------------------------- Private Sub txtID_Enter() If Me.txtID.Value = "직원번호를 입력하세요" Then Me.txtID.Value = "" Me.txtID.ForeColor = RGB(51, 51, 51) ' HEX: #33333 End If End Sub Private Sub txtID_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.txtID.Value = "" Then Me.txtID.Value = "직원번호를 입력하세요" Me.txtID.ForeColor = RGB(128, 128, 128) ' HEX: #808080 End If End Sub
비밀번호 입력 동작도 동일한 방식으로, txtPW 에 포커스가 들어오거나 빠져나갈 때 실행되는 명령문을 추가합니다.
' --------------------------------------------------------- ' frmLogin 유저폼 모듈에 추가합니다. ' --------------------------------------------------------- Private Sub txtPW_Enter() If Me.txtPW.Value = "비밀번호를 입력하세요" Then Me.txtPW.Value = "" Me.txtPW.ForeColor = RGB(51, 51, 51) ' HEX: #33333 Me.txtPW.PasswordChar = "*" End If End Sub Private Sub txtPW_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.txtPW.Value = "" Then Me.txtPW.Value = "비밀번호를 입력하세요" Me.txtPW.ForeColor = RGB(128, 128, 128) ' HEX: #808080 Me.txtPW.PasswordChar = "" End If End Sub
2. 로그인 버튼을 클릭할 경우
로그인 버튼을 클릭하면 아래 조건을 차례로 확인하여 로그인 성공 또는 실패를 구분한 뒤 각각의 동작을 수행합니다.
- txtID 또는 txtPW 값이 기본값 그대로일 경우 "아이디 또는 비밀번호를 입력하세요" 안내 메시지를 출력합니다.
- 입력된 직원번호와 비밀번호가 사용자정보 시트의 정보와 일치하는지 확인합니다. 일치하면 -> 로그인 성공으로 처리합니다.
- 일치하지 않으면 로그인 시도 횟수를 확인하여 3회 미만일 때 -> "아이디 또는 비밀번호를 확인하세요" 안내 메시지를 출력합니다.
- 로그인 시도 횟수가 0 이 되면 -> 파일을 강제 종료합니다.
' --------------------------------------------------------- ' frmLogin 유저폼 모듈에 추가합니다. ' --------------------------------------------------------- Private Sub btnLogin_Click() Login_Verification End Sub Sub Login_Verification() ' 아이디와 비밀번호가 사용자정보시트에 존재하는지 확인 (일치하는지) Dim EndRow As Long '마지막 행 Dim i As Long 'For문 변수 ' 오류처리 If Me.txtID.Value = "직원번호를 입력하세요" Then MsgBox "직원번호를 입력해주세요.": Exit Sub If Me.txtPW.Value = "비밀번호를 입력하세요" Then MsgBox "비밀번호를 입력해주세요.": Exit Sub ' 직원번호와 비밀번호 확인 With shtUser EndRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'https://www.oppadu.com/엑셀-vba-마지막-셀-찾기-마지막-행-찾기/ For i = 2 To EndRow If .Cells(i, 1).Value = Me.txtID.Value And .Cells(i, 2) = Me.txtPW.Value Then '로그인 성공 Login_Success MsgBox .Cells(i, 3).Value & "님 안녕하세요. 환영합니다." & vbNewLine & _ "접속시간 :" & Format(Now(), "yyyy년 mm월 dd일 hh시 mm분") Unload Me Exit Sub End If Next '-------------------- Attempt = Attempt - 1 If Attempt > 0 Then '로그인 실패 MsgBox "존재하지 않는 직원번호 또는 비밀번호가 잘못되었습니다." & vbNewLine & _ "남은 횟수 : " & Attempt & "회" Else MsgBox "직원번호 또는 비밀번호가 3회이상 잘못되어 프로그램을 종료합니다." blnClose = True '강제종료 CloseWB False End If End With End Sub
3. 로그인을 성공했을 경우
입력한 아이디와 비밀번호가 일치하여 로그인에 성공하면, '로그인' 시트는 자동으로 숨김 처리합니다. 이어서 각 사용자 정보에 따라 등록된 시트를 출력합니다.
' --------------------------------------------------------- ' frmLogin 유저폼 모듈에 추가합니다. ' --------------------------------------------------------- Sub Login_Success() '변수설정 Dim WS As Worksheet Dim EndRow As Long ' 각 시트를 돌아가면서 시트를 보임/숨김 For Each WS In ThisWorkbook.Worksheets Select Case WS.Name '관라자일 경우 -> 사용자정보 시트를 표시 Case "로그인기록", "사용자정보" If Me.txtID.Value = "admin" Then WS.Visible = xlSheetVisible '로그인 시트는 숨김 Case "로그인" WS.Visible = xlSheetVeryHidden '나머지 시트는 표시 Case Else WS.Visible = xlSheetVisible End Select Next '로그인 기록시트에 기록 추가 With shtHistory EndRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 .Cells(EndRow, 1) = Now .Cells(EndRow, 2) = Me.txtID.Value End With Attempt = 3 End Sub ' --------------------------------------------------------- ' 일반 모듈에 추가합니다. ' --------------------------------------------------------- Public Attempt As Long
4. 파일을 종료할 경우 (로그아웃 할 경우)
사용자가 파일을 종료하거나 로그아웃할 때, 처음 파일을 실행했을 때와 동일하게 '로그인' 시트만 목록에 보이도록 명령문을 추가합니다. 그래야 이후 다른 사용자가 파일을 실행하더라도 로그인 시트만 목록에 표시됩니다.
' --------------------------------------------------------- ' 현재_통합_문서 모듈에 추가합니다. ' --------------------------------------------------------- Private Sub Workbook_BeforeClose(Cancel As Boolean) Cancel = CloseWB(, True) End Sub ' --------------------------------------------------------- ' 일반 모듈에 추가합니다. ' --------------------------------------------------------- Public blnClose As Boolean Function CloseWB(Optional SaveChanges As Boolean = True, Optional DisplayAlert As Boolean = False) As Boolean Dim WB As Workbook Dim i As Long Dim vbYN As VbMsgBoxResult Application.DisplayAlerts = False Logout If blnClose = False Then If DisplayAlert = True Then vbYN = MsgBox("'" & ThisWorkbook.Name & "' 의 변경내용을 저장하시겠습니까?", vbYesNoCancel) If vbYN = vbNo Then SaveChanges = False: blnClose = True If vbYN = vbYes Then SaveChanges = True: blnClose = True If vbYN = vbCancel Then blnClose = False: GoTo Finally End If For Each WB In Application.Workbooks If WB.Name <> "PERSONAL.XLSB" Then i = i + 1 Next If i = 1 Then If SaveChanges = True Then ThisWorkbook.Save Application.EnableEvents = False Application.Quit Else ThisWorkbook.Saved = True Application.EnableEvents = False Application.Quit End If Else If SaveChanges = True Then ThisWorkbook.Save ThisWorkbook.Close Else ThisWorkbook.Saved = True ThisWorkbook.Close End If End If End If CloseWB = False Application.DisplayAlerts = True Exit Function Finally: Application.DisplayAlerts = True CloseWB = True End Function Sub Logout() Dim WS As Worksheet shtLogin.Visible = xlSheetVisible For Each WS In ThisWorkbook.Worksheets If WS.Name <> "로그인" Then WS.Visible = xlSheetVeryHidden Next End Sub
5. 파일을 실행할 경우
파일을 실행할 때 로그인 유저폼이 자동으로 표시되고 로그인 시도 횟수를 3 으로 초기화하도록 명령문을 추가합니다.
' --------------------------------------------------------- ' 현재_통합_문서 모듈에 추가합니다. ' --------------------------------------------------------- Private Sub Workbook_Open() Attempt = 3 show_frmLogin End Sub ' --------------------------------------------------------- ' 일반 모듈에 추가합니다. ' --------------------------------------------------------- Sub show_frmLogin() frmLogin.Show End Sub
완성된 파일 저장 및 매크로 보안설정
엑셀 로그인 시스템 파일 작성을 마쳤다면, 파일을 저장하기 전에 작성한 매크로를 암호화합니다.
- 매크로 편집기로 이동한 뒤 'VBAProject' 를 우클릭하여 'VBAProject 속성' 으로 이동합니다.

- '보호' 탭으로 이동한 뒤 '읽기전용으로 프로젝트 잠금' 체크박스를 활성화합니다. 이어서 사용할 암호를 입력하고 '확인' 버튼을 클릭합니다.

- 매크로 편집기 화면 좌측 상단의 '저장' 버튼을 클릭하여 파일을 저장합니다.

- 만약 현재 사용 중인 파일이 '일반 통합문서' 형식이라면, "다음 기능은 매크로 제외 통합 문서에 저장할 수 없습니다." 라는 안내 메시지가 표시됩니다.

- 이때는 '아니오' 버튼을 클릭한 뒤 파일 형식을 '매크로 사용 통합문서' 로 선택하여 파일 저장을 마무리합니다.

자주묻는질문
Q1. 파일을 직접 저장한 뒤 다시 실행하면 로그인 시트가 기본으로 표시되지 않습니다.
엑셀은 통합문서 데이터와 함께 시트의 레이아웃 상태도 함께 저장합니다. 따라서 파일을 직접 저장하면 모든 시트가 보이는 상태로 저장되고, 이후 다시 실행하면 로그인 시트가 아니라 마지막으로 저장된 시점의 시트 레이아웃이 그대로 표시됩니다.
이 문제는 아래 명령문을 현재_통합_문서 모듈에 추가하여 해결할 수 있습니다.
아래 명령문을 추가하면, 파일을 저장하는 순간 자동으로 로그아웃 상태로 저장한 뒤 사용자가 보고 있던 시트 레이아웃을 다시 복원해 줍니다.
'아래 명령문을 현재_통합_문서 모듈에 추가합니다. Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Dim DictWS As Object Dim WS As Worksheet Application.ScreenUpdating = False Set DictWS = CreateObject("Scripting.Dictionary") For Each WS In ThisWorkbook.Worksheets DictWS.Add WS.Name, WS.Visible Next Logout ThisWorkbook.Save For Each WS In ThisWorkbook.Worksheets WS.Visible = DictWS(WS.Name) Next Application.ScreenUpdating = True Cancel = True End Sub
명령문의
에 마우스커서를 놓은 뒤, F9키로 중단점을 설정해주세요.
그리고 F8키를 누르면서 각 단계별로 디버깅을 해보시겠어요?
종료가 되지 않는다면 CloseWB 명령문 어딘가에서 IF문을 건너뛴다는 이야기인데, 확인이 필요합니다 ^^ 디버깅 후 좀 더 자세히 설명해주시면 확인 후 답변 드리겠습니다.
감사합니다.