본문 바로가기
기술자료 (KB)/Power Platform

PowerApps으로 만드는 조직도 솔루션 - 01. DB 구조

by 이완주 2024. 9. 9.

 

 

PowerApps으로 만든 조직도 솔루션 제안서

작년에 Power Apps으로 만들어 아직까지 저희 회사에 잘 쓰고 있는 솔루션 입니다.조직도는 연차 결재 솔루션과 연동하여 사용 중에 있습니다. 해당 솔루션의 구성 방법 입니다. 대략 10개 내외 정

leemcse.tistory.com

 

Excel 값을 SharePoint Lists 로 만들기는 아래 동영상에 나와 있으니 먼저 동영상을 참고하시길 바랍니다.

[Microsoft Power Apps 강좌] 시즌3 2화. Excel로 SharePoint 목록 만들기

 

 

 

조직도를 만들기 위해서는 우선 DataBase 설계를 해야 합니다. 
모든 Database는 OrderNo로 순서를 정할 수 있다.

Title 값은 SharePoint 목록의 첫번째 값으로 비어 있는 값으로 등록하면 문제가 되지 않는다.

첫번째 값을 Name으로 하게 되면 Title 과 Name 값의 혼재로 오류가 나타날 수 있다.

 

OrgDomainName - 메일 주소 테이블

Title Name OrderNo
  @globalsoft.co.kr 10
  @globalsoft.onmicrosoft.com 11

 

메일 도메인을 미리 등록 시켜 놓아 사용자 등록할 때 메일 주소 실수를 방지 하기 위함.

 

OrgCompany - 회사 테이블

Title Name OrderNo
  글로벌소프트 10

 

조직에는 여러개의 회사를 하나의 조직으로 관리 할 수 있기 때문에 여러 회사를 등록하여 관리 가능하게 구성.

 

 

OrgJobtitle - 직위 테이블

Title Name OrderNo
  대표 10
  부사장 11
  전무 12
  상무 13
  이사 14
  부장 15
  수석연구원 16
  차장 17
  과장 18
  책임연구원 19
  대리 20
  주임 21
  사원 22
  연구원 23

 

 

OrgPosition - 직책 테이블

Title Name OrderNo
  대표 10
  부사장 11
  임원 12
  본부장 13
  부서장 14
  팀장 15
  팀원 16

 

직위의 기본 값은 사원, 직책의 기본 값은 팀원으로 설정 한다.

 

OrgOriginalDepartment - 회사의 부서 정보

부서의 계층 구조는 Description의 / 로 구분하며 최대 5개 단계로 표현 가능 

예) 영업본부/영업1팀/영업1파트/영업1부문/영업1부문1

 

ID 값은 자동 생성되며 OrgDepartment 목록의 ParentID 값으로 사용 된다.

Title Company Name Description
  글로벌소프트 대표이사 대표이사
  글로벌소프트 임원 임원
  글로벌소프트 영업본부 영업본부
  글로벌소프트 영업1팀 영업본부/영업1팀
  글로벌소프트 영업2팀 영업본부/영업2팀
  글로벌소프트 영업3팀 영업본부/영업3팀
  글로벌소프트 기술본부 기술본부
  글로벌소프트 MS기술팀 기술본부/MS기술팀
  글로벌소프트 보안기술팀 기술본부/보안기술팀
  글로벌소프트 Autodesk기술팀 기술본부/Autodesk기술팀
  글로벌소프트 관리본부 관리본부
  글로벌소프트 마케팅팀 마케팅팀
  글로벌소프트 영업1파트 영업본부/영업1팀/영업1파트
  글로벌소프트 영업1부문 영업본부/영업1팀/영업1파트/영업1부문
  글로벌소프트 영업1부문1 영업본부/영업1팀/영업1파트/영업1부문/영업1부문1

 

OrgDepartment - 솔루션에 사용할 부서 정보 설정
아래 값은 초기화 값을 넣지 않으면 자동으로 텍스트로 설정, 숫자나 날짜의 경우 값을 넣으면 해당 형태로 값이 설정 됨

Title Company Name Description CompanyID Level ParentID No OrderNo Visible
        0 0 0     TRUE

 

 

 

OrgDepartment - 회사의 부서 정보를 조직도 솔루션에 맞게 변경한 값

 

아래 버튼을 눌러 SharePoint 목록의 값을 OrgOriginalDepartment 목록의 값을 받아 OrgDepartment 값으로 변경한다.

조직 - 직원 - 콜렉션 만들기 버튼을 순서대로 실행하여 DB를 정리해야 한다.

 

 

//RemoveIf(OrgDepartment,true);  Network Error 발생
Remove(OrgDepartment,OrgDepartment);
ForAll(                     // ForAll 아래 OrgOriginalDepartment 행의 개수 만큼 실행
    OrgOriginalDepartment,  
    Collect(                // 기존 데이터에 추가로 생성, 없으면 만들어 짐.
        OrgDepartment,       // SharePoint Lists 혹은 Collection
        {                  // SharePoint Lists의 경우 이미 목록을 만들어 놓아야 함.
            Company: Company,       // 직원 정보를 불러와 해당 값에 넣는다.
            Name: Name,
            Description: Description,
            //DepartmentID: ID,
            CompanyID:LookUp(OrgCompany,Name=Company,ID),
            Level:CountA(Split(Description,"/")),
            ParentID : With({varParentName:If(CountA(Split(Description,"/")) >1,Index(Split(Description,"/"),CountA(Split(Description,"/"))-1).Value)},If(IsBlank(varParentName),0,LookUp(OrgDepartment,Name=varParentName,ID))),
            No: Text(ID,"10000"),
            OrderNo: 
            If(
                CountA(Split(Description,"/"))=1,LookUp(OrgCompany,Name=Company,OrderNo) & Text(ID,"10000") & "0000000000000000000000000",
                CountA(Split(Description,"/"))=2,LookUp(OrgCompany,Name=Company,OrderNo) & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-1).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(ID,"10000") & "00000000000000000000",
                CountA(Split(Description,"/"))=3,LookUp(OrgCompany,Name=Company,OrderNo) & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-2).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-1).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(ID,"10000") & "000000000000000",
                CountA(Split(Description,"/"))=4,LookUp(OrgCompany,Name=Company,OrderNo) & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-3).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000")& Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-2).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-1).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(ID,"10000") & "0000000000",
                CountA(Split(Description,"/"))=5,LookUp(OrgCompany,Name=Company,OrderNo)& Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-4).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-3).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000")& Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-2).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(With({varParentName:Index(Split(Description,"/"),CountA(Split(Description,"/"))-1).Value},LookUp(OrgOriginalDepartment,Name=varParentName,ID)),"10000") & Text(ID,"10000")  & "00000"

            )
        }
    )
);

ClearCollect(ColDepartment,AddColumns(OrgDepartment,NewID,ID));
ForAll(
    OrgCompany,
    Collect(
        ColDepartment,
        {
            No: Text(OrderNo,"00"),
            CompanyID : ID,
            Name: Name,
            Level: 0,
            OrderNo: Text(OrderNo,"00") & "000000000000000000000000000000",
            Visible:true
        }
    )
);

 

아래 값은 OrgOriginalDepartment 값을 자동으로 채워진 값

Title Company Name Description CompanyID Level ParentID No OrderNo Visible
  글로벌소프트 대표이사 대표이사 1 1   10001 10100010000000000000000000000000 TRUE
  글로벌소프트 임원 임원 1 1   10002 10100020000000000000000000000000 TRUE
  글로벌소프트 영업본부 영업본부 1 1   10003 10100030000000000000000000000000 TRUE
  글로벌소프트 영업1팀 영업본부/영업1팀 1 2 3 10004 10100031000400000000000000000000 TRUE
  글로벌소프트 영업2팀 영업본부/영업2팀 1 2 3 10005 10100031000500000000000000000000 TRUE
  글로벌소프트 영업3팀 영업본부/영업3팀 1 2 3 10006 10100031000600000000000000000000 TRUE
  글로벌소프트 기술본부 기술본부 1 1   10007 10100070000000000000000000000000 TRUE
  글로벌소프트 MS기술팀 기술본부/MS기술팀 1 2 7 10008 10100071000800000000000000000000 TRUE
  글로벌소프트 보안기술팀 기술본부/보안기술팀 1 2 7 10009 10100071000900000000000000000000 TRUE
  글로벌소프트 Autodesk기술팀 기술본부/Autodesk기술팀 1 2 7 10010 10100071001000000000000000000000 TRUE
  글로벌소프트 관리본부 관리본부 1 1   10011 10100110000000000000000000000000 TRUE
  글로벌소프트 마케팅팀 마케팅팀 1 1   10012 10100120000000000000000000000000 TRUE
  글로벌소프트 영업1파트 영업본부/영업1팀/영업1파트 1 3 4 10013 1010031000410013000000000000000 TRUE
  글로벌소프트 영업1부문 영업본부/영업1팀/영업1파트/영업1부문 1 4 13 10014 10100031000410013100140000000000 TRUE
  글로벌소프트 영업1부문1 영업본부/영업1팀/영업1파트/영업1부문/영업1부문1 1 5 14 10015 10100031000410013100141001500000 TRUE

 

 

OrgOriginalEmployee - 회사의 직원 정보

ResignationDate : 퇴사일을 날짜 값으로 입력하기 위해 첫번째 줄에 퇴사 날짜를 임의의 날짜 값을 넣는다.

소속 부서를 3개 까지 넣을 수 있게 구성 (겸직 처리 가능)

 

아례는 예시 값 입니다.

EmpNo는 엑셀에서 값이 숫자로 들어감으로 문자로 변경해 주셔야 오류가 발생하지 않습니다.

Company EmpNo Department Department1 Department2 Name Jobtitle Position Mail Mobile Phone ShortNumber JoinDate ResignationDate Specialize
글로벌소프트 19980001 대표이사 임원   김대표 대표 대표 kimdp@globalsoft.co.kr 010-3006-7000 070-7098-2000 200 1998-11-15 2023-06-17  
글로벌소프트 20220004 임원     국 부 부사장 부사장 bkuk@globalsoft.co.kr 010-5002-6002 070-7599-2000 201 2022-12-01    

 

OrgEmployee - 회사의 직원 정보를 조직에 맞게 설정하기 위해 초기 값 설정

Company EmpNo Department Department1 Department2 Name Jobtitle Position Mail Mobile Phone ShortNumber CompanyID Level DepartmentID No OrderNo Level1 DepartmentID1 No1 OrderNo1 Level2 DepartmentID2 No2 OrderNo2 Visible JoinDate ResignationDate Specialize
                      0 0 0 0     0 0     0 0     True 2024-09-10 2024-09-10  

 

 

OrgEmployee  - 회사의 직원 정보를 조직도 솔루션에 맞게 변경한 값

 

아래 버튼을 눌러 SharePoint 목록의 값을 OrgOriginalEmployee목록의 값을 받아 Org Employee 값으로 변경한다.

조직 - 직원 - 콜렉션 만들기 버튼을 순서대로 실행하여 DB를 정리해야 한다.

//RemoveIf(OrgEmployee,true);
Remove(OrgEmployee, OrgEmployee);

ForAll(                     // ForAll 아래 OrgOriginalDepartment 행의 개수 만큼 실행
    OrgOriginalEmployee,  
    Collect(                // 기존 데이터에 추가로 생성, 없으면 만들어 짐.
        OrgEmployee,       // SharePoint Lists 혹은 Collection
        {                  // SharePoint Lists의 경우 이미 목록을 만들어 놓아야 함.
            Company: Company,       // 직원 정보를 불러와 해당 값에 넣는다.
            EmpNo : EmpNo,
            Department: Department,
            Department1: Department1,
            Department2: Department2,
            Name: Name,
            Jobtitle:Jobtitle,
            Position:Position,
            Mail:Mail,
            Mobile:Mobile,
            Phone:Phone,
            ShortNumber:ShortNumber,
            JoinDate:JoinDate,
            ResignationDate:ResignationDate,
            Specialize:Specialize,

            CompanyID:LookUp(OrgCompany,Name=Company,ID),
            Level: LookUp(OrgDepartment,Name=Department,Level) + 1,
            DepartmentID : LookUp(OrgDepartment,Name=Department,ID),

            No: If(IsBlank(First(Sort(OrgEmployee,No,SortOrder.Descending)).No),"90001",With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+1,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+1,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+1},
    Max(var1,var2,var3))),


            //OrderNo: Replace(LookUp(OrgDepartment,Name=Department,OrderNo),28,32,If(IsBlank(First(Sort(OrgEmployee,No,SortOrder.Descending)).No),"90001",First(Sort(OrgEmployee,No,SortOrder.Descending)).No+1)),
            
            OrderNo: Replace(LookUp(OrgDepartment,Name=Department,OrderNo),28,32,
                        If(IsBlank(First(Sort(OrgEmployee,No,SortOrder.Descending)).No),"90001",
                            With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+1,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+1,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+1},
    Max(var1,var2,var3))
                        )
                    ),
            
            Level1: If(!IsBlank(LookUp(OrgDepartment,Name=Department1,Level)),LookUp(OrgDepartment,Name=Department1,Level)+1),
            DepartmentID1 : If(!IsBlank(LookUp(OrgDepartment,Name=Department1,ID)),LookUp(OrgDepartment,Name=Department1,ID)),
            
            //No1: If(!IsBlank(LookUp(OrgDepartment,Name=Department1,Level)),If(IsBlank(First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1),"90001",First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+1)),

            No1: If(!IsBlank(LookUp(OrgDepartment,Name=Department1,Level)),If(IsBlank(First(Sort(OrgEmployee,No,SortOrder.Descending)).No),"90002",With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+2,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+2,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+2},
    Max(var1,var2,var3)))),


            //OrderNo1: If(!IsBlank(LookUp(OrgDepartment,Name=Department1,Level)),Replace(LookUp(OrgDepartment,Name=Department1,OrderNo),28,32,If(IsBlank(First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1),"90001",First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+1))),
            OrderNo1: If(!IsBlank(LookUp(OrgDepartment,Name=Department1,Level)),
                        Replace(LookUp(OrgDepartment,Name=Department1,OrderNo),28,32,
                            If(IsBlank(First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1),"90002",
                                With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+2,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+2,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+2}, Max(var1,var2,var3))
                            )
                        )
                      ),

            Level2: If(!IsBlank(LookUp(OrgDepartment,Name=Department2,Level)),LookUp(OrgDepartment,Name=Department2,Level)+1),
            DepartmentID2 : If(!IsBlank(LookUp(OrgDepartment,Name=Department2,ID)),LookUp(OrgDepartment,Name=Department2,ID)),
            
            //No2: If(!IsBlank(LookUp(OrgDepartment,Name=Department2,Level)),If(IsBlank(First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2),"90001",First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+1)),

            No2: If(!IsBlank(LookUp(OrgDepartment,Name=Department2,Level)),If(IsBlank(First(Sort(OrgEmployee,No,SortOrder.Descending)).No),"90003",With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+3,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+3,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+3},
    Max(var1,var2,var3)))),
            
            
            //OrderNo2: If(!IsBlank(LookUp(OrgDepartment,Name=Department2,Level)),Replace(LookUp(OrgDepartment,Name=Department2,OrderNo),28,32,If(IsBlank(First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2),"90001",First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+1)))
            OrderNo2: If(!IsBlank(LookUp(OrgDepartment,Name=Department2,Level)),
                            Replace(LookUp(OrgDepartment,Name=Department2,OrderNo),28,32,
                                If(IsBlank(First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2),"90003",
                                    With({var1:First(Sort(OrgEmployee,No,SortOrder.Descending)).No+3,var2:First(Sort(OrgEmployee,No1,SortOrder.Descending)).No1+3,var3:First(Sort(OrgEmployee,No2,SortOrder.Descending)).No2+3}, Max(var1,var2,var3))
                                )
                            )
                        )
            
        }
    )
);

ClearCollect(ColEmployee,AddColumns(OrgEmployee,NewID,ID));
ForAll(
    OrgCompany,
    Collect(
        ColEmployee,
        {
            No: Text(OrderNo,"00"),
            CompanyID : ID,
            Name: Name,
            Level: 0,
            OrderNo: Text(OrderNo,"00") & "000000000000000000000000000000",
            Visible:true
        }
    )
);

 

버튼으로 DB 변경은 추후 관련 설명을 따로 진행 예정 입니다.

댓글