(VBA) 연결된 데이터의 끝까지 복사하기 / 복사하고 삭제하기 - Recursive copy cycle의 구현

VBA로 데이터를 정리하다보면 어떤 범위의 데이터를 옮겨야 하는 경우가 자주 있습니다.

(여기서부터는 작성 배경입니다.)
전에 말씀드렸습니다만 기본적으로 저는 인덱싱 방식으로 인덱스로 처리하다보니 코드가 main에 위치를 하고 가독성이 나빠지고 중간에 하나 skip이라도 할라면 완전 코드가 꼬여가지고 스파게티도 그런 스파게티가 없더라고요!!

in-house program 개발하다보면 사용하시는 분들의 VOC도 일하시다보면 바뀌는 경우가 있고,(어쩔 수 없다고 생각합니다. 제품 평가 중엔 역시 어떤 factor가 주인자인지 예상하기가 힘드니까 말이에요)
또 전산전문부서가 아닌 일반부서 유저는 전사용 ERP System과 호환성도 고려할 필요도 있기 때문에, SW 고속 개발과 높은 완성도를 위해서는 역시 가독성과 생산성이 좋은 모듈이 필수라고 생각을 했습니다.

그러다보니 고안한 범용 모듈 컨셉이 recursive cycle인데, 아마 다른 분들도 꽤 많이 쓰셨을 것 같습니다만 저도 정리하기 위해서 작성해보려고 합니다.


----
(여기서부터는 소스 작성 부분입니다.)


Copy 모듈의 Recursive는 굉장히 간단합니다.
StartPoint[Sheet명 / Cell주소]와 TargetPoint[Sheet명 / Cell주소], Offset만 있으면 됩니다.
그리고 데이터 연결을 시켜준 뒤 Offset 값에 1을 더해서 Return 해주는 것을 반복하는데, Cell이 빈칸일 때 While을 정지시켜버리면 되겠죠!

아래와 같이 테스트 코드를 동작해보면 역시 연결된 셀은 모조리 복사가 되네요! Good!

다음으로는 Copy & Delete인데 큰 차이는 없습니다.
Return전에 Sheets(StartPoint(0)).Range(StartPoint(1)).Offset(0,OffsetValue).Value를 삭제해버리면 되니까요!

긴 설명 없이 아래의 코드 (A2 -> A5 Copy 후에, A5 -> A8 Copy & Delete 실행)해보면 역시 계획대로네요! Excellent!




----- (VBA Module.xlsm)
Function Shims_Copy(ByRef StartPoint() As String, ByRef TargetPoint() As String, OffsetValue As Integer) As Integer
    'Let's set each argument[0] as the name of worksheet / argument[1] as the name of cell
    Sheets(TargetPoint(0)).Range(TargetPoint(1)).Offset(0, OffsetValue).Value = Sheets(StartPoint(0)).Range(StartPoint(1)).Offset(0, OffsetValue).Value
    Shims_Copy = OffsetValue + 1
End Function

Function Shims_CopyAndDelete(ByRef StartPoint() As String, ByRef TargetPoint() As String, OffsetValue As Integer) As Integer
    'Let's set each argument[0] as the name of worksheet / argument[1] as the name of cell
    Sheets(TargetPoint(0)).Range(TargetPoint(1)).Offset(0, OffsetValue).Value = Sheets(StartPoint(0)).Range(StartPoint(1)).Offset(0, OffsetValue).Value
    Sheets(StartPoint(0)).Range(StartPoint(1)).Offset(0, OffsetValue).Clear
    Shims_CopyAndDelete = OffsetValue + 1
End Function

Sub Test()
    Dim DepArray(0 To 1) As String, DesArray(0 To 1) As String
    Dim OffsetValue As Integer
    OffsetValue = 0
    DepArray(0) = "Sheet1"
    DesArray(0) = "Sheet1"
    DepArray(1) = "A2"
    DesArray(1) = "A5"
    While (Sheets(DepArray(0)).Range(DepArray(1)).Offset(0, OffsetValue).Value)
        OffsetValue = Shims_Copy(DepArray, DesArray, OffsetValue)
    Wend
 
    OffsetValue = 0
    DepArray(0) = "Sheet1"
    DesArray(0) = "Sheet1"
    DepArray(1) = "A5"
    DesArray(1) = "A8"
    While (Sheets(DepArray(0)).Range(DepArray(1)).Offset(0, OffsetValue).Value)
        OffsetValue = Shims_CopyAndDelete(DepArray, DesArray, OffsetValue)
    Wend
End Sub


(이하는 헛소리입니다)
회사에선 역시 Excel 데이터가 많다보니까 이러한 요소처리 모듈이 꽤나 많이 필요하다고 생각합니다. 최근 오다를 받은게 있어서 한 번은 작성해야지... 하면서 뒤로 미루다가 이제서야 작성을 했네요 ㅋㅋ.. 게으르지 않다면 더 좋은 결과가 나올텐데 말이죠~~

VBA는 특히 kernel32.dll과 함께 사용하면 시리얼/이더넷장비 결과를 읽어들이면서 바로 정보처리가 매우매우 손쉽게 되는 장점이 있다고 생각합니다. 제가 역량이 너무 부족해서 아직은 해당 프로그래밍을 이해를 못하다보니 설명을 못드리는 상황이지만, 언젠가 이해하게 되면 정리하는 겸사겸사 외부 장비제어 프로그래밍 소스를 제공해드릴 수 있는 수준이 되면 업로드 할 것입니다. ㅎㅎ

※아래 링크로 들어가보시면 한 선생님께서 만드신 좋은 소스가 있으니까 도움이 되실 것 같습니다. 이 소스를 조금 수정하면 다중 장비 제어도 사용이 가능합니다.

http://egloos.zum.com/snowxtal/v/1509308



댓글

이 블로그의 인기 게시물

(Node.js) XLSX로 결과 출력하기 / 모듈 디자인 Exporting / Node.js modular design

(VBA) 009 - 닫힌 파일에서 데이터 읽어오기 (ExecuteExcel4Macro)

(Node.js) EUC-KR을 Cheerio - Iconv-lite로 불러올 때