지난 포스팅에서 엑셀을 다루는 직장인이나 학생분들을 위한 프로그램을 소개했습니다.
두 파일에서 같은 값으로 검색하기
엑셀에서 덕질할 캐릭터들 MBTI를 정리하다가 두 파일이 순서가 다른 경우 옮겨 적을 때 곤란할 때가 많습니다. 이때 사용하기 위해 두개의 파일에서 위와 같이 한 값이 섞였을 때 사용할 수 있게
devris.tistory.com
이번 시간에는 코드를 리뷰해보겠습니다
우선 엑셀을 다루기 위한 openpyxl 라이브러리를 설치해줍니다
pip install openpyxl
상단에 임포트 해줍니다
import openpyxl
우선 GUI로부터 실행버튼이 눌리면 onClick 이벤트로 메인 함수가 실행되는 게 이 프로그램의 전부입니다.
( 물론 세부적으로 xls 파일을 xlsx 로 변환하는 함수나 선택된 xlsx파일의 모든 sheet를 찾는 함수도 있지만 보조적인 함수이므로 넘어가겠습니다 )
전체적인 메인함수입니다
def buttonStart_pressed(file1, file2, sheetA, sheetB, row1A, row2A, col1A, col2A, row1B, row2B, col1B, col2B):
wb1 = openpyxl.load_workbook(file1)
wb2 = openpyxl.load_workbook(file2)
sheet1 = wb1[sheetA]
sheet2 = wb2[sheetB]
data1 = sheet1[str(col1A)+str(row1A):str(col1A)+str(row2A)]
data2 = sheet1[str(col2A)+str(row1A):str(col2A)+str(row2A)]
data3 = sheet2[str(col1B)+str(row1B):str(col1B)+str(row2B)]
data4 = sheet2[str(col2B)+str(row1B):str(col2B)+str(row2B)]
for row in data1:
for row2 in data3:
if row[0].value is not None:
if row[0].value == row2[0].value:
# 실제 동작 부분
sheet2[str(col2B)+str(row2[0].row)].value = sheet1[str(col2A) + str(row[0].row)].value
result_file = file2.split('.xlsx')[0] + "(result).xlsx"
wb2.save(result_file)
print(" 실행 완료 ")
해석
def buttonStart_pressed(file1, file2, sheetA, sheetB, row1A, row2A, col1A, col2A, row1B, row2B, col1B, col2B):
부분적으로 해석을 해보면 함수에서 받는 매개변수는 두 개의 파일이므로 file1, file2이고 각각의 시트를 sheetA, sheetB로 네이밍 했습니다.(이제 보니 sheet1, sheet2로 해도 괜찮았겠네요..)
각각의 시트마다 행이 2개, 열이 2개이므로, 시트당 4개의 인자, 2개의 시트이므로 총 8개의 인자를 받아와야 합니다.
(row는 행, column은 열입니다.)
변수 선언
wb1 = openpyxl.load_workbook(file1)
wb2 = openpyxl.load_workbook(file2)
sheet1 = wb1[sheetA]
sheet2 = wb2[sheetB]
data1 = sheet1[str(col1A)+str(row1A):str(col1A)+str(row2A)]
data2 = sheet2[str(col1B)+str(row1B):str(col1B)+str(row2B)]
2개의 파일에서 값을 가져오기 때문에 1,2 두 개씩 변수를 만들겠습니다.
- openpyxl의 load_workbook메서드를 이용해서 workbook을 뜻하는 wb변수에 할당합니다
- 인자로 받은 sheet명을 wb변수에서 찾아 sheet1, sheet2라는 변수에 할당합니다
- sheet1이라는 변수는 시트 하나를 뜻하며, 특정 데이터를 얻고 싶을 경우 sheet1 ["A1:B2"]와 같은 식으로 입력하면 됩니다
- 우리는 인자로 행과 열을 받았으므로 str함수로 문자열 타입으로 넣어서 data1, data2, 변수를 만들겠습니다 ( data 변수는 리스트 타입의 셀 데이터겠지요. data = [ A1, B1, C1 ]과 같은 구성 )
반복문
for row in data1:
for row2 in data2:
if row[0].value is not None:
if row[0].value == row2[0].value:
sheet2[str(col2B)+str(row2[0].row)].value = sheet1[str(col2A) + str(row[0].row)].value
file1과 file2에서 각 row마다 반복문을 돌면서 col1이 같은 값을 찾고, 같을 때의 col2의 값을 file1=> file2로 연결합니다.
- 첫 번째 for문은 file1이고, 두 번째 for문은 file2이며 1행부터 끝까지 같은 값을 찾습니다
- 중간에 is not None은 만약 data1의 값이 없을 경우 실행하지 않도록 하기 위해서입니다(data2에 대해서도 체크해도 괜찮을 거 같네요)
- row[0].value == row2[0].value 부분이 동일한 부분을 체크하는 부분이며, 이때 sheet2[].value에 shee1[].value값을 넣는 동작을 합니다
결과 파일 생성
result_file = file2.split('.xlsx')[0] + "(result).xlsx"
wb2.save(result_file)
print(" 실행 완료 ")
마지막으로 file2로 받은 파일명 뒤에 (result)를 붙인 파일로 다른 이름으로 저장을 한 후 끝납니다
입력받는 data1, data2가 두 파일이 동일한 값이 있을 때 옮겨주는 알고리즘에 대해 알아보았습니다.
코드가 엑셀 값 중 필요한 부분을 함수화 하는 게 대부분이고, 실제 동작하는 부분은 한 줄 밖에 되지 않는 생각보다 간단한 코드입니다. 이런 단순한 코딩 한 줄이면 수백 수천 줄의 노가다가 1초도 안 되는 시간에 동작한다는 점이 매우 이로운 거 같네요.
엑셀 노가다를 하는 사람이 조금이라도 줄기를 바라며 포스팅을 마치겠습니다.
댓글