글목록

2021년 4월 18일

행, 열 주기적으로 선택하기-주기적인 데이터 추출하기

이전 글에서 여러 개의 파일을 한꺼번에 열어서, 특정한 영역의 데이터만 1개의 시트로 병합했습니다. 이렇게 병합하는 이유는 수많은 데이터 중에서 사용자가 필요로 하는 부분만 가져와서 각각의 경우에 대해 비교하여 분석할 필요가 있기 때문입니다.

예를 들어, 1~10까지 각 1씩 변하는 조건으로 분석을 했고, 분격 결과 데이터가 각각 10개의 열 데이터로 받았다고 하겠습니다. 그런데 필요한 데이터는 각 데이터의 1~5번 열에 있다면, 파일을 열어 1열부터 5열까지 데이터만 추출해서 1개의 시트에 모아둘 수 있습니다.

그러나, 이렇게 데이터를 모아두는 것은 별 의미가 없습니다. 이제 1~10번 데이터 중에서 각 1열에 해당하는 데이터만 그래프를 그리거나, 통계를 내는 등 각 조건에 대한 데이터를 비교할 필요가 있습니다. 따라서, 1~10번 데이터를 모두 읽어온 상태에서 각 1열을 병합하고, 다음은 각 2열을 병합하고... 이런 식으로 반복을 하면 병합된 데이터를 빠르게 비교해볼 수는 있을 것입니다. 이러한 방법은 앞의 글에서 설명드린 매크로를 이용하면 쉽게 되겠지요..


한편, 어떤 데이터는 1~10번 데이터에 대하여 1개 시트에 한꺼번에 받을 수도 있을 것입니다. 혹은 원본데이터를 정리한다고, 미리 1개 시트에 통합해서 저장해뒀을 수도 있구요.. 이렇게 미리 통합된 데이터에서, 각 분석 데이터의 1번과 3번 열만 추출하고 싶다면 어떻게 해야할까요?

시트에서 10개 열을 주기로, 1번과 3번 열만 추출해라.. 하는 매크로가 있다면 해결될 수 있을 것입니다. 엑셀에서 1개 시트에서 여러 개의 영역을 선택하고 Ctrl+C/V로 복사할 수 있습니다. 단, 이때 선택된 여러 개의 영역의 행번호가 일치하거나, 열번호가 일치해야합니다. 만약, 행과 열번호가 모두 다르다면, 다중 영역 복사가 안됩니다.

어쨋거나, 이미 만들어진 원본데이터에서 주기적으로 영역선택만 해준다면, Ctrl+C/V로 주기적인 데이터를 추출해낼 수 있습니다.


여러 개의 영역을 선택하는 방법으로 엑셀의 Union을 사용할 수 있습니다.

'-----------------------------------------------------

Function UnionRange(iRange1 As Range, iRange2 As Range) As Range
  'Application.Union는 2개의 Range를 1개의 Range로 병합하는 method입니다. 그러나, 만약, 둘 중 하나라도 주소가 지정되지 않은 Nothing값이 입력되면, 에러가 발생됩니다.
  '둘 중 1개라도 Nothing이 입력된 경우에는 나머지 range를 반환하고, 둘다 주소가 지정되어있는 영역이 입력되면, 병합된 ranige를 반환하도록 합니다.
  If iRange1 Is Nothing Then
    Set UnionRange = iRange2
  Else
    If iRange2 Is Nothing Then
      Set UnionRange = iRange1
    Else
      Set UnionRange = Application.Union(iRange1, iRange2)
    End If
  End If
End Function

'-----------------------------------------------------

Sub PeriodicSelection()
  On Error GoTo ErrorHandler
  Dim i As Long, j As Long, tSelRange As Range, tRange As Range, tPeriod As Range, tPN As Long, tCol As Range

  '사용자가 선택한 영역 중 현재 시트의 사용영역과 교차시켜, 데이터가 없는 부분은 선택되지 않도록 합니다. 굳이 union을 한번 더 했던 이유는, 사용자가 Ctrl을 사용하여 여러 영역을 선택할 때, 실수로 동일 영역을 2번 선택한 경우, 1번만 선택한 것으로 바꿔주기 위함입니다.
  Set tSelRange = Application.Intersect(Application.Union(Selection, Selection), ActiveSheet.UsedRange)

  '선택 영역이 1개 이상의 Area로 구성되어 있다면, 오류 처리합니다. 이 부분은 사용 목적에 따라 조금씩 수정해서 사용하면 됩니다.
  If tSelRange.Areas.Count > 1 Then
    MsgBox tSelRange.Areas.Count & "개의 영역이 선택되어 있습니다." & vbCrLf & "1개의 영역만 선택하세요.", vbInformation, "입력 오류"
    GoTo ErrorHandler
  End If
  
  '만약, 매크로 실행 전에 작업 영역을 선택하지 않았다면, 현재 선택된 셀의 확장 영역으로 선택영역을 지정해줍니다. 
  If tSelRange.Columns.Count = 1 And tSelRange.Rows.Count = 1 Then Set tSelRange = tSelRange.CurrentRegion
  
  '선택 영역에서, 엑셀의 Inputbox를 이용해 반복주기를 선택하도록 입력 받습니다. 주기가 되는 열 수를 숫자로 입력받을 수도 있지만, 사용자 입장에서 일일이 세고 있는 것도 귀찮은 일이라.. 그냥 영역을 선택하도록 하면, 주기가 되는 열 수를 세어줍니다.
  Do
    tSelRange.Select
    tSelRange.Cells(1, 1).Activate
    Set tPeriod = Application.InputBox("반복 주기를 선택하세요.", "주기 선택", tSelRange.Address, Type:=8)
    Set tPeriod = Application.Intersect(tSelRange, tPeriod.EntireColumn)
    If tPeriod.Areas.Count <> 1 Then If MsgBox("반복 주기는 1개 영역으로만 선택하세요.", vbOKCancel, "선택 오류") = vbCancel Then GoTo ErrorHandler
  Loop Until tPeriod.Areas.Count = 1
  
  '전체 데이터에서 주기가 되는 열 전체를 선택해서 보여주고, 원하는 데이터 열만 다시 선택하도록 합니다.
  tPeriod.Select
  tPN = tPeriod.Columns.Count
  
  Set tRange = Application.InputBox("선택할 열을 지정하세요.", "열 선택", tPeriod.Address, Type:=8)
  Set tRange = Application.Intersect(tPeriod, tRange.EntireColumn)
  tRange.Select
  
  '선택된 열을 주기적으로 합쳐준 후, 영역 선택을 하고 매크로를 마칩니다.
  Set tCol = Nothing
  For i = 1 To tSelRange.Columns.Count Step tPN
    Set tCol = UnionRange(tCol, tRange)
    Set tRange = tRange.Offset(0, tPN)
  Next
  Set tCol = Application.Intersect(tCol, tSelRange)
  tCol.Select
ErrorHandler:
End Sub

'-----------------------------------------------------

위와 같은 매크로를 실행시킨 후 Ctrl+C/V로 하면, 원하는 열만 추출할 수 있게 됩니다.

데이터 반복수가 몇개 안되면, 그냥 수작업하는 게 빠를 수 있지만, 갯수가 많은 데이터 셋으로부터 반복작업을 하려면, 꽤나 유용할 수 있습니다.

댓글 없음:

댓글 쓰기

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

많이 본 글 :