한글 문서 저장시 이벤트 넣기

현재 파이썬으로 한글 오토메이션 개발을 진행하고 있습니다.

파일 저장시 이벤트를 넣어(예를 들어 DB에 값 저장하고, 폴더경로 자동으로 지정) 등 하고 싶은데 한글에서 이벤트는 불가능하고 소스상에서만 이벤트가 가능한걸까요

이 범주에서는 한글 오토메이션에 대한 다른 사용자의 기술 지원을 제공받을 수 있습니다.

  1. 한글 오토메이션의 API 사용/연동은 개발 가이드를 참조하세요.
  2. 일반 문의는 한글과컴퓨터 웹사이트의 고객 지원을 이용하세요.
  3. 개인정보가 포함되지 않도록 유의하세요. 게시글 또는 댓글에 개인정보가 포함된 내용이 있을 경우 게시물이 숨김처리 될 수 있습니다.
2개의 좋아요

예를들어
현재 문서를 여는거까지는 오토메이션으로 여는데 이후 저장을 누르면 DB에 데이터를 INSERT도 하고 지정경로에 자동으로 저장되게 하고 싶습니다.

2개의 좋아요

안녕하세요 ~ 한글에서도 이벤트는 발생하고 있긴 합니다.
아래와 같은 이벤트를 지원합니다, 하지만 스크립트 형식의 언어에서는 지원하지 않습니다.

아래는 이벤트 핸들러 만드는 관련 글 올려드립니다.

감사합니다~!

2개의 좋아요

한/글에서는 저장을 눌렀을 때 발생하는 이벤트로 아래 두 가지를 제공하고 있습니다.

  1. OnDocumentBeforeSave : 저장 직전에 실행
  2. OnDocumentAfterSave : 저장 직후에 실행

파이썬 기준으로는,

def OnDocumentBeforeSave(self, newVal):
    print("OnDocumentBeforeSave", newVal)  # newVal은 문서(XHwpDocument) 번호
    # DB에 데이터 삽입하는 코드
        
def OnDocumentAfterSave(self, newVal):
    print("OnDocumentAfterSave", newVal)
    # 특정 경로에 다른이름으로 저장하는 코드

식으로 작성하실 수 있겠습니다.
이벤트를 처리하는 아주 간단한 코드를 예시로 보여드리면,

"""
아래아한글 이벤트핸들러 예제

Quit(리턴 없음) : 한/글을 종료할 때 발생
CreateXHwpWindow(리턴 없음) : 한/글에서 새 문서 창을 열었을 때 발생
CloseXHwpWindow(리턴 없음) : 한/글에서 문서 창을 닫았을 때 발생
NewDocument(long) : 새 문서를 생성할 경우 발생(Document ID를 반환)
DocumentBeforeClose(long) : 문서를 닫기 직전에 발생(Document ID를 반환)
DocumentBeforeOpen(long) : 문서를 열기 직전에 발생(Document ID를 반환)
DocumentAfterOpen(long) : 문서를 열고 난 후에 발생(Document ID를 반환)
DocumentBeforeSave(long) : 문서를 저장하기 직전에 발생(Document ID를 반환)
DocumentAfterSave(long) : 문서를 저장한 후에 발생(Document ID를 반환)
"""
import win32com.client as win32
import pythoncom


# 이벤트핸들러 작성
class HwpEvents:  # 클래스명은 자유롭게~
    def OnQuit(self):  # 메서드명은 제공이벤트와 일치해야 함!
        print("OnQuit")
        
    def OnCreateXHwpWindow(self):
        print("OnCreateXHwpWindow")
        
    def OnCloseXHwpWindow(self):
        print("OnCloseXHwpWindow")
        
    def OnNewDocument(self, newVal):
        print("OnNewDocument", newVal)
        
    def OnDocumentBeforeClose(self, newVal):
        print("OnDocumentBeforeClose", newVal)
        
    def OnDocumentBeforeOpen(self, newVal):
        print("OnDocumentBeforeOpen", newVal)
        
    def OnDocumentAfterOpen(self, newVal):
        print("OnDocumentAfterOpen", newVal)
        
    def OnDocumentBeforeSave(self, newVal):
        print("OnDocumentBeforeSave", newVal)
        msgbox = hwp.XHwpMessageBox
        msgbox.string = "확인을 누르면 저장을 완료합니다."
        msgbox.DoModal()
        
    def OnDocumentAfterSave(self, newVal):
        print("OnDocumentAfterSave", newVal)
        msgbox = hwp.XHwpMessageBox
        msgbox.string = "저장이 완료되었습니다. 한/글을 종료합니다."
        msgbox.DoModal()
        hwp.Quit()  # hwp 종료
        
    def OnDocumentAfterClose(self, newVal):
        print("OnDocumentAfterClose", newVal)
        
    def OnDocumentChange(self, newVal):
        print("OnDocumentChange", newVal)
        
    def OnDocumentBeforePrint(self, newVal):
        print("OnDocumentBeforePrint", newVal)
        
    def OnDocumentAfterPrint(self, newVal):
        print("OnDocumentAfterPrint", newVal)
        
    def OnDocumentClickedHyperlink(self, linkType, szAddress, szShowText):
        print("OnDocumentClickedHyperlink", linkType, szAddress, szShowText)
        
    def OnDocumentModifiedHyperlink(self, linkType, szAddress, szShowText):
        print("OnDocumentModifiedHyperlink", linkType, szAddress, szShowText)
        
    def OnBeforeQuit(self, newVal):
        print("OnBeforeQuit", newVal)


# 아래아한글 및 이벤트핸들러 실행
hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")
hwp.XHwpWindows.Item(0).Visible = True
hwp_events = win32.WithEvents(hwp, HwpEvents)

keepOpen = True

while keepOpen:
    pythoncom.PumpWaitingMessages()
    try:
        if hwp.XHwpDocuments.Count != 0:
            keepOpen = True
        else:
            keepOpen = False
            hwp = None
            break  # sys.exit()
    except:
        keepOpen = False
        hwp = None
        break  # sys.exit()

시연화면은 아래와 같습니다.
저장 버튼을 누르는 시점(저장 직전)에 팝업을 띄워주고,
저장이 완료된 직후에 팝업과 함께 한/글을 종료하는 이벤트를 추가하였습니다.

녹화_2023_11_27_22_39_00_566

도움이 되었길 바랍니다.

1개의 좋아요

감사합니다. 늘 개발 포럼 보면서 참고 많이 하고 있습니다. 좋은 하루 되십시오~

2개의 좋아요

감사합니다. 도움 많이 되고 있습니다.

2개의 좋아요


혹시 … 이부분에서 에러로 떨어지지는데 이유를 알 수 있을까요 … OS환경은 Window 7/ 32bit / 한글버전은 2010입니다…

2개의 좋아요

image
에러나는 부분입니다…

2개의 좋아요

안녕하세요.
음 오류 코드를 봤을땐 해당 Event의 클래스 ID가 등록되지 않을것 같아보입니다 .
재설치하거나 한컴 기본 설정을 통해 등록에 대한 초기화가 가능합니다.
한글 2010을 쓰신다고하셨는데 제가 해당 버전은 확인해볼수 없어서 해당 버전이 해당 API를 지원하는지는 확인이 불가능하네요 ㅠ
감사합니다.

2개의 좋아요

버전에 따라 지원되는 API가 다를수도 있을까요 …?

2개의 좋아요

API 지원목록이 경미하게 다를 수는 있지만,
한/글 2010은 (최소) 아래 이벤트는 지원하고 있습니다.

  • Quit
  • CreateXHwpWindow
  • CloseXHwpWindow
  • NewDocument
  • DocumentBeforeClose
  • DocumentBeforeOpen
  • DocumentAfterOpen
  • DocumentBeforeSave
  • DocumentAfterSave
  • DocumentAfterClose
  • DocumentChange

HwpEvents 클래스 내부에 문제가 있을 것도 같은데,
보여주신 코드만으로는 확인이 어렵습니다ㅜ

1개의 좋아요

class HwpEvents:
def OnQuit(self): # 메서드 이름은 제공하는 이벤트명과 정확히 일치해야 함!
print(“OnQuit”)

def OnCreateXHwpWindow(self):
    print("OnCreateXHwpWindow")
    
def OnCloseXHwpWindow(self):
    print("OnCloseXHwpWindow")
    
def OnNewDocument(self, newVal):
    print("OnNewDocument", newVal)
    
def OnDocumentBeforeClose(self, newVal):
    print("OnDocumentBeforeClose", newVal)
    
def OnDocumentBeforeOpen(self, newVal):
    print("OnDocumentBeforeOpen", newVal)
    
def OnDocumentAfterOpen(self, newVal):
    print("OnDocumentAfterOpen", newVal)
    
def OnDocumentBeforeSave(self, newVal):
    print("OnDocumentBeforeSave", newVal)
    msgbox = hwp.XHwpMessageBox
    msgbox.string = "확인을 누르면 저장을 완료합니다."
    msgbox.DoModal()
    
def OnDocumentAfterSave(self, newVal):
    print("OnDocumentAfterSave", newVal)
    msgbox = hwp.XHwpMessageBox
    msgbox.string = "저장이 완료되었습니다. 한/글을 종료합니다."
    msgbox.DoModal()
    hwp.Quit()  # hwp 종료

hwp = win32.gencache.EnsureDispatch(“hwpframe.hwpobject”)
hwp.RegisterModule(“FilePathCheckDLL”, “FilePathCheckerModule”)
hwp.XHwpWindows.Item(0).Visible = True
hwp_events = win32.WithEvents(hwp, HwpEvents)

keepOpen = True

while keepOpen:
pythoncom.PumpWaitingMessages()
try:
if hwp.XHwpDocuments.Count != 0:
keepOpen = True
else:
keepOpen = False
hwp = None
break # sys.exit()
except:
keepOpen = False
hwp = None
break # sys.exit()

소스는 기존 소스 그대로 사용했습니다…

hwp_events = win32.WithEvents(hwp, HwpEvents) 이부분에서 에러가 떨어지는데


에러 부분을 더 확인해보면 DIHwpObjectEvents쪽에서 에러로 떨어집니다… 번거롭게 죄송합니다…

2개의 좋아요

OnDocumentBeforeSave와 OnDocumentAfterSave 말고 나머지는 지워보세요ㅜ

1개의 좋아요

안녕하십니까… 처음에는 API방식의 차이가 있을수 있다 싶어 필요한 기능만 넣고 했음에도 디버깅 오류가 발생합니다… 단순히 저 첨부해주신 코드만 가지고 디버깅 했을때는 한글 파일까지는 열리고 그 이후 win32.WithEvents부분에서 에러로 떨어집니다… 염치불구하고 혹시 저 코드만 가지고 컴파일 해보면 되는걸까요 아니면 다른 세팅이 필요한걸까요…

2개의 좋아요

bhjung님 말씀대로, 해당 Event의 클래스ID가 등록되지 않았을 수도 있겠습니다.
한/글을 재설치하시거나, 한컴 기본 설정을 통해 등록 초기화를 하셔야 할 것 같습니다.

혹은, 파이썬이나 가상환경 폴더 내의
설치폴더/Lib/site-packages/pythonwin/start_pythonwin.pyw 파일을 실행하셔서
Tools - COM Makepy utility 를 선택하시고,
HwpObject 1.0 Type Library (1.0)이 보이는지 확인하시고,
있으면 선택 후 OK를 눌러주세요.
(타입 라이브러리가 보이지 않으면, 한/글을 재등록 또는 재설치하셔야 할 것 같습니다.)

그 다음 파이참이나 IDE를 재시작하시고 다시 코드를 실행해보세요.

녹화_2023_12_01_19_52_59_653

1개의 좋아요

한글 새로지우고, 라이브러리 pythonwin으로 다시 등록도 해보고 제공 API만 정의해도 똑같은 부분에서 오류가 납니다… 영상까지 올려주셨는데 답변 감사합니다 ㅠㅠ

2개의 좋아요

2014에서 동일한 에러가 발생하고
2020에서는 정상적으로 이벤트가 발생하네요.

2개의 좋아요

2020 상위버전부터 지원하는거 같습니다. 2010/2014/2018 했을때도 안됩니다. 저도 공식적인 답변은 받지 못했습니다.

2개의 좋아요