본문 바로가기
아래아한글 자동화/python+hwp 중급

[QnA] (2/5) 표 생성하고, 수정하기

by 일코 2022. 9. 19.
안녕하세요.
한글 자동화 프로그램을 공부하고 있는데 궁금한 사항이 있어 질문합니다.

<질문>

특정 글자가 들어가 있는 문단을 찾아서 그 곳에 글뒤로 속성으로 표를 삽입하고 싶습니다.
1. 자동으로 표 생성시 속성을 "본문과의배치"에서 "글뒤로" 선택하여 생성할 수 있나요?
이 속성없이 생성시 문단에 삽입되면서 글자가 밀려나는 현상이 발생합니다.

2. 찾은 문단의 위치값을 HWPUNIT 값으로 알 수 있나요?
표 생성시 위치값은 HWPUNIT으로 지정해야 하는데 현재 찾은 위치의 속성은 줄,칸으로 알려주네요.
이상입니다.

이전 포스팅(인트로)에서는

특정 단락 위치에 백그라운드로 표를 삽입하는 방법을 구상해보았고,

그 이유와 대략적으로 구현해야 하는 함수 다섯 개를 짚어보았습니다.

2022.09.19 - [업무자동화/파이썬-아래아한글 자동화 응용] - [QnA] (1/5) 특정단어 포함 문단 뒤에 표 깔기-인트로

 

[QnA] (1/5) 특정단어 포함 문단 뒤에 표 깔기-인트로

안녕하세요. 한글 자동화 프로그램을 공부하고 있는데 궁금한 사항이 있어 질문합니다. <질문> 특정 글자가 들어가 있는 문단을 찾아서 그 곳에 글뒤로 속성으로 표를 삽입하고 싶습니다. 1. 자

martinii.fun

 

 

첫 번째 질문은 "표를 글 뒤로 보낼 수 있나?" 하는 내용이니까

여기부터 차근차근 설명을 풀어가겠습니다.

 

한/글에서 표를 생성하는 코드는 사실 단순하지 않습니다.

특히 특정 사이즈의 표를 만들기 위해서는 아래와 같이 코드가 다소 복잡하고 길어지게 됩니다.

"""
5행5열, 셀마다 사이즈를 지정해서 표를 생성하는 코드
"""

hwp.HAction.GetDefault("TableCreate", hwp.HParameterSet.HTableCreation.HSet)
hwp.HParameterSet.HTableCreation.Rows = 5
hwp.HParameterSet.HTableCreation.Cols = 5
hwp.HParameterSet.HTableCreation.WidthType = 2
hwp.HParameterSet.HTableCreation.HeightType = 1
hwp.HParameterSet.HTableCreation.WidthValue = hwp.MiliToHwpUnit(148.0)
hwp.HParameterSet.HTableCreation.HeightValue = hwp.MiliToHwpUnit(150)
hwp.HParameterSet.HTableCreation.CreateItemArray("ColWidth", 5)
hwp.HParameterSet.HTableCreation.ColWidth.SetItem(0, hwp.MiliToHwpUnit(16.0))
hwp.HParameterSet.HTableCreation.ColWidth.SetItem(1, hwp.MiliToHwpUnit(36.0))
hwp.HParameterSet.HTableCreation.ColWidth.SetItem(2, hwp.MiliToHwpUnit(46.0))
hwp.HParameterSet.HTableCreation.ColWidth.SetItem(3, hwp.MiliToHwpUnit(16.0))
hwp.HParameterSet.HTableCreation.ColWidth.SetItem(4, hwp.MiliToHwpUnit(16.0))
hwp.HParameterSet.HTableCreation.CreateItemArray("RowHeight", 5)
hwp.HParameterSet.HTableCreation.RowHeight.SetItem(0, hwp.MiliToHwpUnit(40.0))
hwp.HParameterSet.HTableCreation.RowHeight.SetItem(1, hwp.MiliToHwpUnit(20.0))
hwp.HParameterSet.HTableCreation.RowHeight.SetItem(2, hwp.MiliToHwpUnit(50.0))
hwp.HParameterSet.HTableCreation.RowHeight.SetItem(3, hwp.MiliToHwpUnit(20.0))
hwp.HParameterSet.HTableCreation.RowHeight.SetItem(4, hwp.MiliToHwpUnit(20.0))
hwp.HParameterSet.HTableCreation.TableProperties.TreatAsChar = 1  # 글자처럼 취급
hwp.HParameterSet.HTableCreation.TableProperties.Width = hwp.MiliToHwpUnit(148)
hwp.HAction.Execute("TableCreate", hwp.HParameterSet.HTableCreation.HSet)

(굳이 자세한 설명을 덧붙이자면)

아래 두 번째 줄 148mm는 A4용지 여백 210mm에서 60mm(좌우 각 30mm)를 뺀 150mm에다가,
표 바깥여백 각 1mm를 뺀 148mm입니다. (~.TableProperties.Width = 41954)

각 열의 너비는 5열 표 생성시 평균 26mm가 되어야 하는데
이는 셀마다 안쪽여백 좌우 각각 1.8mm를 뺀 값으로,
148 - (1.8 x 10 =) 18mm = 130mm
그래서 셀 너비의 총 합은 130이 되어야 합니다. (16+36+46+16+16=130)

표를 생성하는 시점에는 표 안팎의 여백을 없애거나 수정할 수 없으므로
이는 고정된 값으로 간주해야 합니다.

또한 한/글에서 사용하는 길이단위는 HWPUNIT(HU)으로,
1포인트는 100HU이고, 1인치는 7200HU, 1mm는 283.465 HU입니다.
머리가 아파오기 시작하네요.

위 코드를 실행하면 아래처럼 표가 생성됩니다.

다행히 우리는 1행1열의 단순한 표를 생성할 것이기 때문에 함수의 길이가 대폭 줄어들기는 합니다.

 

그리고 표를 글 뒤로 보내기라든지, 표의 바깥여백을 0으로 만드는 등의 수정은

표를 생성하는 시점에 설정할 수 없고, 표를 생성한 이후에 표를 선택한 후 설정해야 합니다.

 

[여기서 잠깐] 표의 바깥여백을 0으로 만들어야 하는 이유?

바깥여백을 없애는 이유는 아래와 같은 차이가 생기기 때문인데요.

바깥여백 있는 경우
바깥여백 없는 경우

다소 미묘하지만 아래 예시처럼, 표의 바깥여백을 0으로 해줘야 글자가 표 밖으로 튀어나오지 않네요.

 

다시 본론으로 돌아와서

우리의 목적은

①표 생성 후 ②표를 글자 뒤로 보내고, ③표의 바깥여백을 0으로 바꾸는 코드를 작성하는 것입니다.

이렇게 표를 생성한 후
표를 백그라운드로 보내서, 글자와 표가 겹치게 하려고 합니다.

매크로 녹화 기능을 이용해서 해당 스크립트를 추출해보면 아래와 같습니다.

표를 글자 뒤(백그라운드)로 보내는 함수 - 한/글 스크립트매크로

function OnScriptMacro_script5()
{
	FindCtrl();
	HAction.GetDefault("CellBorderFill", HParameterSet.HCellBorderFill.HSet);
	with (HParameterSet.HCellBorderFill)
	{
		HSet.SetItem("ApplyTo", 1);
	}
	HAction.Execute("CellBorderFill", HParameterSet.HCellBorderFill.HSet);
	HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet);
	with (HParameterSet.HShapeObject)
	{
		TextWrap = TextWrapType("BehindText");
		HSet.SetItem("ShapeType", 6);
	}
	HAction.Execute("TablePropertyDialog", HParameterSet.HShapeObject.HSet);
}

불필요한 부분을 지우고, 파이썬 문법으로 고쳐보면

 

hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
hwp.HParameterSet.HShapeObject.TextWrap = hwp.TextWrapType("BehindText")
hwp.HParameterSet.HShapeObject.HSet.SetItem("ShapeType", 6)
hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)

위 코드를 파이썬으로 실행해보면?

원하는 대로 잘 작동합니다.

필수 파라미터가 빠져서인지 com_error가 발생하는데,
동작은 잘 되므로 오류는 무시하겠습니다. (try문 안에 넣어서 예외처리할 예정)

이번엔 표 바깥여백을 바꾸는 매크로를 녹화해보겠습니다.

스크립트매크로 녹화로 이 과정의 코드만 따옵니다.

표 바깥여백을 모두 0으로 만드는 코드-한/글 스크립트매크로

function OnScriptMacro_script6()
{
	FindCtrl();
	HAction.GetDefault("CellBorderFill", HParameterSet.HCellBorderFill.HSet);
	with (HParameterSet.HCellBorderFill)
	{
		HSet.SetItem("ApplyTo", 1);
	}
	HAction.Execute("CellBorderFill", HParameterSet.HCellBorderFill.HSet);
	HAction.GetDefault("TablePropertyDialog", HParameterSet.HShapeObject.HSet);
	with (HParameterSet.HShapeObject)
	{
		OutsideMarginBottom = MiliToHwpUnit(0.0);
		OutsideMarginTop = MiliToHwpUnit(0.0);
		OutsideMarginRight = MiliToHwpUnit(0.0);
		OutsideMarginLeft = MiliToHwpUnit(0.0);
		HSet.SetItem("ShapeType", 6);
	}
	HAction.Execute("TablePropertyDialog", HParameterSet.HShapeObject.HSet);
}

불필요한 내용을 지우고 파이썬 문법으로 고치면?

hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
hwp.HParameterSet.HShapeObject.OutsideMarginBottom = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HShapeObject.OutsideMarginTop = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HShapeObject.OutsideMarginRight = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HShapeObject.OutsideMarginLeft = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HShapeObject.HSet.SetItem("ShapeType", 6)
hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)

이 코드를 실행해보면?

(미묘하지만... 자세히 보면) 바깥여백이 없어집니다.

아래는 최종코드입니다.

참고로, 아래에 "줄바꿈_지우기"라는 함수가 추가되어 있는데, 간단히 설명드리면
표 삽입시 불필요하게 생성되는 줄바꿈 두 개를 삭제하고,
표 컨트롤과 실제 표 위치의 y오프셋을 0으로 고쳐서 표를 해당문단의 좌측상단에 바짝 붙이는 동작을 합니다.
(이 함수에서도 이유를 알 수 없는 com_error가 발생해서 try-except로 예외처리를 해버렸습니다.)
import pywintypes


def 표_생성(width, height):
    hwp.HAction.GetDefault("TableCreate", hwp.HParameterSet.HTableCreation.HSet)
    hwp.HParameterSet.HTableCreation.Rows = 1
    hwp.HParameterSet.HTableCreation.Cols = 1
    hwp.HParameterSet.HTableCreation.WidthType = 2
    hwp.HParameterSet.HTableCreation.HeightType = 1
    hwp.HParameterSet.HTableCreation.WidthValue = hwp.MiliToHwpUnit(width)
    hwp.HParameterSet.HTableCreation.HeightValue = hwp.MiliToHwpUnit(height)
    hwp.HParameterSet.HTableCreation.CreateItemArray("ColWidth", 1)
    hwp.HParameterSet.HTableCreation.ColWidth.SetItem(0, hwp.MiliToHwpUnit(width))
    hwp.HParameterSet.HTableCreation.CreateItemArray("RowHeight", 1)
    hwp.HParameterSet.HTableCreation.RowHeight.SetItem(0, hwp.MiliToHwpUnit(height))
    hwp.HParameterSet.HTableCreation.TableProperties.TreatAsChar = 0  # 글자처럼 취급안함
    hwp.HParameterSet.HTableCreation.TableProperties.Width = hwp.MiliToHwpUnit(width)
    hwp.HAction.Execute("TableCreate", hwp.HParameterSet.HTableCreation.HSet)
    try:
        hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
        hwp.HParameterSet.HShapeObject.TextWrap = hwp.TextWrapType("BehindText")
        hwp.HParameterSet.HShapeObject.HSet.SetItem("ShapeType", 6)
        hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
        hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
        hwp.HParameterSet.HShapeObject.OutsideMarginBottom = hwp.MiliToHwpUnit(0.0)
        hwp.HParameterSet.HShapeObject.OutsideMarginTop = hwp.MiliToHwpUnit(0.0)
        hwp.HParameterSet.HShapeObject.OutsideMarginRight = hwp.MiliToHwpUnit(0.0)
        hwp.HParameterSet.HShapeObject.OutsideMarginLeft = hwp.MiliToHwpUnit(0.0)
        hwp.HParameterSet.HShapeObject.HSet.SetItem("ShapeType", 6)
        hwp.HParameterSet.HShapeObject.VertOffset = hwp.MiliToHwpUnit(0.0);
        hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
    except pywintypes.com_error as e:
        print(e)


def 줄바꿈_지우기():
    hwp.HAction.Run("CloseEx")
    hwp.HAction.Run("DeleteBack")
    hwp.HAction.Run("Delete")
    hwp.FindCtrl()
    try:
        hwp.HAction.GetDefault("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
        hwp.HParameterSet.HShapeObject.VertOffset = hwp.MiliToHwpUnit(0.0)
        hwp.HAction.Execute("TablePropertyDialog", hwp.HParameterSet.HShapeObject.HSet)
    except pywintypes.com_error as e:
        print(e)


표_생성(width=148, height=50)
줄바꿈_지우기()

이 코드를 실행해보면

멋지게 실행되네요.

예외 발생시 오류를 출력하게 해놓았는데, 그냥 없애도 되겠습니다.

 

그럼 다음 포스팅에서는,

이어지는 포스팅에서는

표_생성 함수에 들어가는 너비 인자는 용지에서, 높이는 문단높이를 통해 구해보는 과정을 진행하겠습니다.

2022.09.19 - [업무자동화/파이썬-아래아한글 자동화 응용] - [QnA] (3/5) 문단의 높이(HwpUnit) 구하기

 

[QnA] (3/?) 문단의 높이(HwpUnit) 구하기

안녕하세요. 한글 자동화 프로그램을 공부하고 있는데 궁금한 사항이 있어 질문합니다. <질문> 특정 글자가 들어가 있는 문단을 찾아서 그 곳에 글뒤로 속성으로 표를 삽입하고 싶습니다. 1. 자

martinii.fun

 

댓글