글목록

2021년 3월 31일

엑셀 시트 데이터 읽기/쓰기 (1)

엑셀 워크시트에 있는 데이터를 읽어오거나 쓰는 방법에 대해 간단히 설명드립니다.


VBA 편집기를 열고, 프로젝트 탐색기에서 현재 엑셀 파일의 마우스 오른쪽 버튼 > 삽입 > 모듈을 클릭하여 새 모듈을 추가합니다.

엑셀의 A1 셀의 데이터를 변수 a에 읽어온다고 하면,

a = Cells(1, 1).Value

와 같이 해주면 됩니다. 여기에서 앞의 1은 열 번호, 뒤의 1은 행 번호입니다.

만약, B5 셀의 데이터라면, a=Cells(5, 2).Value라고 하면 됩니다.

B5는 셀의 주소이며, B는 열(Column) 번호이며, 5는 행(Row) 번호입니다.

엑셀의 주소 형식은 B5와 같이 열-행 순서이나, Cells()로 표시하여 특정 셀의 값을 읽을 때에는 Cells(행번호, 열번호)와 같은 형식으로 입력해주게 됩니다. 순서가 뒤바뀌기 때문에 실수하기 쉽습니다.


각 셀의 값은 문자형, 숫자형, 날짜, 시간 등 다양한 형식으로 지정되며, Variant 타입입니다. 만약, 날짜 형식을 숫자로 대입하려고 한다면, 

a=Cells(2, 5).Value2

라고 하면, 날짜나 시간 형식이 아닌 숫자 형식(Double)으로 대입하게 됩니다. 아래의 두 그림을 비교하시면 쉽게 이해가 가실 겁니다.

Sub Test1()
  Dim a
  a = Cells(1, 1).Value
  MsgBox a
End Sub


Sub Test2()
  Dim a
  a = Cells(1, 1).Value2
  MsgBox a
End Sub


1개의 셀을 입력받아야 할 때도 있지만, 여러 개의 데이터를 입력받아야 하는 경우도 있습니다. 이럴 때에는 아래와 같이 배열을 이용하면 됩니다. 예를 들어, 셀 A1에서 셀 A10의 값을 읽어오려고 한다면,

Sub Test1()
  Dim a(1 To 10), i As Integer
  For i = 1 To 10
    a(i) = Cells(i, 1).Value
  Next
End Sub


여러 개의 행, 열의 데이터를 읽어오려면 2차원 배열을 이용할 수도 있습니다.

예를 들어, 셀 A1에서 셀 E10의 범위에 있는 값을 읽어오려면, 

Sub Test1()
  Dim a(1 To 10, 1 to 5), i As Integer, j as Integer
  For i = 1 To 10
    For j = 1 to 5
      a(i, j) = Cells(i, j).Value
    Next
  Next
End Sub


만약, 읽어오려는 범위가 A1 셀에서 시작하지 않는다면 어떻게 해야할까요?

위의 2차원 배열을 사용할 때, A=1, B=2, ... 로 대입해서 i, j 변수가 어렵지 않게 지정될 수 있었지만, 만약, C2에서 F5 범위의 값을 읽어오려고 하면 코드가 복잡해집니다.

이렇게 지정하는 범위가 다양하거나, 갯수가 수천~수만개의 데이터를 읽어오려고 한다면, 각각의 셀에 접근해서 값을 읽어오는데 수많은 반복 작업을 하게 되어 시간이 오래 걸립니다.

예를 들어, 100개의 열에 있는 10000개의 데이터를 읽어온다면, 100만개의 셀 데이터를 읽어와야하는데, 이러한 작업을 실행해보면, 상당히 오랜 시간이 걸리는 것을 알 수 있습니다.

엑셀에서는 이러한 작업을 쉽게 생략할 수 있도록 배열 변수에 바로 특정 범위의 값을 지정하는 방법이 있습니다.

Sub Test1()
  Dim a(1 To 10000, 1 To 100), i As Integer
  For i = 1 To 10000
    For j = 1 To 100
      a(i, j) = Cells(i, j).Value
    Next
  Next
End Sub

Sub Test2()
  Dim a()
  a = Range(Cells(1, 1), Cells(10000, 100)).Value
End Sub

위의 두 프로시저는 동일하게 100만개의 데이터를 읽어오는 것입니다만, Test1은 각각의 셀 데이터를 읽어오는 반면, Test2는 Cells(1,1)과 Cells(10000, 100) 사이의 범위에 있는 모든 데이터를 한꺼번에 배열에 읽어오는 프로시저입니다.

범위가 커지면 커질수록, 위의 두 프로시저 사이에 걸리는 시간은 훨씬 크게 차이가 나는 것을 알 수 있습니다.


워크시트에 있는 데이터를 읽어오는 것과 반대로 쓰는 것도 가능합니다만, 배열의 크기에 맞게 Range를 지정해주어야하는 문제가 있습니다.

이와 관련된 내용은 다음에 올리도록 하겠습니다.

댓글 없음:

댓글 쓰기

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

많이 본 글 :