안녕하세요?
일상의코딩 블로그를 운영중인 일코입니다.
업무자동화와 관련한 콘텐츠 제작 및 강의 등을 하고 있습니다.
Courses
Reviews
- Python-Arahan Korean Automation Recipe Essential for Office Workers
- Python-Arahan Korean Automation Recipe Essential for Office Workers
- Python-Arahan Korean Automation Recipe Essential for Office Workers
- Python-Arahan Korean Automation Recipe Essential for Office Workers
- Python-Arahan Korean Automation Recipe Essential for Office Workers
Posts
Q&A
하위의 여러 폴더 중 특정폴더의 사진만 추출하기
안녕하세요?어려운 코드는 아니지만, 두 가지 주제로 분리해서 설명을 드려야 할 것 같습니다. ① 하위 폴더의 모든 파일과 경로를 파이썬으로 가져오기현재 폴더의 파일이나 폴더 목록은 os.listdir() 로 간편하게 구할 수 있지만,하위 폴더의 파일 목록까지 한 번에 구하고 싶으시다면 os.walk() 라는 함수를 쓰시는 것이훨씬 간편합니다. 예를 들어 하위폴더와 파일목록이 아래와 같을 때(사진) 아래와 같은 함수를 정의하여 실행하면(경로명 키를 가진 dict를 정의했습니다. 각 값은 해당 경로의 jpg 파일의 절대경로 리스트입니다.)import os def get_jpg_files_by_directory(root_dir="."): jpg_dict = {} for dirpath, _, filenames in os.walk(root_dir): jpg_files = [os.path.abspath(os.path.join(dirpath, f)) for f in filenames if f.lower().endswith(".jpg")] if jpg_files: # 파일이 있는 폴더만 추가 jpg_dict[dirpath] = jpg_files return jpg_dict결과는 아래와 같습니다.>>> jpg_files_dict = get_jpg_files_by_directory() >>> print(jpg_files_dict) { '.\\sub1': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-3.jpg' ], '.\\sub1\\sub2': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-3.jpg' ], '.\\sub1\\sub2\\sub3': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-3.jpg' ], '.\\sub1\\sub2\\sub3\\sub4': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-3.jpg' ] } 위와 같은 데이터구조를 만들면,하위경로별로 각각의 key가 있고 그 안에 값으로 jpg파일 리스트가 있으므로순차적으로 이미지를 삽입하기 쉽습니다. (물론 더 효율적인 좋은 방법이 있을 수도 있습니다.) ② 아래아한글에 이미지 넣기아래아한글 API가 다소 복잡하므로, 저는 최근에 거의 항상 pyhwpx 모듈을 이용해서간단한 명령어들을 처리하고 있습니다.pyhwpx 모듈에 대한 구체적인 설명은 위키독스(링크)에서 확인하실 수 있습니다. pyhwpx에서는hwp.create_table(rows, cols, treat_as_char)로 간편하게 표를 생성하고,hwp.insert_picture(img) 메서드로 셀 안에서 이미지를 삽입하실 수 있습니다. 아래는 pyhwpx를 통해 위 이미지 목록을 간단히 hwp 파일에 삽입하는 예시코드입니다.(사진)for k in jpg_files_dict.keys(): hwp.set_font(Height=25) # 글자크기를 25로 hwp.insert_text(k) # 경로명 삽입 hwp.BreakPara() # 엔터 hwp.create_table(rows=1, cols=1, treat_as_char=True) # 1x1의 글자취급표 생성 for img in jpg_files_dict[k]: # 경로명 키를 순회하면서 hwp.insert_picture(img) # 경로 내의 jpg파일 삽입 hwp.TableAppendRow() # 아래에 새 셀 생성 hwp.Run("TableSubtractRow") # 마지막에 생성된 빈 셀은 제거 hwp.MoveDown() # 표 아래로 내려가서 hwp.BreakPage() # Ctrl-Enter(페이지 나누기)이런 식으로 활용하실 수 있습니다.라인별 주석을 참고해주시기 바랍니다. 엑셀 파일에 경로가 명시되어 있다면 해당 엑셀파일을 판다스 등으로 가져오셔서os.walk나 위 dict 자료 대신 활용하시면 더 간편할 것입니다.부디 도움이 되었길 바랍니다. 추가 질문은 댓글로 남겨주세요.사실, 질문이 조금 두루뭉실한 느낌입니다. 샘플 데이터가 있으면 확실하게 코드로 보여드릴 수 있는데,아시겠지만ㅜ 제가 똑똑한 편이 아니어서ㅎㅎㅎ질문 자체를 이해하는 것도 상당한 에너지가 필요하네요ㅜ행복한 하루 보내시기 바랍니다!
- 1
- 2
- 60
Q&A
누름틀 적용항목 vs 엑셀항목 간의 순서관련 질문
현우님 안녕하세요!!ㅎ연휴에도 이렇게 열심이신 걸 보면, 보통 분이 아니신데요?ㅎ 질문에 답변을 먼저 드리면,필드와 메일머지는 굉장히 유사하게 작동합니다. 다만, 엑셀에서 값을 가져올 때, 칼럼명을 빼고 값만 가져오는 경우에는말씀하신 것처럼, 작동할 수 있습니다. 이미 메일머지를 통해 값을 입력하는 개념을 잘 알고 계시니저를 포함하여 많은 업무자동화 전문가들이 즐겨 사용하는간편한 방법을 하나 미리 알려드리고자 합니다.강의에서 알려드린 코드는 밑바닥까지 직접 구현한 관계로 굉장히 복잡한데요,원리만 이해하시면 됩니다. 실제로는 이렇게 복잡하게 코딩하지 않습니다ㅜ 죄송 우선은 pywin32를 설치하셨던 것과 동일하게,터미널에서 pip install pyhwpx 명령어로 pyhwpx 모듈을 설치해주시기 바랍니다.(사진)혹은 주피터노트북의 아무 셀에서%pip install pyhwpx라고 한 번만 실행하셔도 됩니다. 설치를 완료하셨으면, 다시 주피터노트북으로 돌아가셔서기존에 입력하셨던 아래 코드를 실행하지 마시고import win32com.client as win32 hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") hwp.XHwpWindows.Item(0).Visible = True hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") 아래의 코드를 대신 실행해보시기 바랍니다.from pyhwpx import Hwp hwp = Hwp()이렇게 아래아한글을 실행해도 대부분의 코드는 동일하게 사용하실 수 있지만,hwp.PutFieldText의 작동방식이 더 간편해지고,hwp.open 실행시, 전체경로를 입력하지 않아도 되는 등몇 가지 기능보완 및 편의기능이 추가되어 있습니다. 그럼 pyhwpx의 PutFieldText 활용예시를 몇 가지 보여드리겠습니다. 1. 엑셀파일 그대로 삽입만약 삽입할 데이터가 들어있는 엑셀파일이 깔끔하게 메일머지 형태로 정리되어 있는 경우hwp.PutFieldText(엑셀파일명)을 실행하면 엑셀의 값이 필드 안에 고스란히 들어가게 됩니다.(사진)질문 주셨던 것처럼, 엑셀문서 B열에 사이에 "별명" 칼럼이 끼어 있지만, 필드에 "별명"이 없으므로 누락되었습니다.이 방법이 제일 간편하다면 간편하지만, 파이썬 단에서 조금도 값을 수정할 수 없으므로미리 엑셀파일 안에 모든 값이 완벽하게 작성되어 있어야 합니다. 2. 엑셀파일을 판다스데이터프레임으로 불러온 후 삽입기왕 파이썬을 시작하셨다면, 꼭 pandas를 공부해보시는 걸 강력히 추천드립니다.엑셀파일을 다루는 것뿐만 아니라, 굉장히 방대한 데이터 처리 기능을 제공하므로비단 아래아한글이나 엑셀 업무자동화 뿐만 아니라 통계나 차트, 각종 분석 등 고급 업무에공부시간이 아깝지 않을 만큼 활용하실 수 있는, 파이썬의 가장 인기있는 라이브러리 중 하나입니다.하여튼, 엑셀파일을 판다스 데이터프레임으로 불러와서가공을 거친 후 삽입도 가능합니다.import pandas as pd df = pd.read_excel("엑셀파일.xlsx") # 데이터프레임 생성 df["특기"] = df["특기"] + "내기" hwp.PutFieldText(df)(사진)이런 방식으로 엑셀파일경로 문자열 대신 데이터프레임(df) 객체를 직접 집어넣을 수도 있습니다. 만약, 필드가 하나만 있고, 데이터프레임에서 특정 행만 넣고 싶은 경우는 아래처럼 실행하시면 됩니다.hwp.PutFieldText(df.iloc[[2]])(사진) iloc 활용방법df.iloc 는 "데이터프레임의 i번째 location"이라는 뜻입니다.i번째 행의 데이터만 골라서 넣겠다는 뜻입니다. 이게 굉장히 유용한 경우가 있는데요.메일머지로는 엑셀의 행 하나하나를 별도의 파일로 저장하는 것이 불가능합니다. 그런데 파이썬으로는 좀 더 세부적인 수준에서 필드를 다룰 수 있으므로,예를 들어 엑셀행이 500개가 있다고 할 때, 500개의 파일을 별도로 생성하는 것이 가능합니다.아래처럼 for문 안에서 실행하시면 됩니다.for i in range(len(df)): hwp.PutFieldText(df.iloc[[i]]) hwp.SaveAs(f"{df["이름"][i]}.hwp")(사진) 엑셀파일경로나 df 뿐만 아니라,파이썬의 리스트나 딕셔너리, 혹은 딕셔너리안의 리스트 자료형도동일하게 pyhwpx의 PutFieldText 기능을 통해 삽입 가능하므로아마 생각하시는 거의 모든 작업은 필드를 통해 가능할 것으로 생각됩니다. 처음 질문 주셨던, "특정 칼럼만 골라서 필드에 삽입" 하는 기능은win32com으로 구현하기에는 굉장히 까다로운 부분이 있는데데이터프레임이나, PutFieldText의 내장기능을 활용하면이렇게 간편하게도 구현할 수 있다는 점을 보여드리고 싶었습니다.답변이 되었을지 모르겠습니다^^;; 하여튼 질문 주셨던 것처럼, 특정 칼럼을 배제하려면딕셔너리 자료형으로 추출을 해서, 특정 칼럼명을 배제하거나아니면 처음부터 특정칼럼을 빼고 리스트로 만들거나........하여튼 상당히 까다롭습니다ㅜ 매번 이걸 코딩하기도 어렵고요. 가급적 위에 제안드린 방식을 한 번 검토해보시고실무에 적용하시는 걸 추천드립니다. 또 자동화하시면서, 혹은 자동화하시고자 하는 업무 관련하여 질문이 있으면언제든 편하게 추가질문 남겨주시기 바랍니다!!!! 감사합니다. 남은 연휴 잘 보내시기 바랍니다.행복한 하루 되세요^^
- 1
- 2
- 77
Q&A
pyinstaller 로 exe 파일을 만들면 환경구축이 안되어있는 PC 에서 실행 불가
sam님, 안녕하세요! 반갑습니다^^회신이 조금 늦었습니다 죄송합니다 현재 이 부분 때문에 코드를 손을 봐야 하는데ㅜ 아직 진행을 못 하고 있습니다.급한대로 익셉션이 나지 않는 방법을 알려드려봅니다.먼저 밝혀둘 것은, 익셉션은 보안모듈 등록 때문에 발생하고 있습니다ㅜㅜㅜㅜ죄송합니다. ① pyinstaller 실행시 바이너리 첨부컴파일하실 때 FilePathCheckerModule.dll 파일을 소스코드와 동일한 폴더에 복사하신 후--add-binary="filePathCheckerModule.dll:." 옵션을 추가해주시기 바랍니다.예를 들면 아래처럼요.pyinstaller -F -w --add-binary="FilePathCheckerModule.dll:." source.py ② FilePathCheckerModule.dll 파일 동봉위 방법으로도 간혹 오류가 나는 경우가 있습니다. (권한문제일까요? 원인을 모르겠습니다ㅜ)그런 경우에는 FilePathCheckerModule.dll 파일을 실행파일과 같이 배포해보시기 바랍니다.만약 동봉하여 배포했음에도 오류가 발생한다면, 사용자 폴더(예를 들어 c:\Users\User\ )에다 FilePathCheckerModule.dll 파일을 복사해보세요.하지만 대~~부분의 경우에는 ①번 방법으로 해결될 것입니다. ③ 극단적인 방법 : 보안모듈 등록하지 않기처음에 hwp 객체를 만드실 때, hwp = Hwp(register_module=False) 라고 초기화하시면익셉션이 발생하는 부분의 코드를 실행하지 않습니다.대신 보안모듈이 등록되지 않으므로 보안승인팝업이 뜨게 됩니다.딱 한 번만 "모두 허용"을 눌러주면 되니 큰 문제가 되지는 않을 듯 합니다. 저도 깔끔하게 잘 되는 모듈을 만들어서 배포를 하고 싶은데오류가 쉽게 고쳐지지 않아 죄송한 마음이 큽니다.혹시 위 방법 중 성공하는 방법이 있다면 공유해주시면 감사하겠습니다. 벌써 설 연휴가 시작되었습니다.행복한 하루, 편안한 명절연휴 보내시기 바랍니다.감사합니다.
- 1
- 2
- 78
Q&A
주피터노트북 코드로 한글파일 열수 없다고 나오는데.....
현우님 안녕하세요?먼저, 질문에 답변을 드리면1. 항상 절대경로 사용아래아한글을 파이썬으로 조작할 때는,주피터노트북이나 파이썬 콘솔의 현재 위치를 인식하지 않습니다.그래서 기본적으로 항상 경로를 입력할 때는 전체경로를 입력해주어야 합니다.이미지를 삽입할 때도, win32com으로 엑셀파일을 다룰 때도 마찬가지입니다. 전체 경로를 입력하지 않으면 해당파일이 아래아한글 설치폴더에 있다고 가정하고 탐색하므로 오류가 나버립니다ㅜ 제일 간편한 방법은 os나 pathlib 등 경로를 다루는 모듈을 쓰는 것입니다. 예를 들어 아래와 같이 입력해보시면, 현재 주피터노트북 위치의 문서를 오류 없이 여실 수 있습니다ㅎimport os # win32com 대신 pyhwpx라는 모듈을 사용하실 수 있는데,이 경우에는 상대경로를 인식하므로, 파일명만 입력하셔도 됩니다.강의 후반부에 pyhwpx를 다루는 예제도 소개드리고 있으니, 참고하시기 바랍니다. 코딩프로그램 사용법ㅜ죄송한 부분입니다. 개인적으로는 여러가지를 써보시고가장 취향에 맞는 하나를 고르시게 하고 싶은 의도였는데그게 어려운 부분이 될 줄은 생각하지 못했습니다. 개인적으로는 파이참 유료버전을 오랫동안 써 왔습니다.파이참에서는 유료버전만 주피터노트북 지원을 하니까요.간단한 코드결과를 확인하거나 할 때는 터미널에서 ipython을 실행하기도 하고요. 파이참과 별개로 무료로 주피터노트북을 사용할 수 있는 다른 옵션이 두 가지가 있는데,하나는 vscode를 쓰는 것이고, 다른 하나는 웹브라우저에서 원조 주피터노트북을 쓰는 것입니다. vscode나 커서IDE는 편리한 기능도 많고, 코파일럿 등 AI 기능지원도 강력하고무엇보다 주피터노트북을 무료로 사용할 수 있는데다, 굉장히 다양한 단축키를 제공하고 있어서처음엔 생소하고, 복잡하게 느껴질 수 있지만, 두세 달 진득하게 사용해보시면코딩을 이렇게 편하게 할 수 있게 지원을 잘 해주는구나 하고 느끼시는 지점이 올 것입니다. 음, 결론은 몇 가지를 체험해보시고 제일 느낌이 좋은 에디터 하나를 주력으로 잡으시는 걸 추천드립니다.최근 대세는 단연코 vscode나, 이를 포팅한 cursor IDE이므로, 이들을 쭉 써보시면 좋겠습니다. 첨언드리면우리같은 코알못이 코딩에 발을 들이는 것 자체가, 대단한 용기가 필요한 일이라고 생각합니다. 그리고. 업무를 더 잘 하고 싶거나, 더 빠르고 정확하게 마치고 싶은 분들이 이 강의를 찾아주시는 거라고 생각하기 때문에, 어떤 코딩 실력에 상관없이 존경스럽기도 하고, 대단하다는 마음도 듭니다.코딩은 아직도, 하면 할수록 어려운 문제를 만납니다. 시간이 지나면서 더 어려워지고 고민이 많아지기도 합니다. 근데 처음엔 오죽할까요^^; 개인적으로 현우님께서 어떤 업무를 하시는지, 또 어떤 업무를 자동화하고 싶으신지 알고 싶기도 합니다. 미흡한 상태로 강의를 공개해놔서, 충분히 원하시는 지식을 얻지 못하실까봐 걱정되기도 하고요.괜찮으시다면 댓글로, 담당하시는 업무 관련한 짤막한 코멘트를 남겨주시거나, 자주 질문글을 남겨주세요. 최대한 상세하게 답글이나 예시 소스코드를 제공해드리겠습니다. 그리고 주피터노트북이나 파이썬에 익숙해지기 전에는 코딩이 더딥니다. 차라리 수작업으로 하고 말지 하는 생각도 들고요. 그런 때는 잠시 코딩 공부를 쉬셔도 괜찮다고 생각합니다. 다만, 꼭 코드에디터를 사용하지 않고도, 이러이런 상황에선 대략 이런 코드를 써야겠지? 하는 연습을 틈틈이 하시다 보면 분명히, 숨쉬듯 자연스럽게 내 생각을 코드로 옮길 수 있는 시점이 찾아올 것입니다. 그 지점부터 코딩실력이 빠르게 향상될 것입니다.당장은 아니겠지만, 그렇다고 너무 먼 미래도 아닐 거고요. 내일 이맘때쯤 업무자동화나 코딩의 고수가 되어있을 현우님을 진심으로 응원합니다. 행복한 하루, 즐거운 설연휴 보내시기 바랍니다. 감사합니다.
- 1
- 2
- 72
Q&A
녹화된 스크립트매크로를 파이썬에서 활용하는 방법 내용이 안보입니다.
혜진님 안녕하세요!해당 영상(?)이 제 실수로 제거가 되어버렸나봅니다ㅜㅜㅜㅜ본 내용은 아래 포스팅을 기반으로 하였으므로, (영상 내용도 이와 동일합니다)먼저 참고해주시고ㅜ조만간 복구해놓겠습니다. 감사합니다! 행복한 하루 되세요^^
- 1
- 2
- 66
Q&A
엑셀 그래프와 테이블을 한글 각페이지에 삽입하기
한준님, 안녕하세요?덕분에 유쾌한 금요일을 보냈습니다. 기대하신 것보다 복잡한 코드를 보여드리는 것 같아 우려스런 마음이 있습니다만,막상 아래아한글 파트는 코드 전체에서 열 줄 정도로,엑셀 차트오브젝트나, 특정 범위를 선택하는 코드가 대부분이기는 하네요. 우선 짧은 시연화면을 먼저 보여드립니다.(사진)한/글에서 그림이나 표의 크기를 조절하는 코드를 빼기 위해 용지의 위아래 여백을 15 정도로 줄여두었습니다. 참고하시기 바랍니다. 코드는 크게 두 부분으로 나누었습니다. 하나씩 보여드리면, 1. 차트이미지 삽입하는 코드import xlwings as xw from pyhwpx import Hwp # 한글 인스턴스 생성 hwp = Hwp() # 활성화된 Excel 앱과 워크북 가져오기 excel = xw.apps.active wb = excel.books[0] # 워크시트 내 차트를 순회하며 처리 for ws in wb.sheets: shapes = ws.api.Shapes # 모든 도형 가져오기(단, 모든 도형이 차트라는 가정!!) for i in range(1, shapes.Count + 1): # 모든 도형을 순회하면서 shape = shapes.Item(i) # 도형을 선택하고 if shape.Type == 3: # 3 == 선택한 도형이 차트(ChartObject)이면 shape.CopyPicture() # 그림으로 복사하기 실행 후에 hwp.goto_page(i) # 한/글 문서의 i페이지 시작점으로 이동해서 hwp.MovePageEnd() # 페이지 끝으로 커서를 옮기고 hwp.BreakPara() # 엔터 한 번 친 후에 hwp.Paste() # 차트 이미지 붙여넣기 hwp.BreakPara() # 엔터주석을 읽어보시면 어느 정도 이해가 되실 거라고 생각합니다^^;코드를 따라 치지 마시고, 한 줄, 혹은 두 줄씩 기억해서 직접 작성해보시면더 빠르게 익숙해지실 겁니다. 그리고 아래는 표를 붙여넣는 코드입니다. 2. 엑셀 범위를 한/글 표로 붙여넣는 코드이 부분이 조금 까다롭게 느껴질 수 있는데, 아래에 부연설명을 붙이겠습니다.# 엑셀 열기 ws = wb.sheets[0] # 첫 번째 시트 선택 # A열에서 값이 "구 분"인 셀의 행번호 수집하기 a_values = ws.range(ws.cells(1,1), ws.cells(len(ws.used_range), 1)).value gubun_rows = [i+1 for i, val in enumerate(a_values) if val == "구 분"] # 엑셀범위 복사 및 한/글에 표로 붙여넣는 코드 for idx, row in enumerate(gubun_rows, start=1): # 수집한 행번호를 순회하면서 init_cell = ws.range(f"A{row}") # "구 분" 셀로 이동해서(표의 좌측상단) end_cell = init_cell.end("right").end("down") # 우측하단 끝 셀주소를 찾고 table_range = ws.range(init_cell, end_cell) # 해당 범위를 table_range.copy() # 복사함 hwp.goto_page(idx) # 한/글 문서의 idx페이지 시작점으로 이동한 후 hwp.MovePageEnd() # 커서를 해당페이지 끝으로 이동 hwp.Paste() # 표 붙여넣기 # 표 너비를 본문에 맞춤 i = 0 while hwp.get_into_nth_table(i): # 문서의 i번째 표로 진입한 후 hwp.set_table_width() # 표 너비를 본문 너비에 맞춤 i += 1 # 다음 표로 이동간결하게나마 라인별로 주석을 달아보았는데,제 생각에 가장 어렵게 느껴질 부분은 역시 a_values와 gubun_rows를 구하는 부분이 아닌가 싶습니다.이 문법들은 어떤 깊은 원리가 있다기보다, "우리, 이런 동작은 이런 코드로 약속하자" 식의 문법이라서익숙해지는 것 말고는 왕도가 없는 듯 합니다. ws.range(ws.cells(1,1), ws.cells(len(ws.used_range), 1)).value①우선 ws.range 객체는 워크시트의 셀 범위를 자유롭게 선택할 수 있는데, 사용법이 아래 두 가지입니다.하나는 ws.range("A1:B5").values 이런 식으로 엑셀의 셀 범위 문법을 문자열로 그대로 쓰는 방법과,다른 하나는 ws.range(ws.cells(1,1), ws.cells(2,5))식으로 cells객체를 두 개 넣는 방법입니다.항상 고정된 범위를 선택해야 하는 경우라면 첫번째 방법인 문자열 방식이 훨씬 직관적이지만,지금 우리 경우처럼 특정 셀을 찾아야 하거나, 순회하는 경우에는 두 번째 방법이 코딩하기 쉽습니다. ②그리고 len(ws.used_range) 코드가 들어가 있는 이유는,A열 전체에서 "구 분"이라는 데이터를 찾으려는 목적인데 ws.Range("A:A") 라고 지정해버리면 셀이 100만개나 선택이 되어버리기 때문에 다소 느립니다.그래서 "사용한 범위"의 행 갯수만 세서 A1:A100 정도 내에서만 탐색을 하기 위해"워크시트 사용범위의 행 길이"인 len(ws.used_range)를 탐색범위로 지정한 것입니다. [i+1 for i, val in enumerate(a_values) if val == "구 분"]①enumerate가 조금 생소하실 수 있겠습니다.enumerate는 리스트나 문자열 등 순회 가능한 객체를 for문에 넣었을 때,해당 인덱스의 아이템만 꺼내는 게 아니라, 아이템의 인덱스번호를 같이 리턴해줍니다.아래는 enumerate의 예시입니다.>>> a = ["A", "B", "C"] >>> for i in a: >>> print(i) ... A B C >>> for idx, val in enumerate(a): >>> print(idx, val) ... 0 A 1 B 2 Cfor문 안에서 enumerate 함수는 정말 많이 사용됩니다. 익혀 두시면 큰 도움이 될 것입니다.그러면, A열의 값들이 들어 있는 a_values 리스트 안에서값이 "구 분"인 주소의 행번호(인덱스)만 따로 추출하려면아래와 같이 for문을 작성하면 됩니다.gubun_list = [] for i, val in enumerate(a_values): # if val == "구 분": gubun_list.append(i + 1) # 파이썬인덱스는 0부터, 엑셀행은 1부터 시작하니까 +1 위처럼 네 줄로 짤 수도 있고요.파이썬의 "리스트 컴프리헨션"이라는 문법 덕분에위 네 줄을 간결하게 한 줄로 짤 수 있습니다."리스트컴프리헨션"은 "리스트 안에 for문을 포함(comprehension)하는 문법입니다.타 프로그래밍언어 유저들이 파이썬에서 가장 부러워하는 간결한 문법 세 가지로문자열 인덱싱, f-스트링 및 리스트&딕셔너리 컴프리헨션을 꼽는다고 합니다.그래서 최종 코드에는 아래처럼 리스트컴프리헨션을 써서 한 줄로 적었습니다.gubun_list = [i + 1 for i, val in enumerate(a_list) if val == "구 분"] 혹시 잘 이해가 안 되시거나 어렵게 느껴지는 부분이 있다면추가로 질문 남겨주세요.전적으로 제 설명력 부족 탓입니다ㅜ 마치며엑셀 관련 코드를 짤 때는, 셀이나 범위, 현재 선택위치 등을 생각하면서제법 까다롭게 시행착오를 거쳐야 하는 경우가 많지만,대부분 매크로 녹화를 통해 큰 틀의 코드가 잡힙니다.그리고 VBA와 파이썬 코드는 비슷한 부분이 있어서녹화한 엑셀매크로를 그대로 조금만 수정하면 잘 돌아가는 파이썬 코드를 금방 얻을 수 있습니다.아래아한글도 비슷합니다. 대부분은 스크립트매크로 녹화를 통해특정 수작업이나 프로세스에 대응되는 액션을 찾아내고,그 외에 매크로 녹화가 안 되는 액션이나, 필드, 이미지 삽입 같은 특수한 메서드는 API문서에서 검색하는 방식으로코드를 완성합니다.요즘은 한글개발자포럼이라고,한컴 개발자 분들이 직접 답변을 달아주는 고마운 사이트가 하나 생겼습니다.https://forum.developer.hancom.com/ 감사하게도 보통 하루 안에 상세한 답변을 달아주시고,열정적인 커뮤니티 분들이 더 빠르게 답변을 달아주시기도 해서저도 종종 방문합니다. 답변이 도움이 되었길 바랍니다.그리고 분명히 충분한 답변이 아니라는 것도 짐작이 갑니다.추가로 질문 남겨주세요ㅎ 즐거운 주말 보내세요~^^
- 1
- 2
- 133
Q&A
api 버그를 활용한 서체 일괄체크에서 글자색 모두 바꾸기가 안되서 문의드립니다
재영님 안녕하세요?한글2024에서는 버그픽스가 되었나봅니다.대신 아래 코드를 참고해주시기 바랍니다.""" `hwp.set_pos(lst, para, pos)`는 (hwp.SetPos와 달리) 이동에 실패시 False를 리턴합니다. 그래서 아래처럼 while문 조건으로 사용 가능합니다. """ from pyhwpx import Hwp hwp = Hwp() lst = 0 # 본문에서부터 while hwp.set_pos(lst,0,0): # 모든 영역을 다니면서 hwp.SelectAll() # 전체선택 hwp.set_font(TextColor="Black") # 글자색 검정 lst += 1 # 다음 영역으로시연화면은 아래와 같습니다.(사진)도움이 되었길 바랍니다.강의 본문도 수정해 두도록 하겠습니다. 감사합니다.행복한 하루 되세요^^
- 1
- 2
- 58
Q&A
한/글 API 가이드 링크
아이고, 수정해 두겠습니다.수정된 링크는 아래와 같습니다.https://developer.hancom.com/hwpautomation행복한 하루 되시기 바랍니다^^
- 1
- 2
- 89
Q&A
누름틀의 메모를 조회하는 방법이 궁금합니다.
민수님 안녕하세요?직접적인 메서드는 없지만, xml 파싱하듯 필드 정보를 가져올 수 있습니다.예를 들어 아래는[ {"name": 필드1이름, "direction": 필드1안내문, "memo": 필드1메모}, {"name": 필드2이름, "direction": 필드2안내문, "memo": 필드2메모}, ..., ]방식으로 리턴하는 코드입니다.중간에 문자열 가공이 귀찮아서 정규식을 써버렸는데,더 깔끔한 방법으로 바꾸면 좋을 것 같습니다...ㅠ import xml.etree.ElementTree as ET import re from pyhwpx import Hwp hwp = Hwp() txt = hwp.GetTextFile("HWPML2X") root = ET.fromstring(txt) results = [] for field in root.findall(".//FIELDBEGIN"): name_value = field.attrib.get("Name") command = re.split(r"(Clickhere:set:\d+:Direction:wstring:\d+:)|( HelpState:wstring:\d+:)", field.attrib.get("Command")[:-2]) results.append({"name": name_value, "direction": command[3], "memo": command[-1]})(사진) 코드 쓰기 귀찮으실까봐..pyhwpx 최신버전(0.41.8)에 hwp.get_field_info()를 추가해 두었습니다.혹시 다른 방식으로 작동하길 원하시면 댓글로 제안해주시기 바랍니다. 행복한 하루 되세요^^
- 1
- 1
- 69
Q&A
독립형 프로그램으로 추출 후 오류 발생
ssaycao님 안녕하세요?보안모듈(FilePathCheckerModule.dll) 관련 오류로 보입니다ㅜ(얼마 전에 이와 관련한 업데이트를 한 번 하기는 했는데, 완전히 해결되지 않은 듯 합니다.) 우선 pyhwpx 모듈을 업데이트해주시고, 프로그램을 배포하실 때, 두 가지만 테스트 부탁드립니다. (아마 둘 중 하나로는 해결될것입니다.)① 컴파일하실 때, FilePathCheckerModule.dll 파일을 작업폴더에 넣은 상태에서--add-binary="FilePathCheckerModule.dll:."옵션을 하나 더 추가하여 컴파일해보시겠어요? ② 만약 위의 방법으로도 해결되지 않는다면ㅜFilePathCheckerModule.dll 파일을 exe파일과 같은 폴더에 두고 실행해보시면 해결될 듯 합니다. 가급적 pyhwpx 최신 업데이트는 조심스럽게...현재 버전이 몇인지 기억해 두셨다가, 기존 코드에 오류가 발생하면 롤백을 해주셔야 할 수도 있습니다...ㅜ (죄송한 말씀이지만, 한/글이 버전업되면서 메서드 일부에서 오류들이 생기는 듯 합니다ㅜ)대신 제게 증상과 작성하셨던 코드를 알려주시면 조치방법을 빠르게 알려드리겠습니다.위의 두 가지 방법 중 하나로 공유해보시고,여전히 위 오류가 발생하면(안 생기기를 간절히 빕니다...) 댓글이나 메일로 알려주시기 바랍니다. 죄송한 마음이 큽니다.부디 잘 해결되길 행복한 하루 되세요!!!
- 1
- 2
- 78