글목록

2021년 4월 10일

Module 2. 데이터 정렬(Sorting)하기 (3)

이전 글까지 데이터를 정렬하는 매크로를 만들었는데, 데이터를 크기순으로 정렬하는 것 이외에 크기 순서를 찾을 수 있는 기능을 포함시켜서 만들었다고 말씀드렸습니다.

크기 순으로 정렬하는 것은 특별한 설명없이도 그 결과물에 대해 쉽게 이해하실 수 있지만, 크기 순서를 찾는다는 것이 어떤 의미인지 설명이 필요할 것 같아서 추가로 글을 올립니다.

일단 SortStep 함수에 입력하는 데이터의 구조는 다음과 같습니다.

iData(i, j) 형태이며, j=1인 열에는 배열 전의 데이터, j=2인 열에는 현재 데이터의 index 값, 즉 i 값이 입력되어 있습니다. 각각의 데이터를 크기순으로 배열하면서, j=2인 열의 데이터값이 함께 이동합니다. 데이터가 정렬되면서 원래 데이터 배열에서의 위치 정보가 사라지는데, 이 정보를 계속 함께 이동시키는 것입니다.

현재의 데이터에서 오름차순으로 정렬했을 때, 3번째가 되는 숫자를 알고 싶다고 하면, 원데이터를 정렬한 후, 3번째 데이터를 추출하면 됩니다. 1번의 정렬만으로 원하는 순번의 데이터를 찾을 수 있습니다. 따라서, 숫자로만 구성된 배열에서 정렬 후 크기 순서를 찾는 것은 특별히 의미가 없을 것 같습니다.

만약, 정렬하려는 대상이 숫자가 아닌 경우에는 어떻게 해야할까요? 예를 들어, 데이터가 입력된 셀이 100개가 있습니다. 원래의 셀은 바꾸지 않고, 여기에서 3번째 크기를 갖는 셀을 선택하고 싶다고 하겠습니다. 

다른 예를 들어보도록 하겠습니다. 도형이 100개가 배열되어있습니다. 이 도형들이 1번부터 100번까지 순서대로 배열되어있는 것이 아니고, 순번에 상관없이 위 아래로 배열되어있습니다.  이 중에서, 위에서 3번째에 위치한 도형을 선택하고 싶습니다. 물론 도형의 위치는 그대로 두고 말이지요.

위의 2가지 예시의 공통점은.. 단순히 숫자가 아니라, Object가 있고, 이 Object의 특별한 속성값을 가지고 정렬한 다음, 몇번째 순서에 있는 Object를 선택하겠다는 것입니다. 물론, Object도 속성에 따라 다시 재배열을 시킬 수는 있지만, Object 종류에 따라 프로시저를 만들어줘야한다는 점에서 불편할 수 있습니다.


다음의 매크로를 실행한 후 결과를 보시기 바랍니다.

Sub Test3()
  Dim tData() As Double, tIndex() As Double, tSorted(), n As Long
  n = 10
  tData = RandArray(n)
  tData = GetSorted(tData, False, True, False)
  tIndex = GetSorted(tData, True, True, False)
  ReDim tSorted(1 To n, 1 To 3)
  For i = 1 To n
    tSorted(i, 1) = i
    tSorted(i, 2) = tData(i)
    tSorted(i, 3) = tIndex(i)
  Next
  ActiveSheet.Range(Cells(1, 4), Cells(n, 6)).Value = tSorted
End Sub




10개의 데이터를 생성하고 난 후, 이 값을 숫자로 정렬한 결과를 E열에 출력했고, 정렬된 데이터의 원래 위치에 대한 정보를 F열에 표기한 것입니다.

원데이터의 위치를 알고 있으므로, tIndex(n)을 출력하면, n번째 크기에 해당하는 원래 데이터의 위치를 알 수 있습니다. 위의 경우, 3번째 크기를 갖는 숫자는 원데이터의 5번째에 있고, 그 값이 30.19입니다. 정렬 후 데이터에서 3번째 숫자가 30.19이니 잘 작동하는 것을 알 수 있습니다. 유의할 점은 tIndex에 입력되어 있는 값은 데이터의 순서가 아니라, 데이터의 위치 정보입니다. 크기 순서는 tIndex(n)으로 표기했을 때, 'n' 값이 크기 순서입니다.

이렇게 구현한 이유는 활용성 측면에서입니다.

아래와 같은 프로시저를 실행시켜보시면 쉽게 이해가실 듯 합니다.


Sub Test4()
  Dim tData() As Double, tIndex() As Double, tSorted(), n As Long
  n = 10
  tData = RandArray(n)
  tIndex = GetSorted(tData, True, True, False)
  ActiveSheet.Cells(tIndex(3), 1).Select
End Sub


10개의 데이터를 생성한 후, 크기 순서로 3번째에 해상하는 셀을 선택하라는 매크로가 되겠습니다. 

다른 예로, 100개의 워크시트가 있다고 했을 때, 각 워크시트의 1번째열에 있는 값을 정렬하여 크기순으로 5번째가 되는 행의 데이터만 별도의 워크시트로 추출하고 싶다고 할 때, 1번째 열의 데이터만 정렬해서 해당 행 전체를 복사하면, 원하는 데이터가 추출되지 않습니다. 물론, 엑셀의 정렬기능을 사용하는 방법도 있습니다만, 만약 셀 데이터가 아닌, 다른 Object에 대한 정렬이라면 내장된 기능을 사용할 수는 없겠지요. 이럴 때, 원 데이터는 그대로 두고, 1번열의 데이터를 크기순으로 정렬했을 때 위치 정보만 찾아내어 원데이터에서 원하는 행을 복사하게 되면 깔끔하게 데이터 추출이 가능해집니다.

필요에 따라서 이전 글들에 있는 매크로들을 약간 수정해서 사용하시면 됩니다.

이상 데이터 정렬에 대한 매크로였습니다.

댓글 없음:

댓글 쓰기

의견이나 질문이 있으신 분은 언제든지 댓글을 달아주세요~

많이 본 글 :