[액셀 VBA] 자동화 - 직책별로 뽑은 직원들을 폼에 연동하여 수정 조회 하기
마소 FORMS를 활용한 자동 출퇴근 기록, 근태, 급여산정 등등 프로젝트의 일부입니다.
오늘의 주제는 저번에 DB로 직책별로 뽑아낸 DB를 활용하여 리스트박스에 해당 직원들만 넣고, 수정 조회하는 과정입니다.
- 직원들 DB 시트가 있고, 1행에는 필드명이 있습니다. 이 필드명과 나중에 폼에 있는 컨트롤들을 같게 해 줄 것입니다.
2. 이것을 가지고 직원들을 직책별로 뽑아냅니다. 이 부분은 어떻게 구현했는지 아래 게시글을 보시면 찾으실 수 있을 것입니다.
아래 사진에서 각 테이블마다 표 이름을 "CASHIER", "DINING", "DISHWASHER", "KITCHEN" .. 이런식으로 이름 정의를 합니다.
3. 직책을 참조할 수 있는 테이블을 하나 만들고 이름을 "POSITION"으로 정의합니다.
4. 폼에 컴보박스의 속성에 있는 RowSource의 값을 POSITION으로 설정합니다.
그러면 아래의 그림 같이 해당 직책들이 나올 것입니다.
5. 위의 그림에서 직책을 선택하면 바로 밑에 있는 리스트 박스에 해당 직책을 가진 직원 목록이 뜨도록 해야 겠지요.
Private Sub cboPos_Change() Me.lboxEmployees.RowSource = "[" & wbYS.Name & "]SCHEMA!" & Me.cboPos.Value End Sub
a. "cboPos"는 포지션을 담아 두기 위한 콤보박스 컨트롤 입니다.
b. "lboxEmployees"는 해당 직원 명단을 담아 두기 위한 리스트박스 컨트롤입니다.
c. "[" & wbYS.Name & "]SCHEMA!" : 워크북이 여러개 실행 되고 있는 중이기에 명확하게 "[워크북 이름]워크시트 이름!"을 앞에 붙여 줍니다. 실제 시트의 이름은 SCHEMA이고 이 뒤에 선택한 콤보박스의 값 "Me.cboPos.Value"값을 붙여 주면 리스트 박스에 해당 직원들의 이름를 아래의 그림같이 가져와 붙여 줍니다.
6. 위 그림의 리스트박스에서 직원을 선택하면 이 직원들의 정보를 가져오는데
a. 직원시트에서 해당 직원을 찾아 폼에 뿌려주기 ▶ 조회만 가능, 업데이트 기능을 따로 넣어 주어야 함
b. 직원시트에 있는 각각의 셀의 주소를 ControlSource에 연동시키기 ▶ 조회 및 바로 수정 가능
목적에 따라 a, b 중에 선택하시면 됩니다.
7. 위의 6.b.의 방식, ControlSource로 연동하는 방법의 코딩을 보여 드리겠습니다.
a. 먼저, 폼에 있는 TextBox의 이름을 필드명과 동일하게 합니다. 가령 직원 ID 필드명을 여기서는 "EID"라 명명했습니다.
그럼 폼에 있는 TextBox 중 직원의 ID를 보여줄 녀석의 이름을 EID라고 하면 됩니다. 아래 그림 참조
b. 모든 컨트롤의 이름을 필드명과 같게 변경합니다.
c. 리스트박스에서 선택시 직원의 아이디를 추출합니다.
리스트박스에서 보이는 값은 이름 뿐이지만 ColumnCount=3, BoundColumn=1로
그리고 이름만 보이게 ColumnWith = "0pt; 120pt; 0pt" 이렇게 세팅이 되어 있습니다.
위에 직책별 명단의 필드를 보시면 "EID", "FirstName", "SRATE" 이렇게 세 개의 값들이 있습니다.
따라서 직원을 선택하면 BoundColumn=1 이기 때문에 아래코드 Me.lboxEmployees.Value에 직원 ID인 EID값이 넘어오게 됩니다.
Private Sub lboxEmployees_Click() EMP.EID = Me.lboxEmployees.Value If EMP.EID <> vbNullString Then EMP_ConnectPersonalInfoToForm End Sub
d. 직원 개인 정보를 담을 Type형 전역변수로 EMP를 만들어 두고 그것에 EID값을 찾아 직원시트에서 해당 직원을 찾습니다.
전역변수로 만들었다는 말은 이 프로젝트 전체에서 EMP를 쓰겠다는 의도입니다.
d.1. EMP_GetEmpRow()함수로 해당 직원을 찾음 못찾으면 0을 반환하여 종료함
d.2. EMP_SetEmpCellAddressToDictionary()함수로 해당 직원의 정보를 Dictionary에 담고 각 컨트를들의 ControlSource="셀주소" 를 설정함. 끝나면 True를 반환함
Public Function EMP_ConnectPersonalInfoToForm() As Boolean RowEmp = EMP_GetEmpRow(EMP.EID) '해당 직원의 행 번호를 찾아 반환 If RowEmp = 0 Then Exit Function If EMP_SetEmpCellAddressToDictionary = False Then '클릭한 직원 행 번호 가져오기. RowEmp는 전역변수기 때문에 매개변수로 넘길 필요 없다. EMP_ConnectPersonalInfoToForm = False Exit Function End If End Function '클릭한 직원 행 번호 찾아 반고 Dictonary에 셀주소 담기 Public Function EMP_GetEmpRow(EID As String, Optional Col As String = "A") As Long Dim RowLast As Long Dim rng As Range With wsYS.wsEmp RowLast = sh.GetLastRow(Col, wsYS.wsEmp) Set rng = .Range("A2:A" & RowLast).Find(What:=EID) '여기가 직원의 EID로 행 번호를 찾는 부분입니다. If rng Is Nothing Then MsgBox "EID doesn't exist. Check this employees record and try again.", vbInformation EMP_GetEmpRow = 0 Exit Function End If EMP_GetEmpRow = rng.Row End With End Function
'찾은 행번호로 Dictonary에 셀주소 담고 컨트롤에 연동시킴 Public Function EMP_SetEmpCellAddressToDictionary() As Boolean Dim ColLast As Long Dim i As Long Dim key As String Dim addr As String ColLast = sh.GetLastColumn(1, wsYS.wsEmp) '◀ 마지막 행이나 열 갖은 값을 찾기 위해 만들어 둔 클래스 모듈 dtEmp.RemoveAll With wsYS.wsEmp For i = 1 To ColLast key = .Cells(1, i).Value '◀ 여기에 필드명을 담아 둡니다. addr = "[" & wbYS.Name & "]EMPLOYEES!" & .Cells(RowEmp, i).Address '◀ 여기에 셀 주소값을 담아 둠 On Error Resume Next frmEmp.Controls(key).ControlSource = addr '◀ 이 부분이 해당 폼 컨트를에 각각의 셀을 연동 시켜주는 부분 On Error GoTo 0 '◀ 필드명과 컨트롤의 이름이 같기에 쉽게 루프로 연동 가능 Next i End With EMP_SetEmpCellAddressToDictionary = True End Function
e. 이제 연동이 끝났습니다. 컴보박스에서 직책을 선택하면 알아서 그 명단을 가져오고, 직원을 선택하면 직원시트에 있는 셀로 알아서 연동해 줄 것입니다. 이러면 직원 조회 및 수정 폼이 끝이 난 것입니다.
Dictioanry에 정보를 담아 둔 이유는 다른 곳에 쓸 용도가 있기 때문입니다.
연동만 하고자 할 때는 굳이 Dictionary에 담아 둘 필요가 없습니다.
코딩 팁) 여러개의 워크북과 많은 워크시트를이 동시에 실행되도 있는 상황이면 어느 워크북의 워크시트인지 명확하세 해 두어여 원하는 결과를 처리할 수 있습니다. 하도 에러 경험을 많이 당해서....
그래서 제가 생각한 해결책은
Public wbYS As Workbook '워크불 이름 명명 Public Type pwsYS '위의 위크복에 속해 있는 워크시트들 wsEmp As Worksheet wsSCM As Worksheet wsRH As Worksheet wsSF1 As Worksheet wsSF2 As Worksheet wsTemp As Worksheet attPasteArea As Range End Type Public wsYS As pwsYS '워크시트들을 접근할 수 있게 하는 전역변수
위와 같이 사용자 정의 변수(TYPE)을 이용하여 워크시트를 접근합니다. 그리고 폼 실행시 세팅하는 함수 하나 추가
저는 클래스로 자동 세팅하게 해 놓았습니다.
Private Sub SetWorkbooksAndSheets() If sh Is Nothing Then Set sh = New clsSheets If xlDb Is Nothing Then Set xlDb = New clsXLDataBase If DT Is Nothing Then Set DT = New clsDate If cUtil Is Nothing Then Set cUtil = New clsControlUtil Set wbYS = ThisWorkbook With wsYS Set .wsSCM = wbYS.Worksheets("SCHEMA") Set .wsEmp = wbYS.Worksheets("EMPLOYEES") Set .wsRH = wbYS.Worksheets("Regular Holidays") Set .wsSF1 = wbYS.Worksheets("SalaryFormat1") Set .wsSF2 = wbYS.Worksheets("SalaryFormat2") Set .wsTemp = wbYS.Worksheets("TEMP") Set .attPasteArea = .wsTemp.Range("A2") End With End Sub
각각의 워크북들과 워크시트를 이런식으로 해놓으면, 코드 입력시 아래와 같이 뜨기 때문에 편합니다.
큰 프로젝트를 하다보면 Activesheet, Thisworkbook, ActiveCell, Worksheets("Sheet1") 같은 것을 쓰는 것이 좋지 않다는 것을 아시게 될 겁니다. 의도하지 않은 곳에서 혼자 자동화하고 있을 수도 있습니다.
번호 | 제목 | 작성자 | 작성일 | 추천 | 조회 |
[📚진짜쓰는 실무엑셀] IT/오피스 '1위' 베스트셀러! 엑셀 공부, 이 교재로 마스터하세요! (315)
![]() ![]() |
![]() ![]() |
2022.02.03 | 575 | 609803 | |
78094 |
[M365] 수식으로 고급필터 구현하기
![]() ![]() |
![]() |
2025.04.11 | 1 | 133 |
78009 |
LOOKUP을 XLOOKUP 처럼 사용 (2019 이하 필독)
![]() ![]() |
![]() |
2025.04.06 | - | 129 |
78002 |
[VBA] 괄호가 대응되게 문자열 잘라주는 함수
![]() |
![]() |
2025.04.05 | - | 70 |
77792 |
엑셀 그림 삽입이 안될 때.. (그림 삽입 비활성화 해결)
(1)
![]() ![]() |
![]() ![]() |
2025.03.24 | 2 | 448 |
77667 |
언피벗 툴 업그레이드 버전입니다.
![]() ![]() |
![]() |
2025.03.17 | - | 118 |
77635 |
머리글로 데이터 합치기 툴
![]() ![]() |
![]() |
2025.03.15 | 1 | 127 |
77598 |
MERGE(자석처럼 자료 붙이기) 툴입니다.
![]() ![]() |
![]() |
2025.03.13 | - | 170 |
77577 |
[VBA] 시트명들 가져오는 함수
![]() ![]() |
![]() |
2025.03.12 | 1 | 132 |
77544 |
LOOKUP 함수 사용법(2019 이하 필독)
![]() ![]() |
![]() |
2025.03.11 | - | 206 |
77543 |
[함수TIP] Date함수로 Eomonth함수 대체하기
(3)
![]() |
![]() |
2025.03.11 | 3 | 86 |
77481 |
쉽게 쓸 수 있는 언피벗 툴
![]() ![]() |
![]() |
2025.03.08 | 2 | 133 |
77468 |
월간단위 월주차 함수
![]() ![]() ![]() |
![]() ![]() |
2025.03.07 | - | 155 |
77385 |
TEXTJOIN 을 SUMPRODUCT 공식으로 2차원 데이터 다루기
![]() ![]() |
![]() |
2025.03.04 | - | 106 |
77355 |
TEXTJOIN 으로 2차원 데이터 다루기
![]() ![]() |
![]() |
2025.03.02 | 1 | 110 |
77353 |
& 기호로 SUMPRODUCT 2차원 데이터 다루기
![]() ![]() |
![]() |
2025.03.02 | - | 87 |
77351 |
단어 포함 여부 검색, 원하는 단어로 출력
![]() ![]() |
![]() |
2025.03.02 | 1 | 119 |
77238 |
휴일이면 1 아니면 0이 나오는 함수
![]() ![]() |
![]() |
2025.02.24 | - | 158 |
77072 |
SUMPRODUCT로 VLOOKUP 대체 (2차원 룩업 가능)
![]() ![]() |
![]() |
2025.02.16 | - | 274 |
76915 |
SUMPRODUCT로 2차원 데이터 다루기[응용]
![]() ![]() |
![]() |
2025.02.09 | 1 | 238 |
76913 |
SUMPRODUCT로 2차원 데이터 sumifs 처럼 다루기
![]() ![]() |
![]() |
2025.02.09 | - | 199 |
@dra**** 님 좋은 정보 감사합니다😄
@dra**** 님 좋은 정보 감사합니다
@dra**** 님 좋은 정보 감사드립니다.