엑셀 시트 데이터 연결 함수 :: Connect_DB 명령문

서로 다른 두 시트를 관계형 데이터로 연결하는 Connect_DB 함수의 사용법 및 동작원리를 살펴봅니다.

작성자 :
오빠두엑셀
최종 수정일 : 2021. 06. 28. 20:55
URL 복사
메모 남기기 : (21)

엑셀 시트 데이터 연결 :: Connect_DB 명령문 사용법 정리

엑셀 Connect_DB 명령문 목차 바로가기
요약

엑셀 Connect_DB 함수는 서로 다른 두 시트를 관계형 데이터베이스로 연결하는 엑셀 사용자지정함수입니다.

명령문 구문
Array = Connect_DB ( 기존DB, ID번호, 연결할시트, 불러올필드, [머릿글포함] )
사용된 인수 및 변수 알아보기
인수 설명
기존DB
[Variant]
원본 시트의 데이터가 배열형태로 입력된 DB 입니다. Get_DB 함수로 받아옵니다.
ID번호
[Long]
기존DB에서 연결할 시트의 ID로 참조 될 외래ID가 입력된 필드의 열 번호입니다.
연결할시트
[WorkSheet]
기존 DB와 연결할 시트입니다.
불러올필드
[String]
연결할 시트에서 불러올 필드명입니다. 여러 필드를 불러올 경우 쉼표(,)로 구분하여 입력합니다.
머릿글포함
[Boolean, 선택인수]
머릿글 포함여부입니다. TRUE일 경우 머릿글을 포함하여 병합합니다.

예제파일 다운로드

오빠두엑셀의 강의 예제파일은 여러분을 위해 자유롭게 제공하고 있습니다.


상세 설명

엑셀 Connect_DB 함수는 서로 다른 두 시트를 관계형 데이터베이스로 연결하는 사용자 지정 함수입니다. 관계형 데이터베이스에 대한 기초 설명은 아래 엑셀 vs 관계형데이터베이스 기초 강의를 참고하세요.

Connect_DB 함수를 올바르게 사용하려면 원본 시트와 연결할 시트에는 아래 규칙을 지켜 데이터를 입력해야 합니다.

  1. 시트의 값은 반드시 A1셀부터 시작해야 합니다.
  2. 병합된 셀이 없어야 합니다.
  3. 연결 할 시트의 ID는 반드시 A열에 입력되어야 합니다.
  4. 머릿글은 반드시 1행에 입력되어야 합니다.

Connect_DB 함수는 데이터베이스 관련 VBA 함수 중 하나입니다. 더 다양한 DB 관련 함수는 아래 링크를 참고해주세요.

실전 사용 예제
  1. 판매내역의 제품ID를 참조하여 제품 시트 연결하기
    ' 판매내역 : 판매ID | 제품ID | 날짜 | 수량 | 단가
    ' 제품정보 : 제품ID | 제품명 | 구매처
    Dim DB As Variant
    Dim WS As Worksheet
     
    Set WS = ThisWorkbook.Worksheets("제품정보")
     
    DB = Get_DB(ThisWorkbook.Worksheets("판매내역"))
    DB = Connect_DB(DB, 2, WS, "제품명, 구매처")
     
    ' DB로 판매ID | 제품ID | 날짜 | 수량 | 단가 | 제품명 | 구매처 가 반환됩니다.
  2. 급여내역의 직원ID를 참조하여 직원 정보 추가하기
    ' 급여내역 : 급여ID | 직원ID | 지급월 | 급여
    ' 직원정보 : 직원ID | 직원명 | 직급 | 부서
    Dim DB As Variant
    Dim WS As Worksheet
     
    Set WS = ThisWorkbook.Worksheets("직원정보")
     
    DB = Get_DB(ThisWorkbook.Worksheets("급여내역"))
    DB = Connect_DB(DB, 2, WS, "직원명")
     
    ' DB로 급여ID | 직원ID | 지급월 | 급여 | 직원명 이 반환됩니다.

엑셀 시트 데이터 연결, Connect_DB 명령문 동작원리

Connect_DB 명령문 전체 코드
Function Connect_DB(DB As Variant, ForeignID_Fields As Variant, FromWS As Worksheet, Fields As String, Optional IncludeHeader As Boolean = False)
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'수정 및 배포 시 출처를 반드시 명시해야 합니다.
 
'■ Connect_DB 함수
'■ 서로 다른 두 시트를 연결합니다. FromWS의 첫번째 필드는 반드시 고유값(ID)이 입력되어야 합니다.
'■ 사용방법
'Array = Connect_DB(Get_DB(Sheet1),2,Sheet2, "필드1, 필드2, 필드3")
'■ 인수 설명
'_____________DB                : 병합할 원본 DB입니다.
'_____________ForeignID_Fields  : 연결할 시트에서 참조할 외래ID가 입력된 열번호입니다.
'_____________FromWS            : 연결할 시트입니다.
'_____________Fields            : 연결할 시트에서 불러올 필드목록입니다. 쉼표(,)로 구분하여 입력합니다.
'_____________IncludeHeader     : 머릿글 포함여부입니다. 기본값은 False 입니다.
'■ 사용된 보조명령문
'Get_Dict 함수
'###############################################################
 
Dim cRow As Long: Dim cCol As Long
Dim vForeignID_Fields As Variant: Dim vForeignID_Field As Variant
Dim ForeignID As Variant
Dim vFields As Variant: Dim vField As Variant
Dim vID As Variant: Dim vFieldNo As Variant
Dim Dict As Object
Dim vTemp As Variant
Dim i As Long: Dim j As Long
Dim AddCols As Long
 
 
cRow = UBound(DB, 1)
cCol = UBound(DB, 2)
If InStr(1, Fields, ",") > 1 Then
    AddCols = Len(Fields) - Len(Replace(Fields, ",", "")) + 1
    vFields = Split(Fields, ",")
Else
    AddCols = 1
    vFields = Array(Fields)
End If
 
ReDim Preserve DB(1 To cRow, 1 To cCol + AddCols)
 
Set Dict = Get_Dict(FromWS)
For Each vTemp In Dict.keys
    vID = Dict(vTemp)
    Exit For
Next
 
 
ReDim vFieldNo(0 To UBound(vFields))
 
For Each vField In vFields
    For i = 1 To UBound(vID)
        If vID(i) = Trim(vField) Then vFieldNo(j) = i: j = j + 1
    Next
Next
 
If InStr(1, ForeignID_Fields, ",") > 0 Then vForeignID_Fields = Split(ForeignID_Fields, ",") Else vForeignID_Fields = Array(ForeignID_Fields)
 
For Each vForeignID_Field In vForeignID_Fields
    For i = 1 To cRow
        If IncludeHeader = True And i = 1 Then ForeignID = vTemp Else ForeignID = DB(i, Trim(vForeignID_Field))
        If Dict.Exists(ForeignID) Then
            For j = 1 To AddCols
                DB(i, cCol + j) = Dict(ForeignID)(vFieldNo(j - 1))
            Next
        End If
    Next
Next
 
Connect_DB = DB
 
End Function
 
Function Get_Dict(WS As Worksheet) As Object
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'수정 및 배포 시 출처를 반드시 명시해야 합니다.
 
'■ Get_Dict 함수
'■ 시트에 입력된 데이터를 Dictionary로 반환합니다. 첫번째 필드는 반드시 고유값이 입력되어야 합니다.
'■ 사용방법
'Dictionary = Get_Dict(시트)
'■ 인수 설명
'_____________WS            : Dictionary로 변환할 시트입니다.
'###############################################################
Dim cRow As Long: Dim cCol As Long
Dim Dict As Object
Dim vArr As Variant
Dim i As Long: Dim j As Long
 
Set Dict = CreateObject("Scripting.Dictionary")
 
With WS
 
    cRow = .Cells(.Rows.Count, 1).End(xlUp).Row
    cCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
 
    For i = 1 To cRow
        ReDim vArr(1 To cCol - 1)
        For j = 2 To cCol
            vArr(j - 1) = .Cells(i, j)
        Next
        Dict.Add .Cells(i, 1).Value, vArr
    Next
End With
 
Set Get_Dict = Dict
 
End Function
명령문 동작원리 단계별 알아보기
  1. 명령문에 사용 될 변수를 선언합니다.
    Dim cRow As Long: Dim cCol As Long
    Dim vForeignID_Fields As Variant: Dim vForeignID_Field As Variant
    Dim ForeignID As Variant
    Dim vFields As Variant: Dim vField As Variant
    Dim vID As Variant: Dim vFieldNo As Variant
    Dim Dict As Object
    Dim vTemp As Variant
    Dim i As Long: Dim j As Long
    Dim AddCols As Long
  2. 기존 DB의 행/열 개수를 계산합니다.
    cRow = UBound(DB, 1)
    cCol = UBound(DB, 2)
  3. 불러올 필드를 배열로 반환한 뒤, 필드 개수에 따라 임시 배열에 추가할 열 개수 값을 계산합니다.
    If InStr(1, Fields, ",") > 1 Then
        AddCols = Len(Fields) - Len(Replace(Fields, ",", "")) + 1
        vFields = Split(Fields, ",")
    Else
        AddCols = 1
        vFields = Array(Fields)
    End If
  4. 임시 배열(DB)의 열 개수를 추가합니다.
    ReDim Preserve DB(1 To cRow, 1 To cCol + AddCols)
  5. 연결할 시트를 Dictionary 개체로 변환한 뒤, 머릿글을 배열로 반환합니다.
    Set Dict = Get_Dict(FromWS)
    For Each vTemp In Dict.keys
        vID = Dict(vTemp)
        Exit For
    Next
  6. 불러올 필드의 열 번호를 계산합니다.
    ReDim vFieldNo(0 To UBound(vFields))
     
    For Each vField In vFields
        For i = 1 To UBound(vID)
            If vID(i) = Trim(vField) Then vFieldNo(j) = i: j = j + 1
        Next
    Next
     
    If InStr(1, ForeignID_Fields, ",") > 0 Then vForeignID_Fields = Split(ForeignID_Fields, ",") Else vForeignID_Fields = Array(ForeignID_Fields)
  7. DB의 값을 하나씩 돌아가며, 연결할 시트에서 불러올 값을 배열의 오른쪽으로 추가합니다.
    For Each vForeignID_Field In vForeignID_Fields
        For i = 1 To cRow
            If IncludeHeader = True And i = 1 Then ForeignID = vTemp Else ForeignID = DB(i, Trim(vForeignID_Field))
            If Dict.Exists(ForeignID) Then
                For j = 1 To AddCols
                    DB(i, cCol + j) = Dict(ForeignID)(vFieldNo(j - 1))
                Next
            End If
        Next
    Next
  8. 임시 배열을 함수의 결과값으로 반환한 뒤 명령문을 종료합니다.
    Connect_DB = DB
5 9 투표
게시글평점
21 댓글
Inline Feedbacks
모든 댓글 보기
21
0
여러분의 생각을 댓글로 남겨주세요.x