- 질문 게시판입니다.
Date 19/02/28 13:08:04
Name   Crimson
File #1   navdf.PNG (77.3 KB), Download : 6
Subject   엑셀 or 파이썬을 이용한 반복작업 질문입니다


티타임에 남긴 글에서 댓글로 파이썬을 추천해주시는 분이 많아서 기초강의를 3회 정도 (거의)정주행 했습니다.

프로그래머스의 입문강좌, 점프 투 파이썬, 코딩도장의 파이썬 강좌

어느정도 파이썬에 대해 맛은 봤고 수식을 보면 더듬더듬 이해는 가는 정도인데 딱히 써먹으려 하니 활용법도 모르겠고

연습문제를 푸는 정도에서 멈추어 있는 상태입니다

그러던 중 회사에서 업무를 시켰는데 보자마자 파이썬이 생각 났습니다

사진에 보이는것처럼 양식에 고객 데이터를 기입하여 출력하는 작업입니다

실제로는 4가지의 양식과 100명이상의 고객 데이터가 주어져 있어 수동으로 하려니 한숨부터 나오네요

양식을 엑셀로 만들고 이름, 생년월일 등을 파이썬 openpyxl을 활용해 for 문을 이용해서 셀 주소만 바꿔가며 입력시키면 될 것 같다는 생각은 떠오르는데 구체적인 방법을 모르겠네요 구글에 검색해도 원하는 정보를 찾지 못한 상태입니다

알고리즘은 간단할것 같은 작업이라 엑셀의 매크로? VBA? 를 활용할수도 있을것 같은데

방법을 아시거나 혹은 저런 유형의 작업을 배울 수 있는 사이트 등을 알려주시면 공부해서 활용해보겠습니다



0


seonnyseo
정규표현식으로 원하는 데이터를 찾아서 csv로 저장하면 말씀하신대로 할 수 있을 것 같은데,
양식이 원래 엑셀인지 어떤 것인지에 대해 좀 더 자세히 말씀해주시면 좋을 것 같습니다.
Crimson
양식이 한글파일도 있고 PDF 파일로도 있어서 직접 엑셀파일로 뜯어고치는 중입니다.
Crimson
간단한거 하나 아래 댓글에 링크 올렸습니다 참고해주세요
호라타래
엑셀 파일을 하나 올려주시면 짤 수 있을 듯하옵니다

이름만 자동으로 넣고 나머지는 수기로 해야하는 가장 간편한 양식과 명단 첨부하겠습니다
Crimson
댓글 파일선택은 엑셀은 안올라가는지 해봐도 안되서 구글 스프레드시트 링크 남겨볼께요
https://docs.google.com/spreadsheets/d/1_QnKiH9jphlUTGs0j2P7GeGgF4bUIulN-VeyN2yVlIg/edit?usp=sharing
호라타래
넵넵, 지금은 회사라 구글 이용이 불가능하니 퇴근하고 살펴보겠습니다. 논의하면서 한 번 작업해봐요. 내일부터는 휴일이니 ㅎㅎ
열심히 찾아보고 데이터 넣는것까진 성공했는데 파일 저장할때 각각의 이름으로 하고 싶은데 이게 안되고 있어요
값으로 이름을 만드는게 아니라 수식으로 이름을 만들어 버리네요 ㅜ
호라타래
이제 좀 정신을 차렸습니닷

1. openpyxl을 이용해 파이썬 상에서 엑셀 파일을 생성하고, 양식을 조정한다.
2. 고객 데이터를 타겟으로 한 위치에 입력한 후 저장한다.
3. for 문을 이용하여 반복한다.

올려주신 데이터를 기반으로 코드를 간략하게 짜보면

# 라이브러리 불러오기

import pandas as pd
from openpyxl import Workbook
from op... 더 보기
이제 좀 정신을 차렸습니닷

1. openpyxl을 이용해 파이썬 상에서 엑셀 파일을 생성하고, 양식을 조정한다.
2. 고객 데이터를 타겟으로 한 위치에 입력한 후 저장한다.
3. for 문을 이용하여 반복한다.

올려주신 데이터를 기반으로 코드를 간략하게 짜보면

# 라이브러리 불러오기

import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment

# 엑셀 파일 불러와서 명단만 끌어오기
data = pd.read_excel("fall.xlsx", sheet_name="명단", header = None)

# 엑셀 양식 파이썬으로 만들기(기초적으로)
wb = Workbook() # 워크북 생성
ws = wb.active # 활성화
ws.merge_cells('A1:B2') # A1:B2까지 셀 합치기 - 양식 조정을 위한 예시
ws['A1'] = '수급자명:' # A1:B2까지 합친 셀은 A1으로 찾아들어갈 수 있음. 합친 셀에 글자 입력
name=ws['A1'] # 작업하는 셀을 하나의 변수로 저장
name.alignment = Alignment(horizontal = 'right', vertical = 'center') # 해당 변수의 스타일 조작(글자 위치 조정)
ws.merge_cells('C1:D2') # C1부터 D2까지 합친 후 셀을 합침
ws['C1'].alignment = Alignment(horizontal = 'left', vertical = 'center') # 변수를 따로 생성하지 않고, 병합한 셀 내 글자 위치 조정

# 데이터 입력 및 저장
for i in range(1, 30): # 테스트 용도로 30개만 for문을 돌려봄
ws['C1'] = data[0][i] # 위에서 불러왔던 명단 데이터를 앞서 합쳐둔 빈 셀에 입력.
wb.save('test%d.xlsx' %i) # 이름을 각기 다르게 하여 저장
Crimson
뒤늦게 알게 되었는데 xlrd 라는 패키지 설치를 안한게 문제였네요
설치하고 실행하니 제대로 생성되었습니다. 죄송..
호라타래
괜찮습니다 ㅎㅎㅎ 각자 세팅이 다르니 당연히 생기는 일이지요.
호라타래
저는 주피터 노트북으로 작업했는데, 위 코드를 한 번 실행해 보실래요? 컴공이 전공이 아니라 코드가 깔끔하거나 효율적으로 짜여있지는 않지만... 위 방식을 따라가면 원하시는 방식을 구현할 수는 있을 듯해요.

미리 양식을 엑셀로 짜놓은 이후에, openpyxl로 불러오면 그대로 양식이 유지될지도 모르겠네요. 이 경우에는 파이썬에서 일일히 작업하는 부담을 줄일 수 있을텐데 체크해봐야겠어요.

http://www.hanul93.com/openpyxl-basic/

전 위 링크를 참고했습니다.
그 사이에 거의 해결하셨네요! 다행입니다 :)

수식으로 이름이 들어가요? 혹시 저장에 쓰는 코드만 보여주실 수 있으신가요 ㅎㅎ 포맷팅 문제라면 간단한 거예요!
Crimson
일단 올려주신 코드상에서는 이런 에러가 떠버렸네요

ws['C1'] = data[0][i] # 위에서 불러왔던 명단 데이터를 앞서 합쳐둔 빈 셀에 입력.
^
IndentationError: expected an indented block
호라타래
그거 아마 들여쓰기 오류일텐데,

for i in range(1, 30):
ws['C1'] = data[0][i]
wb.save('test%d.xlsx' %i)

를 바로 복붙하지 마시고

for i in range(1, 30): ws['C1'] = data[0][i]

로 올리셨다가, : 옆에서 엔터를 누르셔서 자동 들여쓰기 되도록 조정하시면 될 거예요.
Crimson

사진 첨부합니다
호라타래
Indentation 오류는 들여쓰기 오류인데 흐음... 작업환경이 달라서 달리 인식하는 걸지도 모르겠네요.
Crimson
from openpyxl import load_workbook
wb = load_workbook(filename='pt.xlsx', data_only=True)
ws1 = wb['1']
ws2 = wb['2']
ws3 = wb['3']
ws4 = wb['4']
ws5 = wb['5']
for i in range(2,10):
... 더 보기
from openpyxl import load_workbook
wb = load_workbook(filename='pt.xlsx', data_only=True)
ws1 = wb['1']
ws2 = wb['2']
ws3 = wb['3']
ws4 = wb['4']
ws5 = wb['5']
for i in range(2,10):
name = "=5!a%d" % i
ws1['I8'] = name
ws2['g4'] = name
ws3['d13'] = name
ws4['b9'] = name
wb.save('%s.xlsx' %name)

제가 만든 코드인데 저장할때 =5!a2.xlsx, =5!a3.xlsx 이런식으로 마지막 숫자만 커지며 수식으로된 파일이 생성되네요
네네, 문자열 포맷팅 논리가

"=5!a" + "%d" + %i
(for문을 통해 i에 들어오는 값들을 %d 위치로 집어넣기)

로 되어있으니

for i in range(2,10):
name = "=5!a%d" % i
print(name)

를 하면 결과가

5!a2
5!a3
5!a4
...

로 되네요.

pt.xlsx 파일이 없어서 추측하자면

5개의 워크시트가 있는데,

워크시트 1의 l8, 2의 g4, 3의 d13, 4의 b9에 name을 각각 입력하는 코드 같은데... 더 보기
네네, 문자열 포맷팅 논리가

"=5!a" + "%d" + %i
(for문을 통해 i에 들어오는 값들을 %d 위치로 집어넣기)

로 되어있으니

for i in range(2,10):
name = "=5!a%d" % i
print(name)

를 하면 결과가

5!a2
5!a3
5!a4
...

로 되네요.

pt.xlsx 파일이 없어서 추측하자면

5개의 워크시트가 있는데,

워크시트 1의 l8, 2의 g4, 3의 d13, 4의 b9에 name을 각각 입력하는 코드 같은데

name은 원하시는대로 들어갔나요?

지금 쓰인 방식이라면 name도 수식으로 5!a2, 5!a3 등이 name이 들어가야 하는 칸에 들어갈 것 같거든요.
Crimson
네 맞습니다.
'1','2','3','4' 라는 이름의 시트에 '5'라는 시트에 A2 A3 A4 ~~~ 에 위치한 명단을 넣기위해
5! 시트
a%d 셀주소
를 이용해서 이름을 넣어봤는데 name 은 제대로 들어가있습니다
코드는 같은데 파일로 저장할때만 값이아닌 수식이 출력되네요
이것도 openpyxl의 한계인건지 뭔지;
호라타래
그러면 for문 내에서 바로 시트에서 데이터를 불러오게 하지 마시고,

for문 밖에서 참고할 데이터의 리스트를 따로 불러내어 변수로 저장한 이후에

그 리스트를 for 문에서 i에 맞추어서 하나씩 열거하는 식으로 해보셔요
호라타래
제가 추측하는 바가 맞는 듯하네요.

써주신 코드를 fall.xlsx에 맞춰서 변형해보면

from openpyxl import load_workbook
wb = load_workbook(filename='fall.xlsx', data_only=True)
ws1 = wb['양식']
ws2 = wb['명단']
for i in range(2,10):
name = "=명단!a%d" % i
ws1... 더 보기
제가 추측하는 바가 맞는 듯하네요.

써주신 코드를 fall.xlsx에 맞춰서 변형해보면

from openpyxl import load_workbook
wb = load_workbook(filename='fall.xlsx', data_only=True)
ws1 = wb['양식']
ws2 = wb['명단']
for i in range(2,10):
name = "=명단!a%d" % i
ws1['l4'] = name
wb.save('%s.xlsx' %name)

로 조정해서

두 번째 시트에 있는 명단을 첫 번째 양식의 l4에 기입하도록 했어요.

엑셀 파일을 열어보니

서명자 위치에 "명단!A2", "명단!A3"... 방식으로 수식이 하나씩 입력되면서 데이터를 끌어오는 식으로 구성되네요.

근데 이거는 엑셀 내부에서 서로 형님 아우 하는 느낌이고

엑셀보다 위에서 파일을 관리하는 파이썬 입장에서는 '이게 무슨 소리여' 할 것 같아요.
파이썬에서는 '명단!A2'라고 했을 때 엑셀처럼 알아듣지 못하니까요.

그러니 제 킹리적 갓심으로는 아래처럼 코드를 변형하시면 될 것 같습니다.

from openpyxl import load_workbook
wb = load_workbook(filename='pt.xlsx', data_only=True)
ws1 = wb['1']
ws2 = wb['2']
ws3 = wb['3']
ws4 = wb['4']
ws5 = wb['5']
namelist=[]
for row in ws5.rows:
namelist.append(row[0].value)
for i in range(2,10):
name = "=5!a%d" % i
ws1['I8'] = name
ws2['g4'] = name
ws3['d13'] = name
ws4['b9'] = name
wb.save('%s.xlsx' %namelist[i])
아앗!! 해결되었습니다!!
1
Crimson
아 그리고 하나만 더!
현재 샘플로 올린fall 파일 안에있는 양식과 명단이라는 시트가 있는데
사실 양식으로 쓸 시트가 4가지 명단시트 1가지 총 5개 시트인데
인쇄하려고 보니 한번에 통합인쇄를 하면 명단시트가 딸려나와서

for i in range(2,10):
wb = load_workbook(filename='~{}.xlsx'.format(i))
ws5 = wb['5']
wb.remove_sheet(ws5)
wb.save('x~{}.xlsx'.f... 더 보기
아 그리고 하나만 더!
현재 샘플로 올린fall 파일 안에있는 양식과 명단이라는 시트가 있는데
사실 양식으로 쓸 시트가 4가지 명단시트 1가지 총 5개 시트인데
인쇄하려고 보니 한번에 통합인쇄를 하면 명단시트가 딸려나와서

for i in range(2,10):
wb = load_workbook(filename='~{}.xlsx'.format(i))
ws5 = wb['5']
wb.remove_sheet(ws5)
wb.save('x~{}.xlsx'.format(i))

이용해서 명단시트를 제거하니 양식 시트에 값이 안닌 수식오류가 떠서 값으로 어떻게 바꾸나 찾아보니 openpyxl 의 한계라고 나오네요

이런 경우 시트를 분리해서 양식파일.xls 명단파일.xls 두개로 만들어서 코드를 다시 짜야할까요?
시트 안에서 코딩은 얼추 하겠는데 파일 2개로 불러오는건 찾아보니 잘 안나와서 힘드네요
호라타래
명단에서 데이터를 불러와서, 양식 시트에 바로 넣는 방식이 아니라

명단에서 불러온 데이터를 작업 환경에 변수로 지정 -> 명단 시트 제거 -> 양식 시트에 따로 저장한 값 삽입 -> 다른 이름으로 조정한 명단 시트 저장 -> 통합 인쇄

요런 방식은 어떨까요?
아 환경변수로 지정하는 방법이 있군요
그게 위에서 코딩하신거구요
파일 이름이야 정 안되면 그냥 손으로 해버리면 되는데
이건 꼭 해결해야할 문제였는데 다행이네요
감사합니다
Crimson
도움 주셔서 감사합니다
카톡아이디나 메일주소 쪽지로 보내주시면
감사의 의미로 기프티콘 하나 드릴께요
소소한거라 부담없이 받으세요
1
미스터주
실질적 조언은 아니어서 죄송하고... 격려하고 싶은건 맘먹으신 대로 한번 코딩 도전하셔서 이루어 내셨으면 좋겠습니다.
코딩하는데 막히다보면 아 이거 걍 손으로 일일이 쓰는게 더 빠르겠는데 생각이 들때가 있는데 그거 극복하시고
한번 이렇게 코딩으로 짜보시면 다음에 비슷한 류의 Python-엑셀 코딩하시는데 훨씬 속도가 붙으실겁니다
힘내세요! 제 생각에 하실수 있을것 같습니다.
미스터주
약간만 덧붙이면 openpyxl 활용이라는 솔루션을 찾으셨다면 제생각에 원하시는거 달성은 어렵지 않을것같아요.
바로 코딩에 들어가기 전에 순서도(flowchart) 를 그려보면 어디에 뭘 구현해야 원하는 바를 이룰수 있는지 명확한 계획이 세워지기 때문에 훨 나은데
정말로 순서도 기호 맞춰가면서 그리는것까지는 안하셔도 프로그램의 input, output을 일단 두고 어떤 식으로 처리해야 원하는 바를 이룰지 한번 그림 형태로 그려보세요.
그럼 각각의 기능에서 맞는 모듈이나 함수를 openpyxl 에서 검색해서 찾기만 하면 됩니다.
Crimson
격려 감사합니다. 문제풀이 말고 첫 실전 업무라 시행착오도 많고 시간도 오래 걸릴듯한데 이번에 성공해 내면 다음부터 비슷한 업무는 굉장히 편하게 할 수 있을것 같아 포기하지 않고 해보려고 하고 있어요!!
보이차
일단 기존 양식을 엑셀로 만들어 뽑아도 되는지부터 확인하세요..
Crimson
네 혹시나 하고 확인해봤는데 내용만 같으면 문제없다는 답변 받았습니다.
보이차
말씀하신 기능을 가장 쉽고, 빠르고, 일반적으로 구현하는 방법은 이렇습니다.
1. (손으로) 양식(워드/엑셀 양식 무관)에 중복되지 않을 예제 혹은 ID값을 채운다.
2. (파이썬 코드에서) 양식과 데이터 파일을 연다.
3. (파이썬 코드에서) 양식에 채웠던 값을 데이터 파일의 값으로 치환(찾아 바꾸기)한 후 다른이름으로 저장한다.
Crimson
저는 엑셀의 개념으로 a1:a100 의 데이터를 다른 시트의 $c$2 에 넣는다고만 생각하고 있었는데
임의의 값을 넣고 치환하는게 훨씬 파이썬스럽네요
정답은 없겠지만 이 방법이 더 좋아보이네요
감사합니다
한글이라면 메일머지 사용해보세요
Crimson
아니 이렇게 강력한 기능이?!?!?!?!!!!!!!!!!!!!!!!!!
목록
번호 제목 이름 날짜 조회 추천
8711 기타의사분들 직급 영문명 아시는분 계실까요? 35 정중아 20/01/31 9026 0
13661 IT/컴퓨터애플워치 소리 끄는 법 아시나요? 4 Thy킹덤 22/07/21 9018 0
8329 체육/스포츠발목 안좋을 때 유산소로 자전거 괜찮을까요? 20 Moleskin 19/11/23 9014 0
3156 IT/컴퓨터c++ 공부 하는데 얼마정도 걸리나요? 6 지식의늪지대 17/08/06 8998 0
11145 의료/건강‘의자는 비싼 거 써야 한다’는 통념이 얼마나 사실인가요? 25 21/03/07 8963 0
692 진로기계공학과 기계설계 취업할때 같은 기계계열로 되나요?? 4 불꽃늑대 16/01/05 8963 0
4089 문화/예술전자책 단말기 추천해주세요 7 로사 18/02/01 8957 0
6672 IT/컴퓨터엑셀 or 파이썬을 이용한 반복작업 질문입니다 36 Crimson 19/02/28 8951 0
9262 의료/건강군대에서 이빨 부러졌는데 도와주세요ㅜㅜ 26 벚문 20/04/23 8946 0
6602 기타벽지간 이음매 불량은 도배하자인가요? 6 별다섯그랑호텔 19/02/19 8942 0
8490 연애직장 동료에게 관심이 있다면 어떻게 다가가야 할까요 22 [익명] 19/12/17 8941 0
3261 가정/육아무쇠팬은 빢빢 긁으면 안되나요? 15 별빛 17/08/24 8940 0
9340 법률민방위 4년차인데 군복 버려도 될까요? 11 [익명] 20/05/05 8937 0
7997 기타동종업계 이직금지 조항, 외국에도 있나요? 31 kaestro 19/10/07 8929 0
10726 진로야간대 졸업하신분 계신가요? 12 copin 20/12/27 8926 0
11101 문화/예술왕좌의 게임은 어디까지 봐야 제일 재미있나요? 24 데자와왕 21/02/26 8920 0
7751 기타천장 매립등 접지선 따로 처리하지 않고 달아도 괜찮나요? 4 호미밭의 파스꾼 19/08/27 8917 0
746 의료/건강프로페시아와 임신 16 난커피가더좋아 16/01/21 8914 0
34 체육/스포츠버피테스트 질문입니다. 8 스파토이 15/06/03 8909 1
12 기타이곳의 배너광고는 어찌되는건가요?? 9 Yato_Kagura 15/05/30 8909 0
5536 기타가정용 보일러 추천받습니다. 6 April_fool 18/09/28 8901 0
4546 기타DSLR을 구입하였습니다! 18 솔구름 18/04/29 8892 1
6202 교육철학과 선배님들께 소소한 질문하나 드려요 76 식지 19/01/01 8887 4
8157 게임게임 안하는 30대 남성 분들은 뭘 하고 노시나요 44 불타는밀밭 19/10/31 8875 0
5426 게임데드셀 파밍 요령이 있나요? 4 Weinheimer 18/09/10 8854 0
목록

+ : 최근 2시간내에 달린 댓글
+ : 최근 4시간내에 달린 댓글

댓글