목록으로
📊 AI와 비즈니스 - 엑셀

AI로 엑셀 오류 해결하기 - ChatGPT 엑셀 트러블슈팅 가이드

#REF! #VALUE! 오류 때문에 머리 아프셨죠? AI가 오류 원인을 찾아내고 해결 방법을 알려드립니다.

재무 예측 모델 시뮬레이션

"내년 매출이 얼마나 될까?", "원가가 10% 오르면 이익은 얼마나 줄어들까?"... 이런 질문에 답하려면 재무 예측 모델이 필요해요. 하지만 통계 지식도 필요하고, 복잡한 수식도 만들어야 해서 쉽지 않죠.

AI를 활용하면 전문가 수준의 재무 모델을 쉽게 만들 수 있습니다. 과거 데이터만 있으면 AI가 추세를 분석하고 미래를 예측해줘요. 시나리오별 시뮬레이션도 자동으로 만들어주고, 민감도 분석까지 해줍니다.

이번 글에서는 AI로 재무 예측 모델을 만드는 방법을 알아봅니다. 매출 예측부터 손익 시뮬레이션, 손익분기점 분석까지 실무에서 바로 쓸 수 있는 모델들을 단계별로 구축해볼게요.

1. 매출 예측 모델

선형 회귀 기반 예측

AI 프롬프트:

"과거 3년 매출 데이터를 기반으로
향후 12개월 매출을 예측하는 모델을 만들어주세요.
추세선과 계절성을 모두 고려하세요."

AI 생성 수식:

// Sheet: 매출예측

// 선형 추세 예측
=FORECAST.LINEAR(A2, 과거매출!$B:$B, 과거매출!$A:$A)

// 또는 TREND 함수
=TREND(과거매출!$B$2:$B$37, 과거매출!$A$2:$A$37, A2)

// 계절성 지수 적용
=C2*INDEX(계절지수!$B:$B, MATCH(MONTH(A2), 계절지수!$A:$A, 0))

// 신뢰 구간 (상한/하한)
// 표준오차 계산
=STEYX(과거매출!$B$2:$B$37, 과거매출!$A$2:$A$37)

// 95% 신뢰구간 상한
=D2+1.96*$표준오차

// 95% 신뢰구간 하한
=D2-1.96*$표준오차

VBA로 자동 예측:

Sub 매출예측모델()
    Dim ws As Worksheet
    Dim forecastWs As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim forecastMonths As Integer

    Set ws = ThisWorkbook.Sheets("과거매출")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' 예측 시트 생성
    On Error Resume Next
    Set forecastWs = Sheets("매출예측")
    If forecastWs Is Nothing Then
        Set forecastWs = Sheets.Add(After:=ws)
        forecastWs.Name = "매출예측"
    Else
        forecastWs.Cells.Clear
    End If
    On Error GoTo 0

    ' 헤더
    With forecastWs
        .Cells(1, 1).Value = "예측월"
        .Cells(1, 2).Value = "추세 예측"
        .Cells(1, 3).Value = "계절 조정"
        .Cells(1, 4).Value = "최종 예측"
        .Cells(1, 5).Value = "하한 (95%)"
        .Cells(1, 6).Value = "상한 (95%)"
        .Cells(1, 7).Value = "신뢰도"
    End With

    ' 통계 계산
    Dim xValues As Range, yValues As Range
    Set xValues = ws.Range("A2:A" & lastRow)
    Set yValues = ws.Range("B2:B" & lastRow)

    Dim slope As Double, intercept As Double
    Dim stdError As Double, rSquared As Double

    slope = Application.WorksheetFunction.slope(yValues, xValues)
    intercept = Application.WorksheetFunction.Intercept(yValues, xValues)
    stdError = Application.WorksheetFunction.StEyx(yValues, xValues)
    rSquared = Application.WorksheetFunction.RSq(yValues, xValues)

    ' 계절 지수 계산
    Dim seasonalIndex(1 To 12) As Double
    Call 계절지수계산(ws, seasonalIndex)

    ' 예측 (12개월)
    forecastMonths = 12
    Dim lastDate As Date
    lastDate = ws.Cells(lastRow, 1).Value

    Application.ScreenUpdating = False

    For i = 1 To forecastMonths
        Dim forecastDate As Date
        Dim month As Integer
        Dim trendValue As Double
        Dim seasonalValue As Double
        Dim finalForecast As Double

        ' 다음 월
        forecastDate = DateAdd("m", i, lastDate)
        month = Month(forecastDate)

        ' 추세 예측 (선형)
        trendValue = slope * (lastRow + i) + intercept

        ' 계절 조정
        seasonalValue = trendValue * seasonalIndex(month)

        ' 최종 예측
        finalForecast = seasonalValue

        ' 신뢰 구간
        Dim margin As Double
        margin = 1.96 * stdError * Sqr(1 + 1 / lastRow)

        ' 결과 입력
        With forecastWs
            .Cells(i + 1, 1).Value = forecastDate
            .Cells(i + 1, 1).NumberFormat = "yyyy-mm"
            .Cells(i + 1, 2).Value = trendValue
            .Cells(i + 1, 3).Value = seasonalIndex(month)
            .Cells(i + 1, 3).NumberFormat = "0.00"
            .Cells(i + 1, 4).Value = finalForecast
            .Cells(i + 1, 5).Value = finalForecast - margin
            .Cells(i + 1, 6).Value = finalForecast + margin
            .Cells(i + 1, 7).Value = Format(rSquared, "0.0%")

            ' 숫자 서식
            .Cells(i + 1, 2).NumberFormat = "#,##0"
            .Cells(i + 1, 4).NumberFormat = "#,##0"
            .Cells(i + 1, 5).NumberFormat = "#,##0"
            .Cells(i + 1, 6).NumberFormat = "#,##0"
        End With
    Next i

    ' 차트 생성
    Call 예측차트생성(ws, forecastWs, lastRow, forecastMonths)

    forecastWs.Columns("A:G").AutoFit
    Application.ScreenUpdating = True

    MsgBox "매출 예측이 완료되었습니다." & vbCrLf & _
           "R² = " & Format(rSquared, "0.00%") & vbCrLf & _
           "향후 12개월 총 예측: " & _
           Format(Application.WorksheetFunction.Sum(forecastWs.Range("D2:D13")), "#,##0"), _
           vbInformation
End Sub

Sub 계절지수계산(ws As Worksheet, ByRef seasonalIndex() As Double)
    Dim lastRow As Long
    Dim monthlySum(1 To 12) As Double
    Dim monthlyCount(1 To 12) As Integer
    Dim i As Long, month As Integer
    Dim totalAvg As Double

    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' 월별 평균 계산
    For i = 2 To lastRow
        month = Month(ws.Cells(i, 1).Value)
        monthlySum(month) = monthlySum(month) + ws.Cells(i, 2).Value
        monthlyCount(month) = monthlyCount(month) + 1
    Next i

    ' 전체 평균
    totalAvg = Application.WorksheetFunction.Average(ws.Range("B2:B" & lastRow))

    ' 계절 지수 계산 (평균 대비 비율)
    For i = 1 To 12
        If monthlyCount(i) > 0 Then
            seasonalIndex(i) = (monthlySum(i) / monthlyCount(i)) / totalAvg
        Else
            seasonalIndex(i) = 1
        End If
    Next i
End Sub

Sub 예측차트생성(historyWs As Worksheet, forecastWs As Worksheet, _
                    historyRows As Long, forecastRows As Integer)
    Dim chartObj As ChartObject

    Set chartObj = forecastWs.ChartObjects.Add( _
        Left:=forecastWs.Range("I2").Left, _
        Top:=forecastWs.Range("I2").Top, _
        Width:=500, _
        Height:=300)

    With chartObj.Chart
        .ChartType = xlLineMarkers

        ' 과거 실적
        .SeriesCollection.NewSeries
        With .SeriesCollection(1)
            .Name = "과거 실적"
            .XValues = historyWs.Range("A2:A" & historyRows)
            .Values = historyWs.Range("B2:B" & historyRows)
            .Format.Line.ForeColor.RGB = RGB(79, 129, 189)
            .MarkerStyle = xlMarkerStyleCircle
        End With

        ' 예측
        .SeriesCollection.NewSeries
        With .SeriesCollection(2)
            .Name = "예측"
            .XValues = forecastWs.Range("A2:A" & forecastRows + 1)
            .Values = forecastWs.Range("D2:D" & forecastRows + 1)
            .Format.Line.ForeColor.RGB = RGB(192, 80, 77)
            .Format.Line.DashStyle = msoLineDash
            .MarkerStyle = xlMarkerStyleDiamond
        End With

        ' 신뢰구간 상한
        .SeriesCollection.NewSeries
        With .SeriesCollection(3)
            .Name = "상한"
            .XValues = forecastWs.Range("A2:A" & forecastRows + 1)
            .Values = forecastWs.Range("F2:F" & forecastRows + 1)
            .Format.Line.ForeColor.RGB = RGB(192, 192, 192)
            .Format.Line.Weight = 1
            .MarkerStyle = xlMarkerStyleNone
        End With

        ' 신뢰구간 하한
        .SeriesCollection.NewSeries
        With .SeriesCollection(4)
            .Name = "하한"
            .XValues = forecastWs.Range("A2:A" & forecastRows + 1)
            .Values = forecastWs.Range("E2:E" & forecastRows + 1)
            .Format.Line.ForeColor.RGB = RGB(192, 192, 192)
            .Format.Line.Weight = 1
            .MarkerStyle = xlMarkerStyleNone
        End With

        .HasTitle = True
        .ChartTitle.Text = "매출 예측 (95% 신뢰구간)"
        .HasLegend = True
        .Legend.Position = xlLegendPositionBottom
    End With
End Sub

2. 손익 시뮬레이션

AI 프롬프트:

"다양한 매출 시나리오(최선, 기본, 최악)에 따른
손익계산서를 자동으로 생성해주세요."

AI 생성 VBA:

Sub 손익시뮬레이션()
    Dim ws As Worksheet
    Dim simWs As Worksheet

    ' 시뮬레이션 시트 생성
    On Error Resume Next
    Set simWs = Sheets("손익시뮬레이션")
    If simWs Is Nothing Then
        Set simWs = Sheets.Add
        simWs.Name = "손익시뮬레이션"
    Else
        simWs.Cells.Clear
    End If
    On Error GoTo 0

    ' 레이아웃 생성
    With simWs
        ' 타이틀
        .Cells(1, 1).Value = "손익계산서 시뮬레이션"
        .Cells(1, 1).Font.Size = 14
        .Cells(1, 1).Font.Bold = True

        ' 시나리오 입력 영역
        .Cells(3, 1).Value = "시나리오"
        .Cells(3, 2).Value = "최악"
        .Cells(3, 3).Value = "기본"
        .Cells(3, 4).Value = "최선"

        ' 가정 입력
        .Cells(5, 1).Value = "** 주요 가정 **"
        .Cells(5, 1).Font.Bold = True

        .Cells(6, 1).Value = "월 매출액"
        .Cells(6, 2).Value = 80000000    ' 최악
        .Cells(6, 3).Value = 100000000   ' 기본
        .Cells(6, 4).Value = 120000000   ' 최선

        .Cells(7, 1).Value = "매출원가율 (%)"
        .Cells(7, 2).Value = 70
        .Cells(7, 3).Value = 60
        .Cells(7, 4).Value = 55

        .Cells(8, 1).Value = "판관비 (고정)"
        .Cells(8, 2).Value = 20000000
        .Cells(8, 3).Value = 20000000
        .Cells(8, 4).Value = 20000000

        .Cells(9, 1).Value = "변동 판관비율 (%)"
        .Cells(9, 2).Value = 15
        .Cells(9, 3).Value = 12
        .Cells(9, 4).Value = 10

        ' 손익계산서
        .Cells(11, 1).Value = "** 손익계산서 **"
        .Cells(11, 1).Font.Bold = True

        Dim items() As Variant
        items = Array("매출액", "매출원가", "매출총이익", "매출총이익률(%)", _
                     "판매관리비", " - 고정비", " - 변동비", _
                     "영업이익", "영업이익률(%)")

        Dim row As Integer
        row = 12
        Dim i As Integer
        For i = 0 To UBound(items)
            .Cells(row + i, 1).Value = items(i)
        Next i

        ' 수식 입력
        Dim col As Integer
        For col = 2 To 4 ' 최악, 기본, 최선
            ' 매출액
            .Cells(12, col).Formula = "=B6"

            ' 매출원가
            .Cells(13, col).Formula = "=B12*B7/100"

            ' 매출총이익
            .Cells(14, col).Formula = "=B12-B13"

            ' 매출총이익률
            .Cells(15, col).Formula = "=B14/B12*100"

            ' 고정비
            .Cells(17, col).Formula = "=B8"

            ' 변동비
            .Cells(18, col).Formula = "=B12*B9/100"

            ' 판관비 합계
            .Cells(16, col).Formula = "=B17+B18"

            ' 영업이익
            .Cells(19, col).Formula = "=B14-B16"

            ' 영업이익률
            .Cells(20, col).Formula = "=B19/B12*100"

            ' 열 참조 업데이트
            .Cells(12, col).Formula = Replace(.Cells(12, col).Formula, "B", Chr(64 + col))
            .Cells(13, col).Formula = Replace(.Cells(13, col).Formula, "B", Chr(64 + col))
            .Cells(14, col).Formula = Replace(.Cells(14, col).Formula, "B", Chr(64 + col))
            .Cells(15, col).Formula = Replace(.Cells(15, col).Formula, "B", Chr(64 + col))
            .Cells(16, col).Formula = Replace(.Cells(16, col).Formula, "B", Chr(64 + col))
            .Cells(17, col).Formula = Replace(.Cells(17, col).Formula, "B", Chr(64 + col))
            .Cells(18, col).Formula = Replace(.Cells(18, col).Formula, "B", Chr(64 + col))
            .Cells(19, col).Formula = Replace(.Cells(19, col).Formula, "B", Chr(64 + col))
            .Cells(20, col).Formula = Replace(.Cells(20, col).Formula, "B", Chr(64 + col))
        Next col

        ' 서식 적용
        .Range("B6:D20").NumberFormat = "#,##0"
        .Range("B15:D15, B20:D20").NumberFormat = "0.0"

        ' 조건부 서식 (영업이익)
        With .Range("B19:D19")
            .FormatConditions.Delete
            .FormatConditions.Add Type:=xlCellValue, Operator:=xlGreater, Formula1:="0"
            .FormatConditions(1).Interior.Color = RGB(198, 224, 180)

            .FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, Formula1:="0"
            .FormatConditions(2).Interior.Color = RGB(255, 199, 206)
        End With

        .Columns("A:D").AutoFit

        ' 차트 생성
        Call 시나리오차트생성(simWs)
    End With

    MsgBox "손익 시뮬레이션이 생성되었습니다.", vbInformation
End Sub

Sub 시나리오차트생성(ws As Worksheet)
    Dim chartObj As ChartObject

    Set chartObj = ws.ChartObjects.Add( _
        Left:=ws.Range("F3").Left, _
        Top:=ws.Range("F3").Top, _
        Width:=400, _
        Height:=300)

    With chartObj.Chart
        .ChartType = xlColumnClustered

        ' 매출액 시리즈
        .SeriesCollection.NewSeries
        With .SeriesCollection(1)
            .Name = "매출액"
            .XValues = ws.Range("B3:D3")
            .Values = ws.Range("B12:D12")
            .Format.Fill.ForeColor.RGB = RGB(79, 129, 189)
        End With

        ' 영업이익 시리즈
        .SeriesCollection.NewSeries
        With .SeriesCollection(2)
            .Name = "영업이익"
            .XValues = ws.Range("B3:D3")
            .Values = ws.Range("B19:D19")
            .Format.Fill.ForeColor.RGB = RGB(155, 187, 89)
        End With

        .HasTitle = True
        .ChartTitle.Text = "시나리오별 손익 비교"
        .HasLegend = True
        .Legend.Position = xlLegendPositionBottom
    End With
End Sub

3. 민감도 분석 (What-If Analysis)

AI 프롬프트:

"매출액과 원가율을 변화시키면서
영업이익이 어떻게 변하는지 테이블로 보여주세요."

AI 생성 VBA:

Sub 민감도분석()
    Dim ws As Worksheet

    ' 분석 시트 생성
    On Error Resume Next
    Set ws = Sheets("민감도분석")
    If ws Is Nothing Then
        Set ws = Sheets.Add
        ws.Name = "민감도분석"
    Else
        ws.Cells.Clear
    End If
    On Error GoTo 0

    With ws
        .Cells(1, 1).Value = "민감도 분석: 영업이익"
        .Cells(1, 1).Font.Size = 14
        .Cells(1, 1).Font.Bold = True

        ' 데이터 테이블 설정
        .Cells(3, 1).Value = "매출액 \ 원가율"
        .Cells(3, 1).Font.Bold = True

        ' 매출액 시나리오 (행)
        Dim sales() As Variant
        sales = Array(80000000, 90000000, 100000000, 110000000, 120000000)

        Dim i As Integer
        For i = 0 To UBound(sales)
            .Cells(4 + i, 1).Value = sales(i)
            .Cells(4 + i, 1).NumberFormat = "#,##0"
        Next i

        ' 원가율 시나리오 (열)
        Dim costRates() As Variant
        costRates = Array(50, 55, 60, 65, 70)

        Dim j As Integer
        For j = 0 To UBound(costRates)
            .Cells(3, 2 + j).Value = costRates(j) & "%"
        Next j

        ' 고정비 설정
        Dim fixedCost As Long
        fixedCost = 20000000

        ' 영업이익 계산
        For i = 0 To UBound(sales)
            For j = 0 To UBound(costRates)
                Dim revenue As Double
                Dim cogs As Double
                Dim grossProfit As Double
                Dim operatingProfit As Double

                revenue = sales(i)
                cogs = revenue * costRates(j) / 100
                grossProfit = revenue - cogs
                operatingProfit = grossProfit - fixedCost

                .Cells(4 + i, 2 + j).Value = operatingProfit
                .Cells(4 + i, 2 + j).NumberFormat = "#,##0"

                ' 조건부 서식
                If operatingProfit > 20000000 Then
                    .Cells(4 + i, 2 + j).Interior.Color = RGB(146, 208, 80)
                ElseIf operatingProfit > 10000000 Then
                    .Cells(4 + i, 2 + j).Interior.Color = RGB(255, 242, 204)
                ElseIf operatingProfit > 0 Then
                    .Cells(4 + i, 2 + j).Interior.Color = RGB(252, 228, 214)
                Else
                    .Cells(4 + i, 2 + j).Interior.Color = RGB(255, 199, 206)
                End If
            Next j
        Next i

        ' 테두리
        .Range("A3:F8").Borders.LineStyle = xlContinuous

        ' 범례
        .Cells(10, 1).Value = "범례:"
        .Cells(11, 1).Value = "우수"
        .Cells(11, 1).Interior.Color = RGB(146, 208, 80)
        .Cells(12, 1).Value = "양호"
        .Cells(12, 1).Interior.Color = RGB(255, 242, 204)
        .Cells(13, 1).Value = "보통"
        .Cells(13, 1).Interior.Color = RGB(252, 228, 214)
        .Cells(14, 1).Value = "주의"
        .Cells(14, 1).Interior.Color = RGB(255, 199, 206)

        .Cells(11, 2).Value = "> 2,000만원"
        .Cells(12, 2).Value = "> 1,000만원"
        .Cells(13, 2).Value = "> 0원"
        .Cells(14, 2).Value = "< 0원 (적자)"

        .Columns("A:F").AutoFit

        ' 3D 차트 생성
        Call 민감도차트생성(ws)
    End With

    MsgBox "민감도 분석이 완료되었습니다.", vbInformation
End Sub

Sub 민감도차트생성(ws As Worksheet)
    Dim chartObj As ChartObject

    Set chartObj = ws.ChartObjects.Add( _
        Left:=ws.Range("H3").Left, _
        Top:=ws.Range("H3").Top, _
        Width:=400, _
        Height:=300)

    With chartObj.Chart
        .ChartType = xlSurface
        .SetSourceData Source:=ws.Range("A3:F8")
        .HasTitle = True
        .ChartTitle.Text = "민감도 분석 (3D)"
    End With
End Sub

4. 손익분기점 분석

AI 프롬프트:

"고정비, 변동비, 판매가격을 입력하면
손익분기점 수량과 매출액을 계산해주세요."

AI 생성 수식 및 VBA:

// 손익분기점 수량 (BEP_Q)
=고정비/(판매단가-단위당변동비)

// 손익분기점 매출액 (BEP_S)
=BEP_Q*판매단가

// 또는 직접 계산
=고정비/(1-변동비율)

// 목표이익 달성 수량
=(고정비+목표이익)/(판매단가-단위당변동비)

VBA 자동 계산기:

Sub 손익분기점계산기()
    Dim fixedCost As Double
    Dim price As Double
    Dim variableCost As Double
    Dim targetProfit As Double

    ' 사용자 입력
    fixedCost = Application.InputBox("월 고정비를 입력하세요 (원):", Type:=1)
    price = Application.InputBox("제품 판매단가를 입력하세요 (원):", Type:=1)
    variableCost = Application.InputBox("제품당 변동비를 입력하세요 (원):", Type:=1)
    targetProfit = Application.InputBox("목표 영업이익을 입력하세요 (원, 0이면 Skip):", Type:=1)

    ' 계산
    Dim contributionMargin As Double
    Dim bepQuantity As Double
    Dim bepSales As Double
    Dim targetQuantity As Double

    contributionMargin = price - variableCost

    If contributionMargin <= 0 Then
        MsgBox "오류: 판매단가가 변동비보다 높아야 합니다.", vbCritical
        Exit Sub
    End If

    bepQuantity = fixedCost / contributionMargin
    bepSales = bepQuantity * price

    If targetProfit > 0 Then
        targetQuantity = (fixedCost + targetProfit) / contributionMargin
    End If

    ' 결과 시트
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = Sheets("손익분기점")
    If ws Is Nothing Then
        Set ws = Sheets.Add
        ws.Name = "손익분기점"
    Else
        ws.Cells.Clear
    End If
    On Error GoTo 0

    With ws
        .Cells(1, 1).Value = "손익분기점 분석 결과"
        .Cells(1, 1).Font.Size = 14
        .Cells(1, 1).Font.Bold = True

        ' 입력값
        .Cells(3, 1).Value = "** 입력값 **"
        .Cells(3, 1).Font.Bold = True
        .Cells(4, 1).Value = "고정비:"
        .Cells(4, 2).Value = fixedCost
        .Cells(5, 1).Value = "판매단가:"
        .Cells(5, 2).Value = price
        .Cells(6, 1).Value = "단위당 변동비:"
        .Cells(6, 2).Value = variableCost
        .Cells(7, 1).Value = "공헌이익:"
        .Cells(7, 2).Value = contributionMargin

        ' 결과
        .Cells(9, 1).Value = "** 분석 결과 **"
        .Cells(9, 1).Font.Bold = True
        .Cells(10, 1).Value = "손익분기점 수량:"
        .Cells(10, 2).Value = Format(bepQuantity, "#,##0.0")
        .Cells(11, 1).Value = "손익분기점 매출:"
        .Cells(11, 2).Value = Format(bepSales, "#,##0")

        If targetProfit > 0 Then
            .Cells(12, 1).Value = "목표이익 달성 수량:"
            .Cells(12, 2).Value = Format(targetQuantity, "#,##0.0")
            .Cells(13, 1).Value = "목표이익 달성 매출:"
            .Cells(13, 2).Value = Format(targetQuantity * price, "#,##0")
        End If

        ' 시뮬레이션 테이블
        .Cells(15, 1).Value = "** 판매 시뮬레이션 **"
        .Cells(15, 1).Font.Bold = True
        .Cells(16, 1).Value = "수량"
        .Cells(16, 2).Value = "매출액"
        .Cells(16, 3).Value = "변동비"
        .Cells(16, 4).Value = "공헌이익"
        .Cells(16, 5).Value = "영업이익"

        Dim row As Integer
        row = 17
        Dim qty As Double

        For qty = bepQuantity * 0.5 To bepQuantity * 1.5 Step bepQuantity * 0.1
            .Cells(row, 1).Value = qty
            .Cells(row, 2).Value = qty * price
            .Cells(row, 3).Value = qty * variableCost
            .Cells(row, 4).Value = qty * contributionMargin
            .Cells(row, 5).Value = qty * contributionMargin - fixedCost

            ' 색상
            If .Cells(row, 5).Value >= 0 Then
                .Cells(row, 5).Interior.Color = RGB(198, 224, 180)
            Else
                .Cells(row, 5).Interior.Color = RGB(255, 199, 206)
            End If

            row = row + 1
        Next qty

        .Range("B4:B13").NumberFormat = "#,##0"
        .Range("A17:E" & row - 1).NumberFormat = "#,##0"
        .Columns("A:E").AutoFit

        ' 차트
        Call BEP차트생성(ws, row - 1, fixedCost, price, variableCost)
    End With

    MsgBox "손익분기점 분석이 완료되었습니다." & vbCrLf & _
           "BEP 수량: " & Format(bepQuantity, "#,##0") & vbCrLf & _
           "BEP 매출: " & Format(bepSales, "#,##0") & "원", _
           vbInformation
End Sub

Sub BEP차트생성(ws As Worksheet, lastRow As Long, _
                 fixedCost As Double, price As Double, variableCost As Double)
    Dim chartObj As ChartObject

    Set chartObj = ws.ChartObjects.Add( _
        Left:=ws.Range("G3").Left, _
        Top:=ws.Range("G3").Top, _
        Width:=450, _
        Height:=350)

    With chartObj.Chart
        .ChartType = xlXYScatterLines

        ' 매출선
        .SeriesCollection.NewSeries
        With .SeriesCollection(1)
            .Name = "매출"
            .XValues = ws.Range("A17:A" & lastRow)
            .Values = ws.Range("B17:B" & lastRow)
            .Format.Line.ForeColor.RGB = RGB(79, 129, 189)
            .Format.Line.Weight = 2
        End With

        ' 총비용선
        .SeriesCollection.NewSeries
        With .SeriesCollection(2)
            .Name = "총비용"
            .XValues = ws.Range("A17:A" & lastRow)

            ' 총비용 = 고정비 + 변동비
            Dim totalCostRange As String
            totalCostRange = "="&ws.Name&"!$C$17:$C$" & lastRow
            Dim i As Long
            For i = 17 To lastRow
                ws.Range("F" & i).Formula = "=" & fixedCost & "+C" & i
            Next i
            .Values = ws.Range("F17:F" & lastRow)

            .Format.Line.ForeColor.RGB = RGB(192, 80, 77)
            .Format.Line.Weight = 2
        End With

        ' 고정비선
        .SeriesCollection.NewSeries
        With .SeriesCollection(3)
            .Name = "고정비"
            Dim fixedArray() As Double
            ReDim fixedArray(1 To lastRow - 16)
            For i = 1 To lastRow - 16
                fixedArray(i) = fixedCost
            Next i

            .XValues = ws.Range("A17:A" & lastRow)
            .Values = fixedArray
            .Format.Line.ForeColor.RGB = RGB(128, 128, 128)
            .Format.Line.DashStyle = msoLineDash
        End With

        .HasTitle = True
        .ChartTitle.Text = "손익분기점 차트 (BEP)"
        .Axes(xlCategory).HasTitle = True
        .Axes(xlCategory).AxisTitle.Text = "판매수량"
        .Axes(xlValue).HasTitle = True
        .Axes(xlValue).AxisTitle.Text = "금액 (원)"
        .HasLegend = True
        .Legend.Position = xlLegendPositionTop
    End With
End Sub

5. 몬테카를로 시뮬레이션

AI 프롬프트:

"불확실한 미래를 고려해서
1,000번의 무작위 시나리오를 생성하고
각 결과의 확률 분포를 보여주세요."

AI 생성 VBA:

Sub 몬테카를로시뮬레이션()
    Dim ws As Worksheet
    Dim iterations As Long
    Dim i As Long

    iterations = 1000

    ' 시뮬레이션 시트
    On Error Resume Next
    Set ws = Sheets("몬테카를로")
    If ws Is Nothing Then
        Set ws = Sheets.Add
        ws.Name = "몬테카를로"
    Else
        ws.Cells.Clear
    End If
    On Error GoTo 0

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    With ws
        .Cells(1, 1).Value = "몬테카를로 시뮬레이션"
        .Cells(1, 1).Font.Size = 14
        .Cells(1, 1).Font.Bold = True

        ' 헤더
        .Cells(3, 1).Value = "시행"
        .Cells(3, 2).Value = "매출액"
        .Cells(3, 3).Value = "원가율(%)"
        .Cells(3, 4).Value = "영업이익"

        ' 시뮬레이션 실행
        Dim salesMean As Double, salesStdDev As Double
        Dim costRateMean As Double, costRateStdDev As Double
        Dim fixedCost As Double

        ' 가정 설정
        salesMean = 100000000      ' 평균 매출
        salesStdDev = 20000000     ' 표준편차
        costRateMean = 60          ' 평균 원가율
        costRateStdDev = 5         ' 표준편차
        fixedCost = 20000000       ' 고정비

        For i = 1 To iterations
            ' 정규분포 난수 생성
            Dim sales As Double, costRate As Double
            Dim operatingProfit As Double

            sales = WorksheetFunction.NormInv(Rnd(), salesMean, salesStdDev)
            costRate = WorksheetFunction.NormInv(Rnd(), costRateMean, costRateStdDev)

            ' 음수 방지
            If sales < 0 Then sales = 0
            If costRate < 0 Then costRate = 0
            If costRate > 100 Then costRate = 100

            operatingProfit = sales * (1 - costRate / 100) - fixedCost

            ' 결과 기록
            .Cells(3 + i, 1).Value = i
            .Cells(3 + i, 2).Value = sales
            .Cells(3 + i, 3).Value = costRate
            .Cells(3 + i, 4).Value = operatingProfit

            If i Mod 100 = 0 Then
                Application.StatusBar = "시뮬레이션 진행 중... " & _
                    Format(i / iterations, "0%")
            End If
        Next i

        ' 통계 요약
        .Cells(3, 6).Value = "통계 요약"
        .Cells(3, 6).Font.Bold = True

        .Cells(4, 6).Value = "평균 영업이익:"
        .Cells(4, 7).Value = Application.WorksheetFunction.Average( _
            .Range("D4:D" & 3 + iterations))

        .Cells(5, 6).Value = "표준편차:"
        .Cells(5, 7).Value = Application.WorksheetFunction.StDev( _
            .Range("D4:D" & 3 + iterations))

        .Cells(6, 6).Value = "최대값:"
        .Cells(6, 7).Value = Application.WorksheetFunction.Max( _
            .Range("D4:D" & 3 + iterations))

        .Cells(7, 6).Value = "최소값:"
        .Cells(7, 7).Value = Application.WorksheetFunction.Min( _
            .Range("D4:D" & 3 + iterations))

        .Cells(8, 6).Value = "중앙값:"
        .Cells(8, 7).Value = Application.WorksheetFunction.Median( _
            .Range("D4:D" & 3 + iterations))

        ' 확률 계산
        Dim profitCount As Long
        profitCount = Application.WorksheetFunction.CountIf( _
            .Range("D4:D" & 3 + iterations), ">0")

        .Cells(10, 6).Value = "이익 확률:"
        .Cells(10, 7).Value = Format(profitCount / iterations, "0.0%")

        .Range("G4:G10").NumberFormat = "#,##0"

        ' 히스토그램 데이터 생성
        Call 히스토그램생성(ws, 3 + iterations)
    End With

    Application.StatusBar = False
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True

    MsgBox "몬테카를로 시뮬레이션이 완료되었습니다.", vbInformation
End Sub

Sub 히스토그램생성(ws As Worksheet, lastRow As Long)
    ' 히스토그램용 구간 설정
    Dim minValue As Double, maxValue As Double
    Dim binWidth As Double
    Dim binCount As Integer
    Dim i As Long

    minValue = Application.WorksheetFunction.Min(ws.Range("D4:D" & lastRow))
    maxValue = Application.WorksheetFunction.Max(ws.Range("D4:D" & lastRow))
    binCount = 20
    binWidth = (maxValue - minValue) / binCount

    ' 구간 생성
    ws.Cells(3, 9).Value = "구간"
    ws.Cells(3, 10).Value = "빈도"

    For i = 0 To binCount
        ws.Cells(4 + i, 9).Value = minValue + i * binWidth
    Next i

    ' 빈도 계산 (FREQUENCY 배열 함수)
    ws.Range("J4:J" & 4 + binCount).FormulaArray = _
        "=FREQUENCY(D4:D" & lastRow & ",I4:I" & 4 + binCount & ")"

    ' 차트 생성
    Dim chartObj As ChartObject
    Set chartObj = ws.ChartObjects.Add( _
        Left:=ws.Range("L3").Left, _
        Top:=ws.Range("L3").Top, _
        Width:=450, _
        Height:=300)

    With chartObj.Chart
        .ChartType = xlColumnClustered
        .SetSourceData Source:=ws.Range("I3:J" & 4 + binCount)
        .HasTitle = True
        .ChartTitle.Text = "영업이익 분포 (히스토그램)"
        .Axes(xlCategory).HasTitle = True
        .Axes(xlCategory).AxisTitle.Text = "영업이익 (원)"
        .Axes(xlValue).HasTitle = True
        .Axes(xlValue).AxisTitle.Text = "빈도"
        .HasLegend = False
    End With
End Sub

마무리

AI로 재무 예측 모델 구축:

  • ✅ 시계열 데이터 기반 매출 예측
  • ✅ 다양한 시나리오 손익 시뮬레이션
  • ✅ 민감도 분석 및 손익분기점 계산
  • ✅ 몬테카를로 방식의 확률적 예측

다음 글에서는 AI와 엑셀을 직접 연동하는 플러그인 활용법을 알아봅니다.