한국GPT협회 표준교재

503. 엑셀 GPT 함수 활용

엑셀 셀에서 GPT를 부르는 gpt() 함수로 텍스트를 분류·정량화

엑셀 GPT 함수 활용

Learning Objectives
  • 엑셀 셀에서 OpenAI API를 호출하는 gpt() 사용자 정의 함수를 만든다.
  • 감성 분류·10점 척도 프롬프트로 후기 수백 건을 일괄 분석한다.
  • 같은 함수를 문의 분류·설문 요약 등 텍스트 처리에 재사용한다.
사례

고객후기 정량화 gpt() 함수

커머스 · 마케팅

학습 안내읽기 + 파일 열기. 제공된 샘플 데이터(.xlsx)를 열고, 아래 gpt() 함수를 직접 추가해 C·D열 수식을 따라 만들어 봅니다. 핵심은 VBA 코드가 아니라 "평가 기준을 프롬프트에 명시하면 누가 돌려도 같은 점수가 나온다"는 것 — Ch1의 형식 지정·퓨샷이 API 활용에서도 그대로 통한다는 점입니다.

비즈니스 상황 — 수백 건의 도서 후기 분류

커머스 마케팅 담당자가 도서 후기를 한 줄씩 읽고 긍정/부정을 분류합니다. 후기 한 건당 1~2분, 수백 건이면 하루가 갑니다. 분류 기준도 사람마다 달라 "좋지만 분량이 많다" 같은 혼합 후기는 담당자에 따라 결과가 갈립니다. 이 사례는 엑셀 VBA로 gpt() 사용자 정의 함수를 만들어, 셀 수식 드래그 한 번으로 전체 후기를 감성 분류(C열)하고 1~10점으로 정량화(D열)합니다.

DATA
후기 수집
A열 도서명 · B열 후기 본문
UDF
gpt() 함수 등록
VBA로 OpenAI API 호출
C열
감성 분류
긍정/부정 한 단어
D열
1~10점 정량화
기준 명시 프롬프트
REPORT
집계·비교
도서·시리즈별 점수 분포

실습 파일 — 도서 후기 샘플 데이터

A열 도서명·B열 후기가 담긴 샘플 데이터입니다. 아래에서 만든 gpt() 함수를 추가한 뒤 C·D열 수식을 채워 가며 실습합니다.

1~2분 → 1~2초
후기 1건 분류 시간 — 수식 드래그로 전 행 처리
기준의 일관성
프롬프트에 기준 명시 → 누가 돌려도 같은 결과
정량 비교 가능
1~10점 지표로 도서·시리즈·시점 비교
gpt() 함수의 구조. VBA 함수(약 200줄)는 ① 프롬프트 검증 → ② 셀/범위를 텍스트로 변환 → ③ 요청 JSON 구성 → ④ MSXML2.XMLHTTP로 OpenAI API 호출 → ⑤ 응답에서 답만 추출의 5단계입니다. 이 코드 역시 AI에게 "엑셀에서 =gpt(프롬프트, 셀) 형태로 쓰는 OpenAI API 호출 UDF를 만들어줘"라고 요청해 받습니다. API 키가 필요하며(유료), 키는 코드에 하드코딩하지 말고 별도 시트나 InputBox로 관리합니다.

gpt() 함수 만들기 ① — AI에게 코드 요청하는 프롬프트

VBA를 몰라도 됩니다. Claude Code/Codex 같은 AI(또는 ChatGPT)에게 아래처럼 원하는 동작을 말로 설명하면 전체 코드를 만들어 줍니다. 어려운 VBA 명령어를 쓸 필요가 없습니다.

엑셀 gpt() 함수 만들기 — 자연어 프롬프트
엑셀에서 ChatGPT를 함수처럼 쓰고 싶어요. 셀에 =gpt("질문 내용", 참고할_셀) 이렇게 입력하면, ChatGPT가 답해서 그 결과를 셀에 넣어 주면 좋겠어요. - 엑셀 VBA(매크로)로 만들어 주세요. - OpenAI API를 사용하고, 모델은 gpt-4.1로 해주세요. - 함수 이름은 gpt 로 하고, 두 번째 칸에 셀 하나나 범위(여러 칸)를 넣으면 그 내용도 함께 ChatGPT에 보내 주세요. - 내 API 키를 넣는 자리를 코드 맨 위에 알아보기 쉽게 만들어 주세요. - 복사해서 바로 붙여넣을 수 있게 전체 코드를 한 번에 주세요.

gpt() 함수 만들기 ② — 실제 사용된 VBA 코드

위 프롬프트로 받은 코드의 실제 예시입니다(샘플 파일에 들어 있는 코드 그대로). 엑셀에서 Alt+F11 → [삽입]▸[모듈]에 붙여넣고, 맨 위 API_KEY 자리에 본인 키만 넣으면 바로 동작합니다.

Module1 — 엑셀 gpt() 사용자 정의 함수 (VBA 전체)
' ==========================================================
' ChatGPT GPT() 커스텀 함수 (Excel VBA)
' 사용법:
'   =GPT("안녕")                                ' 단순 질문
'   =GPT("B2를 영어로 번역", A2)                 ' 단일 셀 참조
'   =GPT("이 데이터 읽고 인사이트 도출해줘", A1:C10) ' 범위 참조
' ==========================================================

Const API_KEY As String = "여기에 본인의 API KEY를 입력하세요"
Const MODEL_ID As String = "gpt-4.1"  ' API 호출용 모델
Const MAX_TOKENS As Long = 2000

Public Function GPT(ByVal prompt As String, Optional ByRef data As Variant) As String
    On Error GoTo ErrHandler
    Dim stage As String: stage = "init"

    If Len(Trim(prompt)) = 0 Then
        GPT = "Error: Please provide a valid prompt."
        Exit Function
    End If

    ' 범위/셀 인자가 넘어왔으면 [DATA] 블록으로 덧붙임
    stage = "range"
    Dim fullPrompt As String
    fullPrompt = prompt
    If Not IsMissing(data) Then
        fullPrompt = fullPrompt & vbLf & vbLf & "[DATA]" & vbLf & RangeToText(data)
    End If

    ' JSON Body 구성
    stage = "body"
    Dim bodyJson As String
    bodyJson = "{""model"":""" & MODEL_ID & """," & _
               """messages"":[" & _
                 "{""role"":""system"",""content"":""You are a helpful assistant.""}," & _
                 "{""role"":""user"",""content"":""" & JsonEscape(fullPrompt) & """}" & _
               "]," & _
               """max_tokens"":" & MAX_TOKENS & "}"

    ' HTTP 요청
    stage = "http"
    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP.6.0")
    http.Open "POST", "https://api.openai.com/v1/chat/completions", False
    http.setRequestHeader "Content-Type", "application/json"
    http.setRequestHeader "Authorization", "Bearer " & API_KEY
    http.send bodyJson

    stage = "parse"
    GPT = ExtractContent(http.responseText)
    Exit Function
ErrHandler:
    GPT = "Error[" & stage & "]: " & Err.Description
End Function

' 셀 하나의 값을 안전하게 문자열로 변환 (Error/Empty/Null/Object 모두 처리)
Private Function CellToText(ByRef v As Variant) As String
    On Error Resume Next
    Dim s As String
    If IsObject(v) Then
        s = CStr(v.Value2)       ' Range 같은 개체면 .Value2 로 풀어서
    ElseIf IsError(v) Then
        s = "#ERR"
    ElseIf IsNull(v) Or IsEmpty(v) Then
        s = ""
    Else
        s = CStr(v)
    End If
    If Err.Number <> 0 Then
        s = ""
        Err.Clear
    End If
    On Error GoTo 0
    CellToText = s
End Function

' 범위/배열/단일값을 탭(열) + 줄바꿈(행) 텍스트로 변환
' - Excel UDF 는 Range 를 보통 2D Variant 배열로 전달함
' - 혹시 Range 객체 그대로 들어와도 .Value2 로 변환
Private Function RangeToText(ByRef data As Variant) As String
    On Error GoTo RangeErr
    Dim arr As Variant
    Dim result As String

    ' Range 객체면 값 2D 배열로 변환
    If IsObject(data) Then
        arr = data.Value2
    Else
        arr = data
    End If

    If IsArray(arr) Then
        Dim rLo As Long, rHi As Long, cLo As Long, cHi As Long
        Dim is2D As Boolean: is2D = False

        rLo = LBound(arr, 1): rHi = UBound(arr, 1)

        On Error Resume Next
        cLo = LBound(arr, 2)
        cHi = UBound(arr, 2)
        If Err.Number = 0 Then is2D = True
        Err.Clear
        On Error GoTo RangeErr

        Dim r As Long, c As Long
        If is2D Then
            For r = rLo To rHi
                If r > rLo Then result = result & vbLf
                For c = cLo To cHi
                    If c > cLo Then result = result & vbTab
                    result = result & CellToText(arr(r, c))
                Next c
            Next r
        Else
            For r = rLo To rHi
                If r > rLo Then result = result & vbLf
                result = result & CellToText(arr(r))
            Next r
        End If
    Else
        result = CellToText(arr)
    End If

    RangeToText = result
    Exit Function
RangeErr:
    RangeToText = "[Range 변환 실패: " & Err.Description & "]"
End Function

' JSON 문자열 이스케이프 (요청 본문용)
Private Function JsonEscape(ByVal s As String) As String
    s = Replace(s, "\", "\\")
    s = Replace(s, """", "\""")
    s = Replace(s, vbCrLf, "\n")
    s = Replace(s, vbLf, "\n")
    s = Replace(s, vbCr, "\n")
    s = Replace(s, vbTab, "\t")
    JsonEscape = s
End Function

' 응답 JSON에서 assistant의 content 값만 추출 (간이 파서)
' - 공백/줄바꿈이 섞인 pretty JSON 모두 대응
' - \uXXXX 유니코드 이스케이프도 처리
Private Function ExtractContent(ByVal json As String) As String
    Const KEY As String = """content"":"
    Dim i As Long
    i = InStr(1, json, KEY)
    If i = 0 Then
        ExtractContent = "Error: " & json
        Exit Function
    End If
    i = i + Len(KEY)

    ' 콜론 다음 공백/탭/줄바꿈 skip
    Do While i <= Len(json)
        Dim c As String: c = Mid(json, i, 1)
        If c = " " Or c = vbTab Or c = vbLf Or c = vbCr Then
            i = i + 1
        Else
            Exit Do
        End If
    Loop

    ' 여는 따옴표 확인
    If i > Len(json) Or Mid(json, i, 1) <> """" Then
        ExtractContent = "Error: cannot find content opening quote"
        Exit Function
    End If
    i = i + 1

    Dim ch As String, nxt As String, result As String, hex4 As String
    Do While i <= Len(json)
        ch = Mid(json, i, 1)
        If ch = "\" Then
            nxt = Mid(json, i + 1, 1)
            Select Case nxt
                Case """": result = result & """":       i = i + 2
                Case "\":  result = result & "\":        i = i + 2
                Case "/":  result = result & "/":        i = i + 2
                Case "n":  result = result & vbLf:       i = i + 2
                Case "r":  result = result & vbCr:       i = i + 2
                Case "t":  result = result & vbTab:      i = i + 2
                Case "b":  result = result & Chr(8):     i = i + 2
                Case "f":  result = result & Chr(12):    i = i + 2
                Case "u"
                    hex4 = Mid(json, i + 2, 4)
                    result = result & ChrW(CLng("&H" & hex4))
                    i = i + 6
                Case Else: result = result & nxt:        i = i + 2
            End Select
        ElseIf ch = """" Then
            Exit Do
        Else
            result = result & ch
            i = i + 1
        End If
    Loop
    ExtractContent = result
End Function

셀에서 쓰는 모습 — 수식이 곧 프롬프트

C열 — 감성 분류 수식
=gpt("이 독서 후기를 읽고, 고객의 감성분석을 하자. 출력 형식은 '긍정'과 '부정' 중 하나의 단어를 출력한다.", B2)
D열 — 1~10점 정량화 프롬프트 (셀 참조로 호출)
당신은 도서 후기 감성 분석 및 만족도 정량화 전문가입니다. 각 후기를 독립적으로 분석하여 다음 작업을 수행하세요. # 작업 1. 각 후기를 [긍정] 또는 [부정]으로 분류합니다. 2. 각 후기를 1~10점 척도로 정량화합니다. 3. 점수는 전반적인 만족도, 추천 의사, 학습 효과, 불만 강도를 종합해 판단합니다. # 점수 기준 - 10점: 매우 강한 만족, 강력 추천 / 9점: 매우 만족, 추천 의사 강함 - 8점: 전반적 만족, 장점 분명 / 7점: 대체로 긍정, 일부 제한점 - 6점: 약한 긍정, 기본 용도로 적합 / 5점: 장단점 비슷하나 아쉬움이 큼 - 4점: 부정 평가 뚜렷 / 3점: 실망감 큼 / 2점: 매우 불만족 / 1점: 극단적 불만 # 주의사항 - 장단점 혼재 후기는 최종 만족도와 추천 가능성으로 판단 - "좋지만"·"아쉽다"가 있어도 전체적으로 추천이면 긍정 분류 가능 - "후회"·"비추천"·"환불"·"실망"은 낮은 점수에 강하게 반영 출력은 반드시 점수에 해당하는 숫자만 출력하세요.

GPT 함수 실행 결과

학습 안내산출. 직접 실행하려면 OpenAI API 키가 필요합니다(키가 없으면 파일 구조 확인과 프롬프트 분석까지만 진행). 완료 기준: C·D열이 채워지고, 점수 분포가 피벗테이블/COUNTIF로 집계되면 통과.

달성 목표
샘플 후기 데이터에 gpt() 함수를 적용해 전 행의 감성 분류(C열)와 1~10점(D열)을 자동 생성하고, 점수 분포를 집계표로 만든다.

완성하면 시트가 아래 모습이 됩니다. (원본 사례의 100건 분포: 9점 18건 · 10점 25건 등)

최종 결과물 — 후기 정량화 시트
A 도서명B 후기C 감성(gpt)D 점수(gpt)
중학 수학 개념서개념 설명이 친절해서 혼자 공부하기 좋아요. 강추!긍정9
중학 수학 개념서기본기용으로는 좋지만 상위권 문제는 부족해요.긍정6
영어 독해 문제집해설이 너무 빈약해서 후회합니다. 비추천.부정2

실습 순서

  1. 위에서 받은 08_커머스_책 후기_샘플.xlsx를 연다.
  2. Alt+F11 → [삽입]▸[모듈]에 위의 gpt() VBA 코드를 붙여넣고, 맨 위 API_KEY 자리에 본인 OpenAI 키를 입력한다. 파일은 .xlsm(매크로 사용 통합 문서)으로 저장한다.
  3. C2·D2 수식을 실행해 1건이 동작하는지 확인한 뒤, 아래로 드래그해 전 행을 처리한다.
  4. D열 점수로 1~10점 분포 집계표(COUNTIF 또는 피벗)를 만든다.
  5. (응용) D열 프롬프트의 점수 기준을 본인 회사의 평가 기준으로 바꿔 다시 실행해 본다.
보안. API 키는 회사 공용 파일에 남기지 않습니다. 실습 후 키를 삭제하거나 키를 별도 시트에 두고 배포 전 제거하십시오. 고객 실명이 포함된 후기 데이터는 Ch1의 가명화 원칙을 적용한 뒤 API로 보냅니다.