아래 포스팅에 이어서 오늘은 Autohotkey 로 이베스트증권 xingAPI 를 사용하여 주식 현재가를 가져 오는 방법에 대해서 소개하려 합니다. 아래 포스팅에 이은 소개이므로 해당 내용을 어느 정도 숙지하고 오셔야 이해가 될 것입니다.

http://iamaman.tistory.com/2224

아래 xingAPI 메뉴얼에 나와 있는 바와 같이 로그인이나 계좌 정보와 관련된 내용들은 XASession 을 사용하지만 조회를 하기 위해서는 XAQuery 를 사용해야 합니다. 또한 실시간 정보를 얻기 위해서는 XAReal 을 사용합니다.

http://www.ebestsec.co.kr/apiguide/guide.jsp?cno=100

또한 xingAPI 에는 TR 이라는 개념이 있는데~ xingAPI 를 사용할 때의 입출력 데이터 규격이라고 보시면 될 것 같습니다. TR 에 정의되어 있는 대로 입력을 넣어주면 증권사 서버에서 출력을 받을 수 있다는 것입니다. TR 은 파일로 되어 있는데 xingAPI 를 설치하면 DevCenter 라는 프로그램이 설치 되고 DevCenter 에서 아래와 같이 버튼을 누르면 한번에 다운로드 받을 수 있고 C:\eBEST\xingAPI\Res 폴더에 res 라는 확장자로 설치 됩니다. 각 TR 에 대한 입출력 정보는 DevCenter 에서 확인하실 수 있습니다.

주식 현재가 조회를 하기 위해서는 t1101 또는 t1102 TR 을 사용할 수 있습니다. 본 포스팅에서는 어떤 질문자 분이 계셔서 t1101 TR 을 사용해 보겠습니다. 해당 TR 의 res 파일 위치는 C:\eBEST\xingAPI\Res\t1101.res 이고~ 주식 현재가를 가져오기 위한 Autohotkey 코드는 아래와 같습니다.

아래 코드를 실행하기 전에 당연히 이전 포스팅에서 사용을 했던 로그인은 먼저 해야 되겠죠~

;~ ------------------------ 주식 현재가 가져오기 Start ----------------------------------------

instXAQueryT1102 := ComObjCreate("XA_DataSet.XAQuery")

ComObjConnect(instXAQueryT1102, "query_") ; event binding to query_ReceiveData

login_query := 0

instXAQueryT1102.ResFileName := "C:\\eBEST\\xingAPI\\Res\\t1101.res"

instXAQueryT1102.SetFieldData("t1101InBlock", "shcode", 0, "078020") ; 이베스트 투자 증권 코드

instXAQueryT1102.Request(0)

while login_query = 0 ; hold for ReceiveData event

{

}

name := instXAQueryT1102.GetFieldData("t1101OutBlock", "hname", 0)

price := instXAQueryT1102.GetFieldData("t1101OutBlock", "price", 0)

MsgBox %name% 종목의 현재 가격은 %price% 입니다.

;~ --------------------- 주식 현재가 가져오기 End ----------------------------------------

query_ReceiveData(code, msg)

{

global login_query:= 1

}

위 코드에서 입력으로 준 078020 은 이베스트 투자 증권의 코드 번호입니다. 정상적으로 동작을 하면 아래와 같이 이베스트투자증권의 현재 가격이 9770 원이라고 나오는 것을 확인할 수 있습니다.

위 코드의 동작중 중요한 부분에 대한 설명은 다음과 같습니다.

0. XAQuery 에 대해 ComObjCreate 를 하고 응답 함수를 ComObjConnect() 를 통해 binding 합니다.

1. SetFieldData 를 통해 t1101 TR 에 대한 입력값을 설정하고~

2. 서버에 Request 를 하고

3. whle 문을 통해 서버 응답을 기다립니다.

4. ReceiveData 함수를 통해 응답이 왔음을 확인하면 while 문을 빠져나가게 되고~

5. GetFieldData 를 통해 서버로부터 온 값 중 필요한 부분을 읽습니다.

혹시나 로그인을 안 한 상태로 위코드를 실행하고 안 돌아간다고 댓글 다실 분들을 위해 전체 코드를 첨부합니다. 아래 코드에서 증권사의 아이디,  패스워드,  공인인증서 비번은 본인의 것을 넣어야 된다는 설명은 굳이 안 해도 되겠죠?

위 코드의 동작만 확실히 이해하게 된다면 다른 대부분의 조회 TR도 이해할 수 있을 거라고 생각합니다.

Autohotkey 를 사용하여 이런것도 할 수 있다는 소개를 위해 작성해 봤는데~ 정말 Autohotkey 의 기능은 쓰면 쓸수록 무궁무진한 것 같습니다. 즐거운 Autohotkey 코딩 하시기 바랍니다.



  1. 이베스트 2018.10.09 14:31

    역시 남성 방장님의 친절한 답변에 감사합니다.열심히 연구 노력해보겠습니다.^^

  2. 키움 2019.04.07 21:31

    여기 글을 보고 키움증권 api를 통해 만들어 보려고 하는데 막히는 부분이 있어서 여쭙니다

    k1:=ComObjCreate("KHOPENAPI.KHOpenAPICtrl.1")
    k1.CommConnect() -> 여기서 오류가 납니다


    파이썬 코드를 보면
    self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
    self.kiwoom.dynamicCall("CommConnect()")


    혹시 해결방안에 대해 아시면 답해주시면 감사하겠습니다. ㅠㅠ

    • 남성 2019.04.07 22:33 신고

      글쎄요 제가 키움증권 API 를 사용하고 있지는 않아서.... Connect 부분에서 에러나는 거면 키움증권 API 관련 사이트에 질문 하면 쉽게 해결 될 수 있지 않을까 합니다.

  3. 2019.07.29 12:57

    비밀댓글입니다

    • 남성 2019.07.29 14:08 신고

      github 에 올려 놓은거라 복사됩니다. 위 코드의 아래 부분에 있는 view raw 라고 써 있는 부분을 클릭하면 새창에서 코드가 열리니 복사 하셔도 되고 그냥 파일로 받고 싶으면 그 옆에 파일명을 클릭하면 github 사이트로 넘어가서 다운로드 받을 수 있습니다. 방문해 주셔서 감사합니다. ^^

Autohotkey 를 사용하여 특정 폴더에 있는 특정 확장자의 파일 수를 세기 위해 함수를 하나 만들어 봤습니다. Autohotkey 에서는 Loop 문을 통해 특정 확장자 파일 모두에 대해 접근을 할 수 있고 루프를 돌 때마다 A_Index 값이 증가 합니다. 이를 사용하면 파일의 갯수를 셀 수 있습니다. 다수의 특정 확장자 입력을 받을 수 있도록 했습니다.

코드는 다음과 같습니다.






위 코드중 제가 만든 함수는 fileCount() 이고 다음과 같이 폴더와 확장자를 지정하면 해당 폴더에 있는 특정 확장자의 갯수가 몇개인지를 알려 주는 함수 입니다. 확장자는 여러개를 순차적으로 넣으면 되고 아래 예에서는 jpg, png 파일을 찾도록 한 것입니다.

directV=C:\testFolder

N_Files := fileCount(directV, "jpg", "png")

그런데 검색을 조금 해 보니 특정폴더에 파일 개수를 찾기 위해서 Windows COM 을 사용하는 방법도 있더군요. Scripting.FileSystemObject, Shell.Application 등을 사용하는 방법이었으며 해당 방법들을 사용해도 동일한 결과를 얻을 수 있습니다. COM 을 사용하는 예에서 Shell.Application 을 사용하여 Item 의 갯수를 찾는 경우 숨김폴더는 제외한 갯수를 알려 주더군요.



오늘은 Autohotkey를 통해 증권사 API를 사용하는 방법에 대해 소개하려합니다. 일단 증권사 API를 사용하기 위해서는 증권사 API 의 설치나 TR과 같은 기본적인 개념에 대해 알아야 되겠고, 해당 내용들은 아래 주소의 ’파이썬으로 배우는 알고리즘 트레이딩’ 이나 증권사의 API 메뉴얼을 참조하시기 바랍니다.

파이썬으로 배우는 알고리즘 트레이딩: https://wikidocs.net/book/110

이베스트증권 API 메뉴얼: http://www.ebestsec.co.kr/apiguide/guide.jsp?cno=100

시스템 트레이딩을 위한 언어로 많은 분들이 C#, 파이썬, C/C++ 등을 사용하고 있는 것 같습니다. 보통 증권사의 시스템 트레이딩을 위한 API는 DLL 버전과 COM(Component Object Model) 버전을 제공해 주더군요. 저는 개인적으로 COM 버전이 사용하기가 쉬워서 COM 버전을 사용하고 있습니다. 시스템트레이딩을 위한 언어로는 파이썬을 사용하고 있고요.

Autohotkey 를 사용하여 시스템트레이딩을 한다고 하는 분은 지금까지 한번도 보지못했는데, COM 을 사용하다 보니 Autohotkey 를 사용해도 될 것 같다는 생각이 들었고, 시도해 보니 그리 어렵지 않게 이베스트증권 xingAPI 를 사용할 수 있었습니다.

Autohotkey 를 사용하여 시스템 트레이딩을 하기 위해서는 32비트 Autohotkey 를 설치해야 합니다. 저는 아래 주소에서 Autohotkey 를 다운로드 받았고 Windows는 64비트 이지만 유니코드 32비트 버전을 설치 했습니다. 이베스트증권의 xingAPI 가 32비트 버전이라 Autohotkey 도 그에 맞춰서 설치를 했습니다.

https://autohotkey.com/download/

xingAPI 의 기본적인 개념에 대해 안다는 가정하에, Autohotkey를 사용하여 이베스트증권에 로그인을 하고 계좌번호를 불러오는 방법에 대해서 소개해 보려 합니다.

Autohotkey 를 사용하여 이베스트증권에 로그인 하고 계좌번호를 불러오는 코드는 다음과 같습니다.

Autohotkey 에서 COM 객체를 만들기 위해서는 ComObjCreate() 라는 함수를 사용하고 xingAPI 가 event 방식으로 동작하므로 ComObjConnect() 라는 함수를 사용하여 세션 객체를 Login 이라는 이벤트에 연결 시켰습니다. 이렇게 연결을 해 놓은 상태에서 ID, 비밀번호, 공인 인증서 비밀번호를 넣고, COM 객체의 login() 함수를 통해 이베스트증권 서버에 로그인을 시도하면 Login 이라는 event 명으로 응답이 오게 됩니다.

Autohotkey 의 ComObjConnect() 라는 함수의 정의는 아래와 같은데 저는 Prefix 로써 session_ 이라는 글자를 넣어줬고 session_Login 이라는 event 를 받는 함수를 만들어 줬습니다.

https://autohotkey.com/docs/commands/ComObjConnect.htm

ComObjConnect(ComObject, Prefix)

로그인이 정상적으로 된 경우 Login event 의 argument 인 code 값으로 0000 이 전달 되게 되고 코드의 중간에 있는 while 루프는 증권사의 응답을 기다리기 위해 넣어놓은 것 입니다.

로그인이 완료 된 이후에는 xingAPISession 인스턴스의 GetAccountListCount() 함수를 사용하여 계좌의 개수를 알 수 있습니다. 이후 계좌의 갯수만큼 루프를 돌면서 GetAccountList() 함수를 통해 계좌 번호를 알아내게 됩니다. Autohotkey Loop 내의 인덱스의 A_Index 는 1 부터 시작하지만 GetAccountList() 함수는 0 인덱스부터 시작하기 때문에 -1 을 해 준 것입니다.

본인의 이베스트증권 ID, PASSWORD, 공인인증서 비밀번호를 넣고 위 코드를 실행시켜 보면 다음과 같이 로그인이 정상적으로 됐다는 message box 와 보유한 계좌번호에 대한 message box 를 아래와 같이 확인할 수 있습니다.

※ 로그인 성공

※ 보유한 계좌 개수

※ 계좌 번호



  1. 이베스트 2018.10.06 22:40

    이베스트로 tr조회하려는데 도저희안되서그럽니다.혹시 뭐가 잘못되었는지 알수 있을까요?
    제공하신소스다음에 다음과 같이 했는데 안되서 그럽니다.뭐가 잘못된건지..알려주시면 감사하겟습니다.
    XAQuery_t1101 := ComObjCreate("XA_DAtaSet.XAQuery")
    XAQuery_t1101.ResFileName:="C:\eBest\xingAPI\Res\t1101.res"
    XAQuery_t1101.SetFieldData("t1101InBlock","shcode",0,"078020")
    XAQuery_t1101.Request(false)
    XAQuery_t1101_ReceiveData(szTrCode)
    {
    sName:=XAQuery_t1101.GetFieldData("t1101OutBlock","hname",0)
    }
    msgBox,%sName%
    하면 아무런 결과가 나오지를 않습니다.

    • 남성 2018.10.07 18:08 신고

      Request 를 한 이후에는 위 포스팅 내용처럼 while 문 등을 통해서 서버에서 응답이 올때까지 기다리게 해야 할 것입니다. 그리고 XAQuery_t1101_ReceiveData 함수는 ComObjConnect 를 통해 event binding 이 되어야 할 것입니다.

  2. 이베스트 2018.10.07 19:59

    정말 감사합니다.방장님. 죄송한데 코드를 조금만 고쳐주시면 안될까요? 초보라서 그런지 많이 어렵네요.ㅠ ㅠ 말씀하신대로 해봐도 안되네요.

아래 포스팅에서 Autohotkey 에서 Windows COM(Component Object Model) 을 사용한 사례에 대해서 소개를 한 적이 있습니다. Windows 컴퓨터 사용시 많이들 사용하는 Microsoft Office 제품을 사용할 때도 COM 을 사용하여 자동화를 할 수가 있습니다.

http://iamaman.tistory.com/1879

http://iamaman.tistory.com/461

http://iamaman.tistory.com/2001

http://iamaman.tistory.com/2021

Autohotkey 에서 COM 을 사용하기 위해서는 아래 메뉴얼 같이 COM object 를 만들어야 합니다.

https://autohotkey.com/docs/commands/ComObjCreate.htm

ComObjCreate의 입력값으로 CLSID 를 넣어줘야 하는데 CLSID 는 우리가 사용하고자 하는 COM 의 Program ID 입니다.

ComObject := ComObjCreate(CLSID [, IID])

탐색기 정보 등을 자동화 하고 싶으면 Shell.Application, Microsoft Word 를 자동화하고 싶으면 Word.application, Microsoft Powerpoint 를 자동화 하고 싶으면 PowerPoint.Application 을 넣어야 하는 식입니다.

COM 을 사용하기 위해서는 당연히 우리 컴퓨터에 사용할 수 있는 COM 이 어떤게 설치가 되어 있는지를 알아야 합니다. Microsoft Office 제품과 같이 우리가 설치한 경우에는 당연히 알 수 있겠지만 다른 프로그램들 같은 경우에는 어떤 이름을 사용해야 COM 을 사용할 수 있는 건지 잘 모르는 경우가 많습니다.

그래서 오늘은 Powershell 을 사용하여 우리 컴퓨터에 설치되어 있는 COM 을 검색하는 방법에 대해서 소개하려합니다. 해당 코드는 Powershell 코드이며 ‘개발자를 위한 Powershell’ 책의 예제에 있습니다.

책의 전체 소스 코드들은 아래 주소에서 다운로드 받을 수 있습니다.

https://github.com/dfinke/powershell-for-developers

그리고 아래 주소의 GetProgID 함수를 사용하면 우리 컴퓨터에 설치되어 있는 COM 을 검색할 수 있습니다.

https://github.com/dfinke/powershell-for-developers/blob/master/chapter10/GetProgID.ps1

Powershell 에서 다음과 같이 ps1 파일을 실행하면 되는데…..

.\GetProgID.ps1

내 컴퓨터에 몇 개의 COM 이 설치되어 있는지 확인을 해보려면 다음과 같이 명령어를 치면 됩니다. 제 컴퓨터에는 1800개 COM 이 있네요.

.\GetProgID.ps1 | measure


1800 개를 눈으로 확인하는 건 조금 불편 하니까 키워드로 검색하는 것이 좋습니다. 다음과 같이 word 를 검색해보면 Word.Application 뿐만 아니라 내가 잘 알지도 못하는 다양한 COM 들이 설치 되어 있다는 것을 알 수가 있습니다. 검색 되는 목록 중에서 Word.Application 을 사용 하면 되는 것이죠.

.\GetProgID.ps1 word


이베스트 xingAPI를 사용해서 시스템 트레이딩을 하시는 분들은 다음과 같이 검색해보시면 COM 이 나오는 것을 확인 하실수 있습니다. xingAPI 를 설치했으므로 검색이 되는 건 당연하겠죠.

.\GetProgID.ps1 XA_DataSet

.\GetProgID.ps1 XA_Session


저는 개인적으로 요즘 이베스트 xingAPI를 통해서 시스템 트레이딩을 조금씩 공부 해 보고 있는데, 컴퓨터 언어는 주로 파이썬을 사용하고 있습니다. 생각해보니 Autohotkey 나 Powershell 을 사용해서도 시스템 트레이딩이 가능할것도 같네요.



Autohotkey 를 사용하여 웹 자동화를 하는 경우 컴포넌트 오브젝트 모델(Component Object Model, COM) 을 사용하여 internet explorer 를 자동화 하곤 했는데~
 
최근에는 Chrome 을 주로 사용하기도 하고~ Python 에서 selenium 사용을 익히다 보니 Autohotkey 를 통한 웹 자동화에 소홀해 졌었습니다. 

그런데 최근 아래 포스팅을 보고 Autohotkey  에서 selenium 을 자동화 할 수 있다는 것을 알게 됐습니다. 


간단하게 정리한 과정은 다음과 같습니다.

1.  아래 주소에서 SeleniumBasic 을 다운로드 받고 설치 합니다.

2.  SeleniumBasic 설치시 WebDriver 도 설치가 되는데~  자신의 브라우저 버전과 안 맞아서 정상적으로 동작하지 않는다면 아래 주소에서 Third party software 부분에서 사용하고자 하는 브라우져의 WebDriver 를 설치 합니다. 


저는 현재 chrome 을 주로 사용하는데 ~ 과거 버전을 사용하고 있습니다. 그래서 최신 버전의  WebDriver 를 설치하니 정상적으로 동작하지 않더군요. 그래서 아래 주소에서 제 브라우저 버전에 맞는 WebDriver 의 버전이 무엇인지를 확인한 후에~  Chrome WebDriver 를 다운로드 받아서 설치 했습니다. 


chrome 의 버전을 확인하고 싶으시면 chrome 의 주소 표시 창에 chrome://help/  또는 chrome://version/ 이라고 치고 들어가 보시면 확인 할 수 있습니다.  저는 버전 54.0.2840.71 이어서~  ChromeDriver 2.25 버전을 아래 주소에서 다운로드 받았습니다.

 
다운로드 받고 압축을 푼 후에 SeleniumBasic이 설치된 폴더(Windows 7 : C:\Program Files\SeleniumBasic, Windows 10 : C:\Users\자신의계정\AppData\Local\SeleniumBasic ) 에 chromedriver.exe 파일을 붙여넣기 합니다. 

Autohotkey 에서 selenium 을 사용하는 예제 등은 첫 번째 링크의 예제를 확인해 보시기 바랍니다.

저는 다음과 같은 예제를 똑같이 따라 해 보니~ 

driver:= ComObjCreate("Selenium.CHROMEDriver") ;Chrome driver
driver.Get("http://the-automator.com/")
driver.findElementsByName("s").item[2].SendKeys("hello world")
MsgBox here

다음과 같이 정상적으로 동작하더군요. 


Autohotkey 에서 Selenium 사용시의 함수 이름 관련 글 : http://iamaman.tistory.com/2307 


  1. 김동민 2018.09.04 08:47

    안녕하세요 작성자님
    질문이 있어 글을 남겨봅니다

    위 스크립트 종료후에 바로 제어되고 있는 크롬창이 종료 되는데
    혹시 크롬창 유지 시켜주는 방법은 없을까요 ?

    • 남성 2018.09.04 13:09 신고

      프로그램이 종료 되기 때문에 크롬창이 꺼지는 것이므로 프로그램이 종료 되지 않게 해 주시면 되지 않을까요?

      아래와 같이 해 주니 프로그램이 종료되지 않고 따라서 브라우저도 살아 있네요.

      #Persistent
      ------Autohotkey 스크립트 ------
      return

  2. 김동민 2018.09.05 08:28

    감사합니다.
    막힌가슴히 뻥 뚤리네요!
    즐거운 하루 되세요 ^^

    • 남성 2018.09.05 13:45 신고

      도움되었다니 다행이네요. 방문해 주셔서 감사합니다. ^^

  3. 김동민 2018.09.05 20:01

    안녕하세요 작성자님
    염치 불구하고 질문좀 드리고자 또 방문드렸습니다..
    기존 파이썬으로 Selenium 을 이용하여 웹 자동화를 구성하다가
    오토핫키로 다시 해보고 있는데요

    driver.find_element_by_link_text("Expand All").click()
    위와 같은 파이썬 소스를
    driver.find_elementbylinktext("단계별A/S진행등록").click()
    위와같이 수정해보았는데 적용이 안되네요..
    혹시 방법이 있을까요 ??

    파이썬에선 잘 작동했는데 오토핫키는 뭔가 다른가보네요...ㅎ

    • 남성 2018.09.05 21:27 신고

      파이썬이랑 비교하면 함수 이름이 조금씩 다릅니다.

      아래 주소글 확인하면 Autohotkey 사용할때의 함수이름을 알 수 있을 거에요.

      http://iamaman.tistory.com/2307

      Python selenium 은 _(underscore) 로 구분된 함수 이름으로 만들었던데 Autohotkey 에서는 그렇지 않습니다. 예를 들어 질문하신 find_element_by_link_text 함수는 Autohotkey 에서는 FindElementsByLinkText 를 사용하시면 될겁니다.

      위 주소의 글 참조하면 다른 함수들 이름에 대해서도 어떻게 쓰는게 맞는건지 확인 할 수 있을 거에요.

  4. 징글징글벨라 2018.09.06 00:16 신고

    코드가 회사 컴에 있어서 지금은 확인이 안되고..

    사이트 들어가보니 잘못된 주소이거나 비공개 또는 삭제된 글이라네요 ~

    티스토리 계정 있어서 로그인 해봐도 안나오네여 ㅎㅎ

    • 남성 2018.09.06 01:28 신고

      어떤게 삭제 됐다는 건지....? 2307 글 삭제 안 됐는데 ...

  5. 김동민 2018.09.06 17:51

    ㅎㅎ 죄송합니다
    잠결에 쳐서 오타가 있었나봐요
    분명 다시 확인했었는데...ㅎ

    알려주신대로 일단 해결했습니다.

    2307 게시물에서도 참고 하고 공부해보고
    잘 모르겠으면 다시 찾아뵙겠습니다

    도움 정말 감사합니다!

  6. 셀레늄 2018.09.09 15:46

    셀레늄과 오토핫키를 어떤 경우에 같이 쓰게 되는건가요?

    • 남성 2018.09.09 18:35 신고

      웹 자동화를 하고 싶은 경우 셀레늄 라이브러리를 주로 사용하는데 언어 선택을 Autohotkey 로 한것 뿐입니다. Python 이든 C# 이든 자바든 편하신 언어 사용하시면 됩니다.

  7. named7 2019.03.07 17:15

    안녕하세요 작성자님
    게시글 올리신지 오래되서 답변을 해주실지는 모르겠지만
    질문이 있어서 댓글남겨요

    driver.findElementsByName("s").item[2].sendkeys(hello world) 와같이

    웹사이트 내 에있는 editbox에 키입력을하는건 성공을했는데 byname이 없고
    Classname&TagName 만 확인되는 버튼은 어떻게 클릭하는지 궁금합니다.

    driver.findElementsByClassName("btn").item[1].click() 이런식으로 작성을했는데 안되더군요..

    • 남성 2019.03.07 18:58 신고

      아래 주소 글 확인해보시면 사용가능한 함수 이름을 알수 있는데 FindElementByClass 라는함수를 사용해 보시는게 좋을것 같네요.

      https://iamaman.tistory.com/2307

아래 포스팅에서 MATLAB, Powershell, Python 에서 Outlook  을 사용하여 자동으로 메일 보내는 방법에 대해 알아봤는데요.




오늘은 Autohotkey 에서 아웃룩을 사용하여 자동으로 메일 보내는 방법에 대해 알아보려 합니다.

코드는 아래와 같습니다.

textBody =

(

안녕하세요. 남성입니다.


메일 보냅니다.

)


tempAttach =C:\Attach.jpg


obj := ComObjCreate("Outlook.Application")

newMail := obj.CreateItem(0)

newMail.Subject := "메일 제목"

newMail.Body := textBody

newMail.To := "받는 사람 메일 주소"


myAttachments := newMail.Attachments

myAttachments.Add(tempAttach)


newMail.Send()

ObjRelease(newMail)

ObjRelease(obj)

위 코드에 대해 간단히 소개하면

tempAttach 에는 첨부파일의 path 를 넣습니다. 다수의 파일을 첨부하고 싶다면 세미콜론(;)으로 구분합니다.

newMail.Subject 에는 메일 제목을 넣고 

newMail.Body 에는 본문의 텍스트를 넣습니다. 보통 본문은 여러 줄로 작성하니 위 예와 같이 textBody 라는 변수를 하나 만들어서 여러 줄로 텍스트를 넣을 수 있습니다.

newMail.To 에는 받는 사람의 주소를 넣습니다. 받는 사람이 여럿일 때는 마찮가지로 세미콜론으로 구분합니다.

추가로 참조를 넣고 싶다면 newMail.Cc 에 참조자의 메일 주소를 넣으면 됩니다.

저는 Autohotkey 를 사용하여 시간이 걸리는 작업을 진행시 작업이 끝났다는걸 알리기 위해 아웃룩 메일을 자동화 하곤 합니다.


탐색기의 주소를 알고 싶은 경우 탐색기에서 ALT + D 를 누른 후에 주소 값을 복사 하면 됩니다. 

Autohotkey 로 탐색기의 주소를 알고 싶은 경우에도 위의 내용을 코딩해 주면 되겠죠. 


해당 내용은 아래와 같을 겁니다. 



send, !d
sleep, 1000
send ^c

그런데 클립보드를 사용하다 보면 이상하게 주소가 저장이 안 될 때가 있습니다. 

그래서 COM 을 사용해 보기로 했습니다. 

Autohotkey 에서 COM 을 사용하여 현재 열린 탐색기의 폴더 주소를 아는 방법은 아래와 같습니다.

#NoEnv
#SingleInstance force

#a::   ; Shortcut : WIN + A
hwnd := WinExist("A")
WinGetClass class, ahk_id %hwnd%

if (class="CabinetWClass" or class="ExploreWClass")
{

for window, in ComObjCreate("Shell.Application").Windows
{
try
{
if (window.hwnd==hwnd)
{
sel := window.LocationURL

sel := RegExReplace(sel,"file:///","")
foldername := RegExReplace(sel,"/","\")
foldername := RegExReplace(foldername,"%20"," ")

Clipboard:=foldername
MsgBox,,, % foldername,1

break
}
}
}
}
return

위 코드를 실행 시킨 후에 탐색기를 연 상태에서 WIN + A 를 누르면 아래와 같이 msgbox 가 1 초간 열렸다가 꺼지고 클립보드에 폴더의 주소가 저장 됩니다.




아래 포스팅에서 작성한 바와 같이 Autohotkey 를 사용하면 COM 을 사용한 작업들을 할 수가 있습니다.

http://iamaman.tistory.com/461

COM 을 사용한 대표적인 작업으로는 Internet explorer 를 비롯하여 Microsoft Office 등을 자동활 할 수 있는데요~

오늘은 Microsoft Office powerpoint 파일을 안 보이게 여는 방법에 대해 조금 소개해 보려 합니다.

보통 엑셀 등에서는 Application object 의 visible 필드의 값을 false 로 하면 파일이 열려 있지만 보이지는 않게 설정 할 수 있습니다.

그런데 powerpoint 에서는 약간 다르더군요.

아래와 같이 file open 시에 4번째 옵션에 false 로 주면 화면에는 보여주지 않고 powerpoint 파일을 열 수 있습니다.

powerpointFile=C:\abc.pptx
pptApp := ComObjCreate("PowerPoint.Application") ; create PowerPoint object 
Xl_Workbook := pptApp.Presentations.Open(powerpointFile,,,false) ; Visible False


Xl_Workbook.Close
pptApp.Quit() 



  1. 김민혁 2018.12.06 09:29

    안녕하세요 좋은 자료 감사히 잘 보고 있습니다

    혹시 인터넷에 첨부된 엑셀파일을 저장하지 않고 열기를 선택하여 활성화된 엑셀파일을 Comobj 명령어로 바로 접근할수 없겠습니까?

    • 남성 2018.12.06 19:07 신고

      현재 엑셀 파일이 열려 있고 해당 엑셀 파일의 COM object 에 접근하기 위해서는 ComObjActive 를 사용하면 됩니다.

      exCOM := ComObjActive("Excel.application")
      exCOM.visible := False


      아래 포스팅도 참고 하시길~

      http://iamaman.tistory.com/1996

  2. 김민혁 2018.12.07 10:53

    답변 주셔서 대단히 감사합니다. 제가 당면한 상황 하나를 더 설명을 못했네요
    저장하지 않은(첨부파일 여러개를 저장하지 않고 열기를 선택한)
    1개 이상의 엑셀파일을 별도로 통제하고 싶습니다


    1. 제가 관리하는 엑셀파일 하나가 실행되어 있는 상태이고
    ( xl:= comobjcreate("Excel.Application")
    xl.open(path) 를 사용하고 있습니다)

    2. 그 상황에서 인터넷에서 엑셀 첨부파일을 열어서(저장하지 않고)
    첨부파일의 데이터를 1번의 엑셀파일에 붙여놓고 싶습니다

    3.문제점
    1) 첨부파일의 엑셀파일을 활성화된 상태에서
    xl2:= comojbactive("Excel.application").ActiveWindow
    xl2.range("A1").copy
    위의 스크립트를 실행하면 range가 알수없는 이름이라고 에러가 뜨고요

    2)
    xl2:= comojbactive("Excel.application")
    xl2.range("A1").copy

    이렇게 실행하면 첨부파일이 아닌 기존1번의 엑셀파일의 A1을 복사합니다..





    인터넷에 찾아봤는데 좋은 예시가 있었으나 이것도 에러가 납니다
    고수님 제발 부탁드립니다 해법을 알려주십시오


    It's recommended to use oExcel := Excel_Get() instead of oExcel := ComObjActive("Excel.Application") to access the Excel object for a few reasons - when you use oExcel := ComObjActive("Excel.Application");
    • if there is more than 1 running Excel process, it will get the first registered on the ROT (Running Object Table).
    • if the Excel process hasn't been registered on the ROT (if it was just opened), you will get a Com Error.
    • you will get an error if the worksheet is being edited

    #IfWinActive, ahk_class XLMAIN

    F1::

    oExcel := Excel_Get(), oSheet := oExcel.ActiveWorkbook.ActiveSheet

    oSheet.Columns("A").ColumnWidth := 4, oSheet.Columns("B").ColumnWidth := 16

    oSheet.Columns("C").ColumnWidth := 10, oSheet.Columns("D").ColumnWidth := 10

    oSheet.Columns("E").ColumnWidth := 40, oSheet.Columns("F").ColumnWidth := 60

    oSheet.Cells.Select



    oSheet.Sort.SortFields.Clear

    oSheet.Sort.SortFields.Add(oSheet.Range("F:F"),0,1,ComObjMissing(),0)

    oSheet.Sort.SetRange(oSheet.Range("A:M"))

    oSheet.Sort.Header := 1, oSheet.Sort.MatchCase := 0

    oSheet.Sort.Orientation := 1, oSheet.Sort.SortMethod := 1

    oSheet.Sort.Apply

    return

    #IfWinActive


    에러 문구:
    Call to nonexistent function.
    Specifically: Excel_Get(), oSheet := oExcel.ActiveWorkbook.ActiveSheet

    • 남성 2018.12.07 15:39 신고

      아래와 같이하면 복사가 될 겁니다.

      xl2:= ComObjActive("Excel.application")
      xl2.ActiveSheet.Range("A1").copy

  3. 김민혁 2018.12.07 10:56

    참고한 사이트는 해당사이트 입니다
    https://autohotkey.com/board/topic/77840-how-to-pass-com-object-pointer-to-a-script/#entry495039

UUID(Universally Unique Identifier) 는 개체를 식별하기 위한 고유 번호이다. 사람의 주민 번호와 비슷하다고 생각하면 될 것 같다.

 

UUID 에 대한 자세한 설명은 아래 주소에서 확인해 보자.

 

https://ko.wikipedia.org/wiki/%EB%B2%94%EC%9A%A9_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90

 

오라클 데이터베이스나 마이크로소프트 등에서는 GUID (Globally Unique Identifier) 라는 이름으로 사용한다고 한다.

 

https://ko.wikipedia.org/wiki/%EC%A0%84%EC%97%AD_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90

 

어쨌든 이런 UUID 는 다양한 프로그램에서 생성할 수 있는데~ 오늘은 내가 주로 사용하는 Powershell, Autohotkey, Python 에서 생성하는 방법에 대해 간단히 소개하려 한다.

 

Powershell 에서는 아래와 같은 명령어를 통해 GUID 를 생성 할 수 있다.

 

[guid]::NewGuid()

 

ToString() Method 를 통해 string 으로 표현할 수 있는데~ 아래와 같이 여러 개의 GUID 를 만들 수 있다.

 

1..10 | foreach { [guid]::NewGuid().ToString()}  


 

다음으로 Autohotkey 에서는 아래 명령으로 GUID 를 생성할 수 있다.

 

TypeLib := ComObjCreate("Scriptlet.TypeLib")

NewGUID := TypeLib.Guid

MsgBox %NewGUID%

 

이런 결과가 나오는 것을 확인 할 수 있다.

 

 

Python 등에서는 uuid 라는 모듈이 있으며~ 아래와 같이 간단하게 random 한 uuid 를 생성 할 수 있다.

 

import uuid

uuid.uuid4()


 

uuid 모듈에 대한 자세한 설명은 아래 매뉴얼을 참조하기 바란다.

 

https://docs.python.org/2/library/uuid.html

ImageMagick 은 이름에서도 알 수 있는 바와 같이 image 파일들에 대해 여러 효과를 낼 수 있는 툴인데요~

   

아래 포스팅에서 소개 드렸다시피 저는 캡쳐 한 이미지들로 GIF 파일을 만드는데 종종 사용하곤 했습니다. 

 

2012/03/22 - [유틸] - ImageMagick 으로 GIF 파일 만들기

 

그런데 아래 Autohotkey 포럼을 찾아보니 Autohotkey 에서 Com Object 를 통해 ImageMagick 을 사용할 수 있더군요.

 

현재 저는 Autohotkey unicode 32 비트를 사용하고 있어서 ImageMagick도 아래 주소에서 32 비트 dll 버전을 설치 했습니다.

 

http://www.imagemagick.org/script/binary-releases.php#windows


설치 중간에 아래 그림과 같은 설정 부분에서 OLE Control 설치 부분을 체크 했습니다.  

 

아래 포럼 주소에 imageMagick 사용과 관련한 예제가 나와있는데~


http://www.autohotkey.com/board/topic/56987-com-object-reference-autohotkey-v11/page-3#entry373462

 

여러 사진들을 사용하여 썸네일 이미지등을 만들 때 대단히 유용해 보이더군요.

 

oI := ComObjCreate("ImageMagickObject.MagickImage.1")

 

imgs := Object()

 

Loop, 16 {

filename := "plasma" . A_Index . ".jpg"

oI.convert("-size", "200x200", "plasma:", filename)

imgs.Insert(filename)

}

 

imgs.Insert("montage.jpg")

stitch(oI, imgs*)

 

stitch(obj, params*) {

obj.montage("-geometry", "+0+0", params*)

}

 

oI.convert("montage.jpg", "-verbose", "info:image_info.txt")

oI.convert("montage.jpg", "-define", "histogram:unique-colors=false", "histogram:histogram.gif") ; create histogram

FileRead, info, image_info.txt

FileDelete, image_info.txt

MsgBox % info

 

위 코드를 돌려보시면~ plasma1.jpg, plasma2.jpg, plasma3.jpg … 등과 같은 파일이 생성되고~ 마지막에 아래 그림과 같이

 

histogram.gif 파일과~

각 이미지들에 대한 모음인 montage.jpg 파일이 생성됩니다.



아래 포스팅에서 밝힌 바와 같이 Autohotkey에서는 ComObjCreate() 함수를 사용하여 COM object 를 사용 할 수 있습니다.

  

2012/08/16 - [programming language/Autohotkey] - Autohotkey_L을 이용한 MS Word 자동화


2012/06/24 - [programming language/Autohotkey] - Autohotkey_L 로 구글 검색하기


2012/05/21 - [programming language/Autohotkey] - Autohotkey_L Text to Speech


오늘은 ComObjCreate()를 사용하여 Autohotkey에서 VBScript 과 JScript 언어를 실행하는 방법에 대해 알아보려 합니다.

 

저는 현재 윈도우 7 64 비트 환경에 Autohotkey UNICODE 64 비트를 설치했었는데~ 64 비트에서는 ComObjCreate("ScriptControl") 가 정상적으로 실행되지 않더군요.

 

그래서 UNICODE 32 비트를 설치했습니다.

 

샘플로 실행해본 코드는 인터넷에서 찾아본 코드들로 다음과 같습니다.

 

첫 번재로 VBScript 입니다.

 

sc := ComObjCreate("ScriptControl")

 

;// define the Language

sc.Language := "VBScript"

 

;// define the VBScript

script =

(

Dim string

Arr = Array("Auto", "Hot", "key!")

For Each i In Arr

string = string & i

Next

MsgBox "Joined Array Elements:" & vbCR & string, 64, "VBScript MsgBox"

)

 

;// execute the VBScript

sc.ExecuteStatement(script)

 

;// extract values from the VBScript

MsgBox, 64, AutoHotkey MsgBox, % "Joined Array Elements:`n" sc.Eval("Arr(0) & Arr(1) & Arr(2)")

 

다음과 같은 실행 결과가 나오더군요.

 

두 번째로 JScript예제 입니다. 아래 예제는 Autohotkey 에서 JScript를 사용하여 URI Encoding 하는 예제 인데~

 

 

UriEncode(Uri)

{

oSC := ComObjCreate("ScriptControl")

oSC.Language := "JScript"

Script := "var Encoded = encodeURIComponent(""" . Uri . """)"

oSC.ExecuteStatement(Script)

Return, oSC.Eval("Encoded")

}

 

UriDecode(Uri)

{

oSC := ComObjCreate("ScriptControl")

oSC.Language := "JScript"

Script := "var Decoded = decodeURIComponent(""" . Uri . """)"

oSC.ExecuteStatement(Script)

Return, oSC.Eval("Decoded")

}

 

keyword := UriEncode("한글")

 

MsgBox % keyword

   

한글이라는 글자가 다음과 같이 encoding 돼서 나오더군요.


지난 포스팅에서 perl 을 이용한 워드 문서 생성 자동화에 대해 간략히 소개 드렸었는데요.



2012/01/11 - [컴퓨터일반] - Perl을 이용한 MS word 문서 생성 자동화


 

아래 주소의 글을 보니 Autohotkey_L 을 이용한 MS word 에 대한 예제 코드가 있더군요.

 

http://www.autohotkey.com/community/viewtopic.php?t=61509&start=30&p=393082#p393082

 

위 링크의 예제에서 끝에 파일로 저장하도록 수정해 봤습니다.

 

코드는 다음과 같구요~

 

oWord := ComObjCreate("Word.Application") ; create MS Word object

oWord.Documents.Add ; create new document

 

oWord.Selection.Font.Bold := 1 ; bold

oWord.Selection.TypeText("Visit ") ; type text

oWord.ActiveDocument.Hyperlinks.Add(oWord.Selection.Range, "http://www.autohotkey.com/forum/topic61509.html"

,"","","COM Object Reference [AutoHotkey_L]") ; insert hyperlink

oWord.Selection.TypeText("and learn how to work with ") ; type text

oWord.Selection.Font.Italic := 1 ; italic

oWord.Selection.TypeText("COM objects") ; type text

oWord.Selection.Font.Bold := 0, oWord.Selection.Font.Italic := 0 ; bold and italic off

oWord.Selection.TypeText(".") ; type text

oWord.Selection.TypeParagraph ; type paragraph (enter, new line)

 

;~ oWord.Visible := 1, oWord.Activate ; make it visible and activate it.

 

oWord.ActiveDocument.saveas("c:\autohotkeyMSWORD.docx")

oWord.Quit()

 

보시면 아시겠지만 autohotkeyMSWORD.docx 라는 워드 파일이 만들어집니다.

 

매번 반복해서 작성하게 되는 문서는 이런 자동화 툴들을 이용하면 편리하겠죠~

 

작성된 결과는 이렇게 보이더군요~




 


Autohotkey_L 을 이용하면 윈도우 COM (Component Object Model)도 쉽게 다룰 수 있다고 하는데요~

 

아직 COM 에 대해서는 제대로 몰라서 자유 자재로 사용하지는 못하지만 그 사용 가능성이 무궁무진 하다고 생각되서 열심히 구글링을 하고 있습니다.

 

검색을 하다 보니 아래 주소의 글을 발견했는데요.

 

http://aboutscript.com/blog/posts/313

 

Autohotkey_L 을 이용하여 구글 검색을 하는 간단한 예이지만 꽤 유용한 예라고 생각되서 소개 드리려 합니다.

 

코드는 다음과 같습니다.

 

pwb := ComObjCreate("InternetExplorer.Application") ; 익스플로러 object

pwb.visible := false ; 창 안보이게

pwb.ToolBar := false ;툴바 안보이게

 

InputBox, query ; 사용자 쿼리 받기

query_text:= "https://www.google.co.kr/webhp?hl=ko&tab=ww#hl=ko&newwindow=1&output=search&q=" . query ; 구글 검색 쿼리

 

pwb.navigate(query_text) ; 해당 페이지로 이동

while pwb.ReadyState != 4 ; 창 준비 될때까지 기다리기

    Sleep 100

 

pwb.visible := true ; 창 보이기

 

주석만으로도 이해가 될 만큼 쉬운 코드이지만 단축키 등으로 지정해 쓰면 굉장히 편리 할 거라고 생각되더군요.

 

위 코드를 실행하면 다음과 같이 input box 가 뜹니다.

 

위 그림의 빈칸에 자신이 검색하고자 하는 키워드를 써 넣고 엔터를 치면 google 검색이 돼서 아래 그림처럼 나오게 되죠.

 

위 Autohotkey 코드에서 툴바를 나타내지 않게 설정해서 윈도우 익스플로러 창이 왠지 좀 시원~~ 해 보이죠~


  1. 쥬르날 2012.06.26 05:46 신고

    알아두면 유용할 것 같네요 ^^

    • 남성 2012.06.26 09:05 신고

      윈도우 사용하신다면 적극 추천입니다. Autohotkey 이용하시면 반복작업 하실때 굉장히 편리하게 이용할 수 있습니다.

Autohotkey_L 를 사용하면서 참 쉽고 재미있다는 생각과 굉장히 강력하다는 생각을 동시에 하게 됩니다.

 

윈도우에서만 돌아 간다는게 유일하게 안타까운 점인데요~

 

오늘은 Autohotkey 로 이런 것도 할 수 있다~~ 의 예로서

 

Text-to-Speech 에 대해 간단하게 소개 드리려 합니다.

 

Text-to-Speech 는 말 그대로 문자를 말로 변환해서 스피커로 나오게 하는 건데요.

 

Autohotkey_L 에서는 단 몇 줄로 이런 기능의 구현이 가능 합니다.

 

이에 대한 소개는 아래 주소를 참조하시면 됩니다.

 

http://www.autohotkey.com/community/viewtopic.php?p=391483#p391483

 

소개에 있는 간단한 예제 코드를 돌려 보니깐

 

진짜 신기하고 재미 있더군요.

 

Text := "Hello World!" ; 스피커로 말 할 텍스트

 

SAPI := ComObjCreate("SAPI.SpVoice")

MsgBox, 0, Rate: 0, Speak the Text

SAPI.speak(Text) ; Hellp World 라는 텍스트 말하기

 

MsgBox, 0, Rate: -7, Slow down the Speech

SAPI.rate := -7

SAPI.speak(Text) ; Hellp World 라는 텍스트 느리게 말하기

 

MsgBox, 0, Rate: 7, Speed up the Speech

SAPI.rate := 7

SAPI.speak(Text) ; Hellp World 라는 텍스트 빠르게 말하기

 

 

SAPI.rate := 0 ; set to default rate

 

MsgBox, 0, Volume: 50, Lower the Volume (ranges 0-100)

SAPI.volume := 50

SAPI.speak(Text) ; Hellp World 라는 텍스트를 볼륨 50으로 말하기

 

코드 몇 줄에 이런 게 가능하다니 저는 위 코드 돌려 보고 진짜 신기하다는 생각이 들더군요.

 

SpVoice 와 관련한 다양한 Properties 와 Methods 들은 아래 주소에서 공부 하실 수 있습니다.

 

http://msdn.microsoft.com/en-us/library/ms723602

 

아쉽게도 한글 발음은 안되던데.

 

한국어를 영어 발음으로 바꿔서 해 보니깐 좀 웃기게 들리긴 하더군요. ㅋㅋㅋㅋ

 

위 코드에서 발음할 텍스트를 아래와 같이 바꾸고 실행시켜 보니깐~~

 

Text := "Daehanminkuk"

 

데~에~한 민 쿡 하고 들리더군요. ㅋㅋㅋ

 

한글 발음 방법 알고 계신 분은 댓글 좀~~ 굽신 굽신 ^^;

 

어쨌든 공부 좀 해봐야겠습니다.


+ Recent posts