오빠두엑셀 `2026 무료 챌린지` 오픈! 완주하고 수료증 받아가세요! 5년 연속 IT분야 베스트셀러! 「 진짜쓰는 실무엑셀 」로 2026년 공부 끝내기 엑셀이 막히셨나요? Q&A 게시판에서 바로 해결하세요.
메뉴
VBA 프로젝트 강의

[엑셀x카카오톡] 자동화 서식 만들기

오빠두엑셀 by 오빠두엑셀
  • 학습시간 1시간
  • 난이도 전문가
  • 작성일 2020.12.02

엑셀 VBA와 윈도우32 API를 사용하여 카카오톡 문자보내기를 자동화하는 명령문을 작성합니다.

이 강의에서는 엑셀 VBA와 Win32 API를 결합해 카카오톡 친구에게 메시지를 자동 전송하는 명령문을 작성하는 방법을 다룹니다. hWnd 개념부터 user32.dll 함수 호출, FindWindow·SendMessage·PostMessage 등 핵심 API 활용까지 단계별로 정리해, 반복되는 안내 메시지 발송 작업을 엑셀에서 그대로 자동화하는 흐름을 알아봅니다.

[엑셀x카카오톡] 자동화 서식 만들기
DOWNLOADS

실습자료를 준비했어요

수업에서 사용한 예제 파일과 보충 자료를 한 곳에 정리했습니다!👇

실습 가이드

.

라이브 강의 전체영상도 함께 확인해보세요!

위캔두 회원이 되시면 매주 오빠두엑셀에서 진행하는 라이브강의 풀영상을 확인하실 수 있습니다.


예제파일 다운로드

오빠두엑셀의 강의 예제파일은 여러분을 위해 자유롭게 제공하고 있습니다.


hWnd 란 무엇인가요?

윈도우 hwnd

hWnd는 'Handle to the Window'의 약자로, 윈도우에서 실행 중인 프로그램의 창에 부여되는 고유 식별값을 의미합니다. 윈도우에서 동작하는 모든 프로그램의 모든 창(Window)은 각각 고유한 값을 가지며, 이번 강의에서 다룰 카카오톡 또한 단계별로 실행되는 각 창마다 고유한 hWnd 값을 가지게 됩니다.

Window Detective (윈도우 hWnd 조회 프로그램) 다운로드

강의 초반부에 간략히 설명한 hWnd(Handle to Window: 실행 중인 프로그램의 고유 창 번호)를 조회하려면 Window Detective 프로그램이 필요합니다. (이 외에도 Spy++, WinSpy++ 등 동일한 기능을 제공하는 다른 도구를 사용할 수 있습니다.)

현재 사용 중인 PC에서 실행 중인 카카오톡이나 다른 프로그램의 창 번호를 직접 조회하면서 강의를 실습하시려면, 아래 링크에서 Window Detective 프로그램을 설치한 뒤 강의를 진행해 주세요.

(아래에 정리된 최종 명령문에는 카카오톡에 사용되는 모든 클래스 이름과 창 이름이 이미 포함되어 있으므로, Window Detective를 설치하지 않으셔도 강의를 그대로 따라오실 수 있습니다.)

윈도우 API 살펴보기

윈도우 API는 마이크로소프트가 윈도우 운영체제에서 동작하는 다양한 프로그램을 제어할 수 있도록 제공하는 API(Application Programming Interfaces)입니다. 윈도우 API는 운영체제 버전에 따라 다양하게 제공되며, 현재 가장 보편적으로 사용되는 버전은 Win32 API입니다.

Win32 API는 윈도우 95부터 제공되기 시작하였고, 2020년 기준으로 마이크로소프트는 Win32 대신 Win64 API 사용을 권장하고 있습니다. 다만 호환성 이슈를 고려하면, VBA에서 윈도우 API를 사용할 때는 여전히 Win32 API를 사용하는 것이 안전합니다.

윈도우 API는 운영체제 버전에 따라 다양한 형태로 지원됩니다.

  • Win16 / Win32 / WIn32s / Win64 / WinCE

윈도우 API에서 제공되는 함수는 크게 8개의 카테고리로 구분할 수 있습니다. 특히 엑셀 VBA에서 가장 자주 사용되는 윈도우 API 라이브러리는 User32.dll이며, 이번 강의에서도 user32.dll 라이브러리에서 제공되는 함수만 사용하였습니다.

  1. Base Service (kernel32.dll) :
    파일 시스템, 장치, 스레드, 오류 처리 등 핵심 리소스 접근에 사용됩니다.
  2. Advanced Service (advapi32.dll) :
    윈도우 레지스트리, 시스템 재부팅·시작·종료, 계정 생성 등 부가 기능 접근에 사용됩니다.
  3. Graphics Device Service (gdi32.dll) :
    모니터, 프린터 등 그래픽 출력 장치 접근에 사용됩니다.
  4. ★ User Interface (user32.dll) :
    화면, 마우스, 키보드, 윈도우 GUI 제어 등 엑셀과 외부 프로그램을 연동할 때 가장 많이 사용되는 라이브러리입니다.
  5. Common Dialog Box Library (comdlg32.dll) :
    응용 프로그램 실행, 파일 저장 등을 위한 공용 대화상자 접근에 사용됩니다.
  6. Common Control Library (comctl32.dll) :
    상태 표시줄, 도구 모음 등 일부 프로그램에서 제공하는 컨트롤 접근에 사용됩니다.
  7. Windows Shell (shell32.dll) :
    셸(Shell) 접근에 사용되며, 다양한 명령문을 통한 프로그램 제어에 활용됩니다.
  8. Network Services :
    인터넷 익스플로러, FTP 접속 등 네트워킹 기능 제어에 사용됩니다.

강의에 사용된 전체 명령문

Option Explicit
 
#If VBA7 Then
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa
Private Declare PtrSafe Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
                                                        (ByVal lpClassName As String, _
                                                        ByVal lpWindowName As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowexa
Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
                                                            (ByVal hwndParent As Long, _
                                                            ByVal hwndChildAfter As Long, _
                                                            ByVal lpszClass As String, _
                                                            ByVal lpszWindow As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagea
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
Private Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-keybd_event
Private Declare PtrSafe Sub keybd_event Lib "user32.dll" _
                                                            (ByVal bVk As Byte, _
                                                            ByVal bScan As Byte, _
                                                            ByVal dwFlags As Long, _
                                                            ByVal dwExtraInfo As Long)
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate
Private Declare PtrSafe Function GetKeyState Lib "user32" ( _
                                                            ByVal nVirtKey As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindow
Public Declare PtrSafe Function GetWindow _
                                                        Lib "user32" _
                                                        (ByVal hwnd As Long, _
                                                        ByVal wCmd As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassname
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpClassName As String, _
                                                            ByVal nMaxCount As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtexta
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpString As String, _
                                                            ByVal cch As Long) As Long
#Else
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
                                                        (ByVal lpClassName As String, _
                                                        ByVal lpWindowName As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowexa
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
                                                            (ByVal hwndParent As Long, _
                                                            ByVal hwndChildAfter As Long, _
                                                            ByVal lpszClass As String, _
                                                            ByVal lpszWindow As String) As Long
' https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagea
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal wMsg As Long, _
                                                            ByVal wParam As Long, _
                                                            ByRef lParam As Any) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-keybd_event
Private Declare Sub keybd_event Lib "user32.dll" _
                                                            (ByVal bVk As Byte, _
                                                            ByVal bScan As Byte, _
                                                            ByVal dwFlags As Long, _
                                                            ByVal dwExtraInfo As Long)
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getkeystate
Private Declare Function GetKeyState Lib "user32" ( _
                                                            ByVal nVirtKey As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindow
Public Declare Function GetWindow _
                                                        Lib "user32" _
                                                        (ByVal hwnd As Long, _
                                                        ByVal wCmd As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclassname
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpClassName As String, _
                                                            ByVal nMaxCount As Long) As Long
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtexta
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
                                                            (ByVal hwnd As Long, _
                                                            ByVal lpString As String, _
                                                            ByVal cch As Long) As Long
#End If
 
'######################################
' 공통 상수 선언
'######################################
' 가상키 ASCII 코드
Public Const WM_SETTEXT = &HC
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const VK_RETURN = &HD
Public Const VK_CONTROL = &H11
Public Const VK_ESC = &H1B
Public Const KEYEVENTF_KEYUP As Long = 2
Public Const VK_A = &H41
Public Const VK_V = &H56
Public Const VK_C = &H43
Public Const VK_DOWN = &H28
Public Const VK_UP = &H26
 
'######################################
' 친구에게 카카오톡 메세지를 전송합니다.
'######################################
Function SendKakao(Target As String, Message As String, Optional ChatRoomSearch As Boolean = False, Optional iDelay As Long = 1) As Boolean
 
' 변수 선언
Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
 
' 친구 채팅입력창 hwnd 찾기
hwnd_RichEdit = FindRecepientHwnd(Target, ChatRoomSearch, iDelay)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
'보낼 대상의 채팅창 없을 경우 안내메세지 출력 후 종료
If hwnd_RichEdit = 0 Then MsgBox "보낼 대상의 카카오톡 대화창을 찾을 수 없습니다.": Exit Function
 
' 메세지 보내기
Send_TextMsg Message, hwnd_RichEdit
 
End Function
 
'######################################
' 카카오톡 메세지를 전송합니다.
'######################################
Sub Send_TextMsg(Message As String, hwnd_RichEdit As Long)
 
' 대화상대 채팅 입력창 hWnd 에 메세지 입력
Call SendMessage(hwnd_RichEdit, WM_SETTEXT, 0, ByVal Message)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
' 사용자 Ctrl 키 입력여부 확인
If IsCtrlKeyDown = False Then
    ' Ctrl 키 미입력 시, 메세지 전송
    Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
Else
    ' Ctrl 키 입력중일 경우, 강제로 Ctrl 키 올림 -> 메세지 전송 -> Ctrl 키 재입력
    keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
    Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
    keybd_event VK_CONTROL, 0, 0, 0
End If
 
End Sub
 
'######################################
' 보낼 대상의 hWnd 값을 찾습니다.
' 보낼 대상의 채팅창이 없을 경우 False를 반환합니다.
'######################################
Function FindRecepientHwnd(Target As String, ChatRoomSearch As Boolean, iDelay As Long) As Long
 
' 변수 선언
Dim dStart As Double
Dim hwnd_KakaoTalk As Long   ' 친구 채팅창 hwnd
Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
 
' 보낼대상의 카톡창 실행
ActiveChat Target, iDelay, ChatRoomSearch
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
' 보낼대상의 카톡창 Hwnd 찾기
hwnd_KakaoTalk = FindWindow(vbNullString, Target)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
dStart = Now
While hwnd_KakaoTalk = 0
    hwnd_KakaoTalk = FindWindow(vbNullString, Target)
    ' 1초 지날때까지 창을 못찾으면 함수 결과로 False 반환 후 종료
    If DateDiff("s", dStart, Now) > 1 Then FindRecepientHwnd = 0: Exit Function
Wend
 
' 친구의 채팅입력창 hWnd 찾기
hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit50W", vbNullString)  '카카오톡 버전에 따른 RichEdit ClassName 차이
If hwnd_RichEdit = 0 Then hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit20W", vbNullString)
 
FindRecepientHwnd = hwnd_RichEdit
 
End Function
 
'############################
' 친구 채팅창이 열려있지 않을 경우 채팅창을 검색 후 활성화합니다.
'############################
Function ActiveChat(Target As String, iDelay As Long, ChatRoomSearch As Boolean)
 
' 변수 설정
Dim hWndMain As Long: Dim hWndChild1 As Long: Dim hWndChild2 As Long: Dim hWndEdit As Long
Dim i As Long
 
' 대화상대 창 이미 열려있을 시 명령문 종료
If FindWindow(vbNullString, Target) > 0 Then Exit Function
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
 
' 카카오톡 메인 hWnd 검색 [▶▶▶▶▶F5키]
hWndMain = FindHwndEVA
' 카카오톡 메인 창 없으면 카톡 실행 안됨 -> 함수 False 반환 후 명령문 종료
If hWndMain = 0 Then ActiveChat = False: Exit Function
 
' 메인 [▶▶▶▶▶F5키]
hWndChild1 = FindWindowEx(hWndMain, 0, "EVA_ChildWindow", vbNullString)
'▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
' 연락처 목록 검색 -> EVA_Window 첫번째 항목
hWndChild2 = FindWindowEx(hWndChild1, 0, "EVA_Window", vbNullString)
' 채팅창 목록 검색 -> EVA_Window 두번째 항목
If ChatRoomSearch = True Then hWndChild2 = FindWindowEx(hWndChild1, hWndChild2, "EVA_Window", vbNullString)
' EVA_Window의 대화상대 검색창
hWndEdit = FindWindowEx(hWndChild2, 0, "Edit", vbNullString)
 
' 검색창에 대화상대 복사/붙여넣기
Call SendMessage(hWndEdit, WM_SETTEXT, 0, ByVal Target): MyDelay iDelay
' 채팅창 목록 검색일 경우 윗쪽방향키 눌러서 첫번째 항목 활성화
If ChatRoomSearch = True Then Call PostMessage(hWndEdit, WM_KEYDOWN, VK_UP, 0): MyDelay iDelay
' 엔터키로 채팅창 열기
Call PostMessage(hWndEdit, WM_KEYDOWN, VK_RETURN, 0): MyDelay iDelay
 
End Function
 
'############################
' 카카오톡 실행여부 확인 후, 실행중일 시 메인창의 hWnd 를 반환합니다.
'############################
Private Function FindHwndEVA() As Long
 
' 변수 설정
Dim hwnd As Long: Dim lngT As Long: Dim strT As String
 
' 현재 Desktop에서 실행중인 첫번째 프로그램 hWnd
hwnd = FindWindowEx(0, 0, vbNullString, vbNullString)
 
' 모든 hWnd 를 돌아가며 검색
While hwnd <> 0
    ' hWnd를 돌아가며 ClassName을 확인
    strT = String(100, Chr(0))
    lngT = GetClassName(hwnd, strT, 100)
    ' hWnd 의 ClassName 에 "EVA_Window_DblClk"이 포함될 경우
    If InStr(1, Left(strT, lngT), "EVA_Window_Dblclk") > 0 Then
        ' 해당 hWnd의 채팅창이름을 받아옵니다.
        strT = String(100, Chr(0))
        lngT = GetWindowText(hwnd, strT, 100)
        ' 채팅창 이름이 "카카오톡" 또는 "KakaoTalk"(영문OS 사용시)일 경우, hWnd 을 함수 결과로 반환 후 종료
        If InStr(1, Left(strT, lngT), "카카오톡") > 0 Or InStr(1, Left(strT, lngT), "KakaoTalk") > 0 Then FindHwndEVA = hwnd: Exit Function
    End If
hwnd = FindWindowEx(0, hwnd, vbNullString, vbNullString)
Wend
 
End Function
 
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'▶ MyDelay 함수
'▶ 임시 지연 코드
'▶ ______________iDelay    : 지연 속도 조절 (클수록 많은 지연, 1 ≒ 4ms)
'###############################################################
Sub MyDelay(Optional iDelay As Long = 1)
 
Dim i As Long
For i = 1 To iDelay * 10000000:        i = i + 1:        Next
 
End Sub
 
'###############################################################
'오빠두엑셀 VBA 사용자지정함수 (https://www.oppadu.com)
'▶ IsCtrlKeyDown 함수
'▶ 키보드 Ctrl 키 누름여부를 확인합니다.
'▶ 인수 설명
'_____________LeftRightKey : 왼쪽/오른쪽 Ctrl 키 누름여부를 정합니다.
' 1 : 왼쪽 Ctrl키 입력시 TRUE
' 2 : 오른쪽 Ctrl키 입력시 TRUE
' 3 : 양쪽 Ctrl키 동시 입력시 TRUE
' 0 : 둘 중 하나라도 입력시 TRUE
'###############################################################
 
Private Function IsCtrlKeyDown(Optional LeftRightKey As Long = 0) As Boolean
 
Const VK_LCTRL = &HA2: Const VK_RCTRL = &HA3: Const KEY_MASK As Integer = &HFF80
 
Dim Result As Long
 
Select Case LeftRightKey
    '왼쪽 CTRL 키 입력여부 확인
    Case 1:        Result = GetKeyState(VK_LCTRL) And KEY_MASK
    '오른쪽 CTRL 키 입력여부 확인
    Case 2:        Result = GetKeyState(VK_RCTRL) And KEY_MASK
    '양쪽 CTRL 키 동시 입력여부 확인
    Case 3:        Result = GetKeyState(VK_LCTRL) And GetKeyState(VK_RCTRL) And KEY_MASK
    'CTRL 키 둘중 하나의 입력여부 확인
    Case Else:    Result = GetKeyState(vbKeyControl) And KEY_MASK
End Select
 
IsCtrlKeyDown = CBool(Result)
 
End Function

강의에 사용된 보조 명령문 목록

엑셀 카카오톡 자동화 명령문 순서

이번 강의에서 제작하는 SendKakao 명령문은 크게 4개의 보조 명령문으로 구성되며, 각 보조 명령문의 역할은 아래와 같습니다.

  1. FindHwndEVA 함수 : 카카오톡 실행 여부를 확인하고, 실행 중인 카카오톡 메인 윈도우의 hWnd 를 반환합니다.
    '############################
    ' 카카오톡 실행여부 확인 후, 실행중일 시 메인창의 hWnd 를 반환합니다.
    '############################
    Private Function FindHwndEVA() As Long
     
    ' 변수 설정
    Dim hwnd As Long: Dim lngT As Long: Dim strT As String
     
    ' 현재 Desktop에서 실행중인 첫번째 프로그램 hWnd
    hwnd = FindWindowEx(0, 0, vbNullString, vbNullString)
     
    ' 모든 hWnd 를 돌아가며 검색
    While hwnd <> 0
        ' hWnd를 돌아가며 ClassName을 확인
        strT = String(100, Chr(0))
        lngT = GetClassName(hwnd, strT, 100)
        ' hWnd 의 ClassName 에 "EVA_Window_DblClk"이 포함될 경우
        If InStr(1, Left(strT, lngT), "EVA_Window_Dblclk") > 0 Then
            ' 해당 hWnd의 채팅창이름을 받아옵니다.
            strT = String(100, Chr(0))
            lngT = GetWindowText(hwnd, strT, 100)
            ' 채팅창 이름이 "카카오톡" 또는 "KakaoTalk"(영문OS 사용시)일 경우, hWnd 을 함수 결과로 반환 후 종료
            If InStr(1, Left(strT, lngT), "카카오톡") > 0 Or InStr(1, Left(strT, lngT), "KakaoTalk") > 0 Then FindHwndEVA = hwnd: Exit Function
        End If
    hwnd = FindWindowEx(0, hwnd, vbNullString, vbNullString)
    Wend
     
    End Function
  2. ActiveChat 함수 : 카카오톡 친구목록에서 친구를 검색한 뒤 엔터키를 입력하여 채팅창을 활성화합니다.

    인수 설명
    Target As String 친구목록에서 검색할 친구 이름입니다.
    iDelay As Long 친구목록 검색 시 적용할 지연 시간입니다. (1 = 약 0.04s)
    ChatRoomSearch As Boolean TRUE 일 경우 대화목록에서 검색합니다.
    '############################
    ' 친구 채팅창이 열려있지 않을 경우 채팅창을 검색 후 활성화합니다.
    '############################
    Function ActiveChat(Target As String, iDelay As Long, ChatRoomSearch As Boolean)
     
    ' 변수 설정
    Dim hWndMain As Long: Dim hWndChild1 As Long: Dim hWndChild2 As Long: Dim hWndEdit As Long
    Dim i As Long
     
    ' 대화상대 창 이미 열려있을 시 명령문 종료
    If FindWindow(vbNullString, Target) > 0 Then Exit Function
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    ' 카카오톡 메인 hWnd 검색 [▶▶▶▶▶F5키]
    hWndMain = FindHwndEVA
    ' 카카오톡 메인 창 없으면 카톡 실행 안됨 -> 함수 False 반환 후 명령문 종료
    If hWndMain = 0 Then ActiveChat = False: Exit Function
     
    ' 메인 [▶▶▶▶▶F5키]
    hWndChild1 = FindWindowEx(hWndMain, 0, "EVA_ChildWindow", vbNullString)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
    ' 연락처 목록 검색 -> EVA_Window 첫번째 항목
    hWndChild2 = FindWindowEx(hWndChild1, 0, "EVA_Window", vbNullString)
    ' 채팅창 목록 검색 -> EVA_Window 두번째 항목
    If ChatRoomSearch = True Then hWndChild2 = FindWindowEx(hWndChild1, hWndChild2, "EVA_Window", vbNullString)
    ' EVA_Window의 대화상대 검색창
    hWndEdit = FindWindowEx(hWndChild2, 0, "Edit", vbNullString)
     
    ' 검색창에 대화상대 복사/붙여넣기
    Call SendMessage(hWndEdit, WM_SETTEXT, 0, ByVal Target): MyDelay iDelay
    ' 채팅창 목록 검색일 경우 윗쪽방향키 눌러서 첫번째 항목 활성화
    If ChatRoomSearch = True Then Call PostMessage(hWndEdit, WM_KEYDOWN, VK_UP, 0): MyDelay iDelay
    ' 엔터키로 채팅창 열기
    Call PostMessage(hWndEdit, WM_KEYDOWN, VK_RETURN, 0): MyDelay iDelay
     
    End Function
  3. FindRecepientHwnd 함수 : 친구 채팅창의 채팅 입력창 hWnd 를 반환합니다.
    인수 설명
    Target As String 친구목록에서 검색할 친구 이름입니다.
    iDelay As Long 친구목록 검색 시 적용할 지연 시간입니다. (1 = 약 0.04s)
    ChatRoomSearch As Boolean TRUE 일 경우 친구이름을 대화목록에서 검색합니다.
    '######################################
    ' 보낼 대상의 hWnd 값을 찾습니다.
    ' 보낼 대상의 채팅창이 없을 경우 False를 반환합니다.
    '######################################
    Function FindRecepientHwnd(Target As String, ChatRoomSearch As Boolean, iDelay As Long) As Long
     
    ' 변수 선언
    Dim dStart As Double
    Dim hwnd_KakaoTalk As Long   ' 친구 채팅창 hwnd
    Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
     
    ' 보낼대상의 카톡창 실행
    ActiveChat Target, iDelay, ChatRoomSearch
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    ' 보낼대상의 카톡창 Hwnd 찾기
    hwnd_KakaoTalk = FindWindow(vbNullString, Target)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    dStart = Now
    While hwnd_KakaoTalk = 0
        hwnd_KakaoTalk = FindWindow(vbNullString, Target)
        ' 1초 지날때까지 창을 못찾으면 함수 결과로 False 반환 후 종료
        If DateDiff("s", dStart, Now) > 1 Then FindRecepientHwnd = 0: Exit Function
    Wend
     
    ' 친구의 채팅입력창 hWnd 찾기
    hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit50W", vbNullString)  '카카오톡 버전에 따른 RichEdit ClassName 차이
    If hwnd_RichEdit = 0 Then hwnd_RichEdit = FindWindowEx(hwnd_KakaoTalk, 0, "RichEdit20W", vbNullString)
     
    FindRecepientHwnd = hwnd_RichEdit
     
    End Function
  4. Send_TextMsg 함수 : 채팅 입력창에 메시지를 입력한 뒤 엔터키를 눌러 메시지를 전송합니다.
    인수 설명
    Message As String 친구에게 보낼 메시지입니다.
    hwnd_RichEdit As Long 보낼 메시지를 입력할 채팅입력창의 hWnd 입니다.
    '######################################
    ' 카카오톡 메세지를 전송합니다.
    '######################################
    Sub Send_TextMsg(Message As String, hwnd_RichEdit As Long)
     
    ' 대화상대 채팅 입력창 hWnd 에 메세지 입력
    Call SendMessage(hwnd_RichEdit, WM_SETTEXT, 0, ByVal Message)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
    ' 사용자 Ctrl 키 입력여부 확인
    If IsCtrlKeyDown = False Then
        ' Ctrl 키 미입력 시, 메세지 전송
        Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
    Else
        ' Ctrl 키 입력중일 경우, 강제로 Ctrl 키 올림 -> 메세지 전송 -> Ctrl 키 재입력
        keybd_event VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
        Call PostMessage(hwnd_RichEdit, WM_KEYDOWN, VK_RETURN, 0)
        keybd_event VK_CONTROL, 0, 0, 0
    End If
     
    End Sub
  5. SendKakao 함수 : 지정한 친구에게 메시지를 전송합니다.
    인수 설명
    Target As String 메시지를 보낼 친구 이름입니다.
    Message As Long 친구에게 보낼 메시지입니다.
    ChatRoomSearch As Boolean TRUE 일 경우 친구이름을 대화목록에서 검색합니다.
    iDelay As Long 친구이름 검색 시 적용할 지연시간입니다.
    '######################################
    ' 친구에게 카카오톡 메세지를 전송합니다.
    '######################################
    Function SendKakao(Target As String, Message As String, Optional ChatRoomSearch As Boolean = False, Optional iDelay As Long = 1) As Boolean
     
    ' 변수 선언
    Dim hwnd_RichEdit As Long       ' 채팅입력창 hwnd
     
    ' 친구 채팅입력창 hwnd 찾기
    hwnd_RichEdit = FindRecepientHwnd(Target, ChatRoomSearch, iDelay)
    '▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶▶
     
    '보낼 대상의 채팅창 없을 경우 안내메세지 출력 후 종료
    If hwnd_RichEdit = 0 Then MsgBox "보낼 대상의 카카오톡 대화창을 찾을 수 없습니다.": Exit Function
     
    ' 메세지 보내기
    Send_TextMsg Message, hwnd_RichEdit
     
    End Function
댓글 96
4.8 (55개 평가)
SEANPAUL
SEANPAUL 2020.12.03 09:17
감히 천재라고 인정합니다
영혼의때를위하여
영혼의때를위하여 2020.12.03 14:36
오빠두엑셀 님 최고
mone****
mone**** 2020.12.03 15:01
항상 유용하고 멋진 강의 감사합니다.
제가 못 찾는 건지 모르겠는데 완성파일에 실제 입력하는 시트가 없어서요
오빠두엑셀
오빠두엑셀 작성자 2020.12.04 16:43
안녕하세요.
완성파일은 영상 후반부에 제작 완료한 (매크로가 포함된) 파일입니다. ^^
영상 초반부에 설명드린 카카오톡 문자보내기 자동화 양식은 아래 무료서식 링크를 확인해보시겠어요?
https://www.oppadu.com/product/%ec%97%91%ec%85%80-%ec%b9%b4%ec%b9%b4%ec%98%a4%ed%86%a1-%eb%ac%b8%ec%9e%90%eb%b3%b4%eb%82%b4%ea%b8%b0-%ec%9e%90%eb%8f%99%ed%99%94-%ec%84%9c%ec%8b%9d/
감사합니다.
군자소프
군자소프 2020.12.08 09:24
엑셀 시트에서 보내는 방법은 어디서 배울수 있는지 궁금 합니다 *^_^*
군자소프
군자소프 2020.12.08 09:23
엑셀 시트에서 보내는 방법은 어디서 배울수 있는지 궁금 합니다 *^_^*
오빠두엑셀
오빠두엑셀 작성자 2020.12.08 17:13
안녕하세요.
시트에서 명령문을 실행하는 방법은 다양합니다.
만약 도형을 추가한 뒤 버튼을 클릭하는 형태로 문자를 보내고자 하시면, 아래 강의를 참고해보세요 :)
https://www.oppadu.com/%ed%8f%89%ec%b0%bd%ec%98%ac%eb%a6%bc%ed%94%bd-%ea%b3%b5%ec%8b%9d-%eb%a1%9c%ea%b3%a0%eb%a5%bc-vba%eb%a1%9c-%ec%97%91%ec%85%80-vba-1-1/
군자소프
군자소프 2020.12.11 01:22
감사 합니다 *^_^*
군자소프
군자소프 2020.12.11 01:26
완성파일에서와 같이 만드려고 합니다
그런데 아무리 찾아 봐도 알수가 없어서요
위 링크는 엑셀 시트에서 vba 와 연동해서 카톡 보내는거와 틀려

솔직히 모르겠습니다 ㅠㅠ
완성 파일과 같이 하려면 어디를 봐야 할까요
시트위치 연동이 필요 한거 같습니다
시트위치를 지정을 어떻게 해주어야
명령이 실행이 되고
명령이 실행 될때 db 가져 오는 부분을 시트지정을
해줘야 할거 같은데 그부분을 모르겠습니다
바쁘실텐데 죄송 합니다
군자소프
군자소프 2020.12.11 19:41
인수설명
 Target As String메시지를 보낼 친구 이름입니다.
 Message As Long친구에게 보낼 메시지입니다.
 ChatRoomSearch As Boolean
TRUE 일 경우 친구이름을 대화목록에서 검색합니다. 
iDelay As Long친구이름 검색 시 적용할 지연시간입니다.
SendKakao(Target As String, Message As String, Optional ChatRoomSearch As Boolean = False, Optional iDelay As Long = 1)
위 함수에 시트 셀범위를 넣어 주면 될거 같은데
어떻게 넣어 줘야 할까요 ^^
오빠두엑셀
오빠두엑셀 작성자 2020.12.12 06:12
Dim Rng as Range: Dim R as Range
Dim Str as String
Set Rng = Range("범위")
For Each R in Rng
Str = Str & R.Value
Next
SendKakao "친구이름", Str
으로 사용해보세요 ^^
답변이 도움이 되셨길 바랍니다.
열공
열공 2020.12.28 16:06
안녕하세요? 멋진 오빠두엑셀님 여기 있는 전체 명령문을 이용하여 카톡을 보내보니 대화상대에게 채팅창을 띄워 메시지를 전송하고 메시지 창이 열린 상태로 다음 상대에게 보내는데.
대기시간이 짧을 경우 이미 보낸 이전 상대에게 다음 상대의 메시지를 보내더군요. 대기시간을 얼마를 줘야 할지 몰라 많이 늘려서 해 보는데 그렇게 하지 않고 하는 방법은 없을까요? 가령 새로 보내야 하는 대화상대의 값을 받아 와서 보낼 대화상대와 같으면 보내고 아니면 더 기다리고...
또한 보낸 대화상대의 채팅창을 종료하는 코드 좀 알려주세요?
june
june 2020.12.31 19:27
안녕하세요 영상 잘 보고 있습니다. 감사합니다.
예제파일을 보고 있는데요
visual basic에서 트리부분에 하나의 트리만 보이고
프로젝트가 잠겨있다고 나와 있는데요
어떻게 해야하나요?
오빠두엑셀
오빠두엑셀 작성자 2021.01.03 15:21
안녕하세요.
강의 관련 예제파일/완성파일에는 프로젝트 보안이 설정되어있지 않습니다.
다시 확인해보시겠어요?
감사합니다.
푸른나무
푸른나무 2021.01.03 18:18
강의 너무 유익했습니다. 실습해보려는데 Window Detective 이제 다운받을 수 없나요?
오빠두엑셀
오빠두엑셀 작성자 2021.01.07 05:17
안녕하세요.
Window Detective 는 위에 적어드린 링크에서 다운로드하실 수 있습니다.
푸른나무
푸른나무 2021.01.08 08:40
감사합니다~
파이어폭스
파이어폭스 2021.01.13 12:20
대단하십니다!!! 혹시 시트의 특정영역을 이미지로 카톡에 넣는 방법도 알려주실수 있으실까요?
엑셀초보000
엑셀초보000 2021.12.26 21:03
혹시 어떻게 넣어요
임선묵
임선묵 2022.03.13 17:25
헉 대단하시네요 혹 저도 좀 공유할수 있을까요??
EXCELCHOBO
EXCELCHOBO 2021.01.14 13:07
유용한 기능 감사합니다!!

혹시 사진을 다수의 인원에게 동시에 개인톡으로 발송하려고 하는데 어떻게 하면 되는지 여쭤볼 수 있을까요?