교무업무자동화

[구글폼 자동화] 학년초 학생 기초생활 조사2 #필드이름

dinggle 2024. 1. 30. 00:44

 

 

[구글폼 자동화] 학년초 학생 기초상담카드 #한글양식

[구글폼 자동화] 학년초 학생 기초상담카드 #기획 고3 담임의 학년초 업무, 학생 기초 상담자료 생성 자동화 < 목차 > 1. [기획의도] 학년 초 고3 담임교사의 주요 업무 2. 학생 기초상담카드 자동화

dingglego.tistory.com

 

한글 자동화의 시작, 필드이름 생성하기

< 목차 >
1. 필드 이름이란?
2. 필드 이름 생성을 위한 사전 작업
3. 필드 이름을 자동 생성 파이썬 코드

 

필드 이름이란?

한글 문서로 만들어진 양식에 원하는 데이터를 입력하기 위해서는 두 가지가 필요하다. 

 

입력할 데이터, 입력할 데이터의 위치 정보

 

데이터시트나 데이터베이스의 형태로 가공하여 입력할 데이터를 한글파일 양식에 입력하기 위해서는 데이터를 입력할 위치 정보가 필요하다.

 

바로 이 위치정보 값에 해당하는 것이 필드이름 이다. 

 

필드 이름은 두 가지 형태로 존재하는데 누름틀과 표의 형태이다. 

한글에서 제공하는 HWPCtrl API 문서를 참조하면 모든 필드를 컨트롤 할 수도 있고, 누름틀 필드, 표의 셀 필드를 각각 구분해서 컨트롤하는 것도 가능하다. 

 

필드를 통해 위치정보를 확인만 하면 파이썬을 통해 내가 원하는 곳에 원하는 정보를 넣는 것은 매우 단순한 작업이 된다. 그렇기 때문에 양식을 생성할 때 가능하면 누름틀이나 표의 형태를 통해 필드를 생성하는 작업이 선행되어야 한다. 

 

 

 

필드 이름 생성을 위한 사전 작업

한글에서 필드 이름을 활용하는 방식은 두 가지가 존재한다. 

 

필드이름{{n}}

 

동일한 필드 이름을 가진 값 들 중에 n번째에 해당하는 값을 지정할 수 있다. 

예를 들어 "제목{{1}}\x2본문\x2이름{{0}}" 과 같이 지정하면 ‘제목’이라는 이름의 필드 중 두 번째, ‘본문’이라는 이름망의 필드 중 첫 번째, ‘이름’이라는 이름의 필드 중 첫 번째를 각각 지정한다. 

 

이와 같은 방식은 동일한 표가 반복되거나, 또는 메일머지와 같이 동일한 패턴이 반복될 경우 활용할 수 있다. 하지만 이 경우 문서의 처음부터 n번째 해당하는 값을 찾아서 값을 입력해야 하기 때문에 문서의 크기가 크고 필드가 많을 경우 시간이 조금 소요될 수 있다. 

 

고유한 필드이름

 

내가 선호하는 방식은 모든 필드를 고유한 값으로 이름을 부여하는 것이다. 필드가 모두 개별적이고, 다양한 형태의 양식이 존재한다면 이 방식이 훨씬 사용하기가 편하다. 개별적인 값들을 찾아 업데이트 할 수도 있고, 전체 값을 업데이트 하는 것도 특정한 규칙을 파악할 필요 없이 전체 필드 리스트를 출력하여 데이터와 매칭만 하면 되기 때문에 초보자가 컨트롤하기에는 더 쉬운 방식이다. 

 

하지만 위의 두 가지 방식 모두 사전에 모든 필드에 이름을 부여하는 과정이 필요하다. 표의 크기가 크고 입력할 셀이 많다면 필드 이름을 부여하는 것조차 단순 작업으로 많은 시간이 소요되기 때문에 이 과정도 파이썬으로 처리하는 것이 정신 건강에 이롭다. 

 

 

 

필드 이름 자동생성

 

아래 코드는 한글 파일을 열기 위해 win32com.client를 사용하여 한글 프로그램에 연결하고, 선택된 파일을 'new_'로 시작하는 새로운 파일로 복사한 뒤 해당 파일을 연다. 

 

문서의 처음으로 이동하고,  표(테이블)을 탐색하면서 셀을 찾아서 필드를 생성한다.

 

각 셀의 위치 정보와 table_i를 활용하여 필드명을 설정하고, 오른쪽으로 이동하면서 계속해서 필드를 생성한다.

 

아래 그림에서 첫 번째 표는 table_i가 1이고, 건강 상태 특이사항 입력 셀은 B7이기 때문에 1_B7과 같이 필드 이름이 부여된다. 

 

 

예외처리 작업이 부족하지만 양식에서 표를 찾아 필드이름을 부여하하는데 효과적인 방식이다. 

 

 

 

import win32com.client as win32
import os
import tkinter as tk
from tkinter import filedialog
import shutil


# 파일 대화 상자를 표시하여 원본 hwp 파일을 선택
root = tk.Tk()
root.withdraw()  # tkinter 창을 숨김
path = filedialog.askopenfilename(title="작업할 한글파일을 선택하세요", filetypes=[("hwp files", "*.hwp")])

#파일경로에서 파일명으로 추출
file_name = os.path.basename(path)  #파일이름 추출
dir_path = os.path.dirname(path) #파일경로 추출
new_filename = os.path.join(dir_path, 'new_' + file_name) #새파일 이름 지정
root.destroy()  # tkinter 창을 닫음

### 한글파일 작업
#한글 실행
hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")

# 수정할 한글파일 복사
shutil.copyfile(path, new_filename)

hwp.Open(new_filename)

#백그라운드 숨김 해제
hwp.XHwpWindows.Item(0).Visible = True  


#문서의 처음으로 이동
hwp.Run("MoveDocBegin")

#테이블 카운팅
table_i = 0

#테이블 탐색 함수
def find_select_table():
    global table_i
        #선택한 개체가 표가 아닐 경우 다음 개체를 탐색
    while True:
            find_table = hwp.KeyIndicator()
            #print(find_table)
            if find_table[-1] != "표":
                    hwp.Run("SelectCtrlFront")

                    next_table = hwp.KeyIndicator()
                    if find_table == next_table:
                            hwp.Run("Cancel")
                            break
                    
            else:
                    #표가 존재한다면 첫번째 셀을 선택
                    hwp.Run("ShapeObjTableSelCell")
                    hwp.Run("Cancel")
                    table_i += 1
                    break

#셀주소 추출 함수
def GetCellAddress():
        return str(table_i) + "_" + hwp.KeyIndicator()[-1][1:].split(")")[0]
    
                
#테이블 필드 생성
while True:
        now_tbl = hwp.KeyIndicator()
        hwp.Run("SelectCtrlFront")
        mov_tbl = hwp.KeyIndicator()
        
        if now_tbl == mov_tbl:
                break
        else:
                find_select_table()
                while True:
                        
                        #셀일 경우 주소줄에서 "문자입력"으로 표시되는 부분을 추출
                        cell_state = hwp.KeyIndicator()[-1].split(':')[-1].strip()
                        
                        if cell_state == "문자 입력":
                                #셀 필드명 입력
                                hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
                                hwp.HParameterSet.HShapeObject.ShapeTableCell.Editable = 1
                                hwp.HParameterSet.HShapeObject.ShapeTableCell.CellCtrlData.name = GetCellAddress()
                                hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
 
                                #현재 셀 위치 정보 확인
                                cell_now = GetCellAddress()
                                # 오른쪽으로 셀 이동
                                hwp.HAction.Run("TableRightCell")
                                #이동한 셀의 위치 정보 확인
                                cell_move = GetCellAddress()
                                #이동 전의 셀과 이동 후의 셀정보가 같다면 
                                if cell_now == cell_move:
                                        hwp.Run("Cancel")
                                        hwp.Run("SelectCtrlFront")

                                        break
                        else:
                                break
                        
#한글 파일 저장
hwp.Save(new_filename)

 

new_학생기초생활조사서.hwp
0.04MB