vb6parse 1.0.0

vb6parse is a library for parsing and analyzing VB6 code, from projects, to controls, to modules, and forms.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="VB6Parse Library Reference - nper - Financial">
    <title>nper - Financial - VB6Parse Library Reference</title>
    <link rel="stylesheet" href="../../../assets/css/style.css">
    <link rel="stylesheet" href="../../../assets/css/docs-style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
    <script src="../../../assets/js/theme-switcher.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/vbnet.min.js"></script>
    <script>hljs.highlightAll();</script>
</head>
<body>
    <header class="docs-header">
        <div class="container">
            <h1><a href="../../../index.html">VB6Parse</a> / <a href="../../../library/index.html">Library</a> / <a href="../../../library/functions/financial/index.html">Financial</a> / nper</h1>
            <p class="tagline">VB6 Library Reference</p>
        </div>
    </header>

    <nav class="docs-nav">
        <div class="container">
            <a href="../../../index.html">Home</a>
            <a href="../../../library/index.html">Library Reference</a>
            <a href="../../../documentation.html">Documentation</a>
            <a href="https://docs.rs/vb6parse" target="_blank">API Docs</a>
            <a href="https://github.com/scriptandcompile/vb6parse" target="_blank">GitHub</a>
            <button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
                <span class="theme-icon">🌙</span>
            </button>
        </div>
    </nav>

    <main class="container">
        
        <article class="library-item">
            <h1 id="nper-function">NPer Function</h1>
<p>Returns a Double specifying the number of periods for an annuity based on periodic, fixed payments and a fixed interest rate.</p>
<h2 id="syntax">Syntax</h2>
<pre><code class="language-vbnet">NPer(rate, pmt, pv, [fv], [type])</code></pre>
<h2 id="parameters">Parameters</h2>
<ul>
<li><strong>rate</strong> (Required) - Double specifying interest rate per period. For example, if you get a car loan at an annual percentage rate (APR) of 10 percent and make monthly payments, the rate per period is 0.1/12, or 0.0083.</li>
<li><strong>pmt</strong> (Required) - Double specifying payment to be made each period. Payments usually contain principal and interest that doesn't change over the life of the annuity.</li>
<li><strong>pv</strong> (Required) - Double specifying present value, or value today, of a series of future payments or receipts. For example, when you borrow money to buy a car, the loan amount is the present value to the lender of the monthly car payments you will make.</li>
<li><strong>fv</strong> (Optional) - Variant specifying future value or cash balance you want after you've made the final payment. For example, the future value of a loan is $0 because that's its value after the final payment. However, if you want to save $50,000 over 18 years for your child's education, then $50,000 is the future value. If omitted, 0 is assumed.</li>
<li><strong>type</strong> (Optional) - Variant specifying when payments are due. Use 0 if payments are due at the end of the payment period, or use 1 if payments are due at the beginning of the period. If omitted, 0 is assumed.</li>
</ul>
<h2 id="return-value">Return Value</h2>
<p>Returns a <strong>Double</strong> specifying the number of payment periods in an annuity.</p>
<h2 id="remarks">Remarks</h2>
<p>The <code>NPer</code> function calculates how many periods (usually months or years) it will take to pay off a loan or reach a savings goal, given a fixed payment amount and interest rate.</p>
<h3 id="key-characteristics">Key Characteristics:</h3>
<ul>
<li>Returns number of periods (can be fractional)</li>
<li>Assumes constant payment amounts</li>
<li>Assumes constant interest rate</li>
<li>For loans, pv is positive (amount borrowed), pmt is negative (payment out)</li>
<li>For investments, pv is negative (deposit), fv is positive (goal)</li>
<li>Type parameter: 0 = end of period (default), 1 = beginning of period</li>
<li>Rate must be expressed per period (annual rate / periods per year)</li>
<li>Commonly used with PMT, PV, FV, and Rate functions</li>
</ul>
<h3 id="common-use-cases">Common Use Cases:</h3>
<ul>
<li>Calculate loan payoff time</li>
<li>Determine how long to reach savings goal</li>
<li>Plan retirement savings duration</li>
<li>Calculate time to pay off credit card debt</li>
<li>Determine mortgage term needed</li>
<li>Investment planning timelines</li>
<li>Debt consolidation analysis</li>
<li>Education savings planning</li>
</ul>
<h2 id="typical-uses">Typical Uses</h2>
<ol>
<li><strong>Loan Payoff Time</strong> - Calculate how many months to pay off a loan</li>
<li><strong>Savings Goal Timeline</strong> - Determine time to reach a savings target</li>
<li><strong>Mortgage Planning</strong> - Calculate term needed for specific payments</li>
<li><strong>Credit Card Payoff</strong> - Estimate months to pay off credit card balance</li>
<li><strong>Investment Duration</strong> - Calculate time to reach investment goal</li>
<li><strong>Retirement Planning</strong> - Determine years needed to save for retirement</li>
<li><strong>Debt Analysis</strong> - Compare payoff timelines for different payment amounts</li>
<li><strong>What-If Scenarios</strong> - Model different payment scenarios</li>
</ol>
<h2 id="basic-examples">Basic Examples</h2>
<pre><code class="language-vbnet">&#x27; Example 1: How many months to pay off a $10,000 loan at 8% APR with $200/month payments?
Dim months As Double
months = NPer(0.08 / 12, -200, 10000)
&#x27; Result: approximately 62.6 months (5.2 years)</code></pre>
<pre><code class="language-vbnet">&#x27; Example 2: How many years to save $50,000 with $300/month at 6% annual return?
Dim years As Double
years = NPer(0.06 / 12, -300, 0, 50000) / 12
&#x27; Result: approximately 10.8 years</code></pre>
<pre><code class="language-vbnet">&#x27; Example 3: Time to pay off credit card with minimum payments
Dim balance As Double
Dim monthlyPayment As Double
Dim apr As Double
Dim payoffMonths As Double
balance = 5000
monthlyPayment = -100
apr = 0.1899 &#x27; 18.99% APR
payoffMonths = NPer(apr / 12, monthlyPayment, balance)
&#x27; Result: approximately 79 months</code></pre>
<pre><code class="language-vbnet">&#x27; Example 4: Retirement savings timeline
Dim monthlyDeposit As Double
Dim retirementGoal As Double
Dim annualReturn As Double
Dim yearsNeeded As Double
monthlyDeposit = -500
retirementGoal = 1000000
annualReturn = 0.07
yearsNeeded = NPer(annualReturn / 12, monthlyDeposit, 0, retirementGoal) / 12
&#x27; Result: approximately 38.3 years</code></pre>
<h2 id="common-patterns">Common Patterns</h2>
<pre><code class="language-vbnet">&#x27; Pattern 1: Loan payoff calculator
Function CalculatePayoffMonths(loanAmount As Double, _
                               monthlyPayment As Double, _
                               apr As Double) As Double
    Dim monthlyRate As Double
    monthlyRate = apr / 12
    CalculatePayoffMonths = NPer(monthlyRate, -monthlyPayment, loanAmount)
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 2: Savings goal timeline
Function YearsToReachGoal(monthlyDeposit As Double, _
                         currentBalance As Double, _
                         targetAmount As Double, _
                         annualReturn As Double) As Double
    Dim months As Double
    months = NPer(annualReturn / 12, -monthlyDeposit, -currentBalance, targetAmount)
    YearsToReachGoal = months / 12
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 3: Compare payment scenarios
Sub ComparePaymentScenarios(balance As Double, apr As Double)
    Dim payment As Double
    Dim months As Double
    Dim i As Integer
    For i = 1 To 5
        payment = balance * 0.02 * i &#x27; 2%, 4%, 6%, 8%, 10% of balance
        months = NPer(apr / 12, -payment, balance)
        Debug.Print &quot;Payment: $&quot; &amp; Format(payment, &quot;0.00&quot;) &amp; _
                    &quot; - Months: &quot; &amp; Format(months, &quot;0.0&quot;)
    Next i
End Sub</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 4: Interest rate impact on duration
Function CalculateRateImpact(loanAmount As Double, _
                            monthlyPayment As Double) As String
    Dim result As String
    Dim rate As Double
    Dim months As Double
    result = &quot;Interest Rate Impact:&quot; &amp; vbCrLf
    For rate = 0.03 To 0.15 Step 0.02
        months = NPer(rate / 12, -monthlyPayment, loanAmount)
        result = result &amp; Format(rate * 100, &quot;0.0&quot;) &amp; &quot;% APR: &quot; &amp; _
                 Format(months, &quot;0.0&quot;) &amp; &quot; months&quot; &amp; vbCrLf
    Next rate
    CalculateRateImpact = result
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 5: Minimum payment warning
Function IsMinimumPaymentTooLow(balance As Double, _
                                payment As Double, _
                                apr As Double) As Boolean
    Dim months As Double
    Dim maxYears As Double
    maxYears = 10
    months = NPer(apr / 12, -payment, balance)
    IsMinimumPaymentTooLow = (months &gt; maxYears * 12)
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 6: Early payoff calculation
Function MonthsSavedByExtraPayment(balance As Double, _
                                   regularPayment As Double, _
                                   extraPayment As Double, _
                                   apr As Double) As Double
    Dim regularMonths As Double
    Dim acceleratedMonths As Double
    regularMonths = NPer(apr / 12, -regularPayment, balance)
    acceleratedMonths = NPer(apr / 12, -(regularPayment + extraPayment), balance)
    MonthsSavedByExtraPayment = regularMonths - acceleratedMonths
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 7: Formatted duration display
Function FormatPayoffTime(months As Double) As String
    Dim years As Long
    Dim remainingMonths As Long
    years = Int(months / 12)
    remainingMonths = Int(months Mod 12)
    If years &gt; 0 Then
        FormatPayoffTime = years &amp; &quot; year&quot;
        If years &gt; 1 Then FormatPayoffTime = FormatPayoffTime &amp; &quot;s&quot;
        If remainingMonths &gt; 0 Then
            FormatPayoffTime = FormatPayoffTime &amp; &quot;, &quot; &amp; remainingMonths &amp; &quot; month&quot;
            If remainingMonths &gt; 1 Then FormatPayoffTime = FormatPayoffTime &amp; &quot;s&quot;
        End If
    Else
        FormatPayoffTime = remainingMonths &amp; &quot; month&quot;
        If remainingMonths &lt;&gt; 1 Then FormatPayoffTime = FormatPayoffTime &amp; &quot;s&quot;
    End If
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 8: College savings timeline
Function CalculateCollegeSavingsTime(currentAge As Integer, _
                                     currentSavings As Double, _
                                     monthlyDeposit As Double, _
                                     collegeGoal As Double, _
                                     annualReturn As Double) As Double
    Dim months As Double
    Dim yearsUntilCollege As Integer
    months = NPer(annualReturn / 12, -monthlyDeposit, -currentSavings, collegeGoal)
    yearsUntilCollege = 18 - currentAge
    CalculateCollegeSavingsTime = months / 12
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 9: Debt consolidation comparison
Function CompareConsolidation(debt1 As Double, rate1 As Double, pmt1 As Double, _
                             debt2 As Double, rate2 As Double, pmt2 As Double, _
                             consolidatedRate As Double) As String
    Dim currentMonths As Double
    Dim consolidatedMonths As Double
    Dim totalDebt As Double
    Dim totalPayment As Double
    Dim result As String
    &#x27; Calculate current payoff time
    currentMonths = Application.Max( _
        NPer(rate1 / 12, -pmt1, debt1), _
        NPer(rate2 / 12, -pmt2, debt2))
    &#x27; Calculate consolidated payoff time
    totalDebt = debt1 + debt2
    totalPayment = pmt1 + pmt2
    consolidatedMonths = NPer(consolidatedRate / 12, -totalPayment, totalDebt)
    result = &quot;Current: &quot; &amp; Format(currentMonths, &quot;0.0&quot;) &amp; &quot; months&quot; &amp; vbCrLf
    result = result &amp; &quot;Consolidated: &quot; &amp; Format(consolidatedMonths, &quot;0.0&quot;) &amp; &quot; months&quot; &amp; vbCrLf
    result = result &amp; &quot;Savings: &quot; &amp; Format(currentMonths - consolidatedMonths, &quot;0.0&quot;) &amp; &quot; months&quot;
    CompareConsolidation = result
End Function</code></pre>
<pre><code class="language-vbnet">&#x27; Pattern 10: Payment sufficiency check
Function IsPaymentSufficient(balance As Double, _
                            payment As Double, _
                            apr As Double) As Boolean
    Dim monthlyInterest As Double
    &#x27; Check if payment exceeds monthly interest
    monthlyInterest = balance * (apr / 12)
    If payment &lt;= monthlyInterest Then
        IsPaymentSufficient = False &#x27; Will never pay off
    Else
        On Error Resume Next
        Dim periods As Double
        periods = NPer(apr / 12, -payment, balance)
        IsPaymentSufficient = (Err.Number = 0)
        On Error GoTo 0
    End If
End Function</code></pre>
<h2 id="advanced-usage">Advanced Usage</h2>
<h3 id="example-1-loan-analyzer-class">Example 1: Loan Analyzer Class</h3>
<pre><code class="language-vbnet">&#x27; Class: LoanAnalyzer
&#x27; Comprehensive loan analysis with payoff scenarios
Option Explicit
Private m_principal As Double
Private m_apr As Double
Private m_monthlyPayment As Double
Public Sub Initialize(principal As Double, apr As Double, monthlyPayment As Double)
    m_principal = principal
    m_apr = apr
    m_monthlyPayment = monthlyPayment
End Sub
Public Function GetPayoffMonths() As Double
    GetPayoffMonths = NPer(m_apr / 12, -m_monthlyPayment, m_principal)
End Function
Public Function GetPayoffYears() As Double
    GetPayoffYears = GetPayoffMonths() / 12
End Function
Public Function GetTotalInterest() As Double
    Dim months As Double
    Dim totalPaid As Double
    months = GetPayoffMonths()
    totalPaid = m_monthlyPayment * months
    GetTotalInterest = totalPaid - m_principal
End Function
Public Function GetPayoffDate() As Date
    Dim months As Double
    months = GetPayoffMonths()
    GetPayoffDate = DateAdd(&quot;m&quot;, Int(months), Date)
End Function
Public Function AnalyzeExtraPayment(extraMonthly As Double) As String
    Dim baseMonths As Double
    Dim acceleratedMonths As Double
    Dim monthsSaved As Double
    Dim interestSaved As Double
    Dim result As String
    baseMonths = NPer(m_apr / 12, -m_monthlyPayment, m_principal)
    acceleratedMonths = NPer(m_apr / 12, -(m_monthlyPayment + extraMonthly), m_principal)
    monthsSaved = baseMonths - acceleratedMonths
    interestSaved = (m_monthlyPayment * baseMonths - m_principal) - _
                    ((m_monthlyPayment + extraMonthly) * acceleratedMonths - m_principal)
    result = &quot;Extra Payment Analysis:&quot; &amp; vbCrLf
    result = result &amp; &quot;Extra payment: $&quot; &amp; Format(extraMonthly, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; &quot;Time saved: &quot; &amp; Format(monthsSaved, &quot;0.0&quot;) &amp; &quot; months&quot; &amp; vbCrLf
    result = result &amp; &quot;Interest saved: $&quot; &amp; Format(interestSaved, &quot;#,##0.00&quot;)
    AnalyzeExtraPayment = result
End Function
Public Function GenerateAmortizationSummary() As String
    Dim summary As String
    Dim months As Double
    Dim totalPaid As Double
    Dim totalInterest As Double
    months = GetPayoffMonths()
    totalPaid = m_monthlyPayment * months
    totalInterest = totalPaid - m_principal
    summary = &quot;Loan Amortization Summary&quot; &amp; vbCrLf
    summary = summary &amp; String(50, &quot;-&quot;) &amp; vbCrLf
    summary = summary &amp; &quot;Principal: $&quot; &amp; Format(m_principal, &quot;#,##0.00&quot;) &amp; vbCrLf
    summary = summary &amp; &quot;APR: &quot; &amp; Format(m_apr * 100, &quot;0.00&quot;) &amp; &quot;%&quot; &amp; vbCrLf
    summary = summary &amp; &quot;Monthly Payment: $&quot; &amp; Format(m_monthlyPayment, &quot;#,##0.00&quot;) &amp; vbCrLf
    summary = summary &amp; &quot;Payoff Time: &quot; &amp; Format(months, &quot;0.0&quot;) &amp; &quot; months (&quot; &amp; _
                       Format(months / 12, &quot;0.0&quot;) &amp; &quot; years)&quot; &amp; vbCrLf
    summary = summary &amp; &quot;Total Paid: $&quot; &amp; Format(totalPaid, &quot;#,##0.00&quot;) &amp; vbCrLf
    summary = summary &amp; &quot;Total Interest: $&quot; &amp; Format(totalInterest, &quot;#,##0.00&quot;) &amp; vbCrLf
    summary = summary &amp; &quot;Payoff Date: &quot; &amp; Format(GetPayoffDate(), &quot;mmm dd, yyyy&quot;)
    GenerateAmortizationSummary = summary
End Function</code></pre>
<h3 id="example-2-retirement-planner-class">Example 2: Retirement Planner Class</h3>
<pre><code class="language-vbnet">&#x27; Class: RetirementPlanner
&#x27; Plans retirement savings timeline and scenarios
Option Explicit
Private m_currentAge As Integer
Private m_retirementAge As Integer
Private m_currentSavings As Double
Private m_monthlyContribution As Double
Private m_expectedReturn As Double
Private m_retirementGoal As Double
Public Sub Initialize(currentAge As Integer, _
                     retirementAge As Integer, _
                     currentSavings As Double, _
                     monthlyContribution As Double, _
                     expectedReturn As Double, _
                     retirementGoal As Double)
    m_currentAge = currentAge
    m_retirementAge = retirementAge
    m_currentSavings = currentSavings
    m_monthlyContribution = monthlyContribution
    m_expectedReturn = expectedReturn
    m_retirementGoal = retirementGoal
End Sub
Public Function GetYearsToGoal() As Double
    Dim months As Double
    months = NPer(m_expectedReturn / 12, -m_monthlyContribution, -m_currentSavings, m_retirementGoal)
    GetYearsToGoal = months / 12
End Function
Public Function WillReachGoal() As Boolean
    Dim yearsNeeded As Double
    Dim yearsAvailable As Integer
    yearsNeeded = GetYearsToGoal()
    yearsAvailable = m_retirementAge - m_currentAge
    WillReachGoal = (yearsNeeded &lt;= yearsAvailable)
End Function
Public Function GetRequiredMonthlyContribution() As Double
    Dim monthsAvailable As Long
    monthsAvailable = (m_retirementAge - m_currentAge) * 12
    GetRequiredMonthlyContribution = -PMT(m_expectedReturn / 12, _
                                         monthsAvailable, _
                                         -m_currentSavings, _
                                         m_retirementGoal)
End Function
Public Function GenerateScenarioAnalysis() As String
    Dim result As String
    Dim yearsNeeded As Double
    Dim yearsAvailable As Integer
    Dim shortfall As Double
    yearsNeeded = GetYearsToGoal()
    yearsAvailable = m_retirementAge - m_currentAge
    result = &quot;Retirement Scenario Analysis&quot; &amp; vbCrLf
    result = result &amp; String(50, &quot;-&quot;) &amp; vbCrLf
    result = result &amp; &quot;Current Age: &quot; &amp; m_currentAge &amp; vbCrLf
    result = result &amp; &quot;Retirement Age: &quot; &amp; m_retirementAge &amp; vbCrLf
    result = result &amp; &quot;Years Available: &quot; &amp; yearsAvailable &amp; vbCrLf
    result = result &amp; &quot;Current Savings: $&quot; &amp; Format(m_currentSavings, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; &quot;Monthly Contribution: $&quot; &amp; Format(m_monthlyContribution, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; &quot;Expected Return: &quot; &amp; Format(m_expectedReturn * 100, &quot;0.00&quot;) &amp; &quot;%&quot; &amp; vbCrLf
    result = result &amp; &quot;Retirement Goal: $&quot; &amp; Format(m_retirementGoal, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; vbCrLf
    result = result &amp; &quot;Years Needed: &quot; &amp; Format(yearsNeeded, &quot;0.0&quot;) &amp; vbCrLf
    If WillReachGoal() Then
        result = result &amp; &quot;Status: On track! &quot; &amp; Format(yearsAvailable - yearsNeeded, &quot;0.0&quot;) &amp; _
                 &quot; years ahead of schedule.&quot;
    Else
        shortfall = yearsNeeded - yearsAvailable
        result = result &amp; &quot;Status: Behind schedule by &quot; &amp; Format(shortfall, &quot;0.0&quot;) &amp; &quot; years.&quot; &amp; vbCrLf
        result = result &amp; &quot;Required Monthly: $&quot; &amp; _
                 Format(GetRequiredMonthlyContribution(), &quot;#,##0.00&quot;)
    End If
    GenerateScenarioAnalysis = result
End Function</code></pre>
<h3 id="example-3-debt-payoff-optimizer-module">Example 3: Debt Payoff Optimizer Module</h3>
<pre><code class="language-vbnet">&#x27; Module: DebtPayoffOptimizer
&#x27; Optimizes debt payoff strategies
Option Explicit
Private Type DebtInfo
    name As String
    balance As Double
    apr As Double
    minimumPayment As Double
    payoffMonths As Double
End Type
Public Function AnalyzeSnowballMethod(debts() As DebtInfo, _
                                      extraPayment As Double) As String
    Dim i As Integer
    Dim result As String
    Dim totalMonths As Double
    &#x27; Sort debts by balance (smallest first)
    SortDebtsByBalance debts
    result = &quot;Debt Snowball Method Analysis&quot; &amp; vbCrLf
    result = result &amp; String(60, &quot;-&quot;) &amp; vbCrLf
    totalMonths = 0
    For i = LBound(debts) To UBound(debts)
        If i = LBound(debts) Then
            debts(i).payoffMonths = NPer(debts(i).apr / 12, _
                                         -(debts(i).minimumPayment + extraPayment), _
                                         debts(i).balance)
        Else
            &#x27; Add freed-up payment from previous debt
            Dim availablePayment As Double
            availablePayment = debts(i).minimumPayment + extraPayment
            For j = LBound(debts) To i - 1
                availablePayment = availablePayment + debts(j).minimumPayment
            Next j
            debts(i).payoffMonths = totalMonths + _
                NPer(debts(i).apr / 12, -availablePayment, debts(i).balance)
        End If
        totalMonths = debts(i).payoffMonths
        result = result &amp; debts(i).name &amp; &quot;: &quot; &amp; _
                 Format(debts(i).payoffMonths, &quot;0.0&quot;) &amp; &quot; months&quot; &amp; vbCrLf
    Next i
    result = result &amp; vbCrLf &amp; &quot;Total Time: &quot; &amp; Format(totalMonths, &quot;0.0&quot;) &amp; &quot; months&quot;
    AnalyzeSnowballMethod = result
End Function
Public Function AnalyzeAvalancheMethod(debts() As DebtInfo, _
                                       extraPayment As Double) As String
    &#x27; Sort debts by APR (highest first)
    SortDebtsByRate debts
    &#x27; Use same logic as snowball but with different sort
    AnalyzeAvalancheMethod = AnalyzeSnowballMethod(debts, extraPayment)
End Function
Private Sub SortDebtsByBalance(debts() As DebtInfo)
    &#x27; Simple bubble sort
    Dim i As Integer, j As Integer
    Dim temp As DebtInfo
    For i = LBound(debts) To UBound(debts) - 1
        For j = i + 1 To UBound(debts)
            If debts(i).balance &gt; debts(j).balance Then
                temp = debts(i)
                debts(i) = debts(j)
                debts(j) = temp
            End If
        Next j
    Next i
End Sub
Private Sub SortDebtsByRate(debts() As DebtInfo)
    &#x27; Simple bubble sort
    Dim i As Integer, j As Integer
    Dim temp As DebtInfo
    For i = LBound(debts) To UBound(debts) - 1
        For j = i + 1 To UBound(debts)
            If debts(i).apr &lt; debts(j).apr Then
                temp = debts(i)
                debts(i) = debts(j)
                debts(j) = temp
            End If
        Next j
    Next i
End Sub</code></pre>
<h3 id="example-4-financial-goal-tracker">Example 4: Financial Goal Tracker</h3>
<pre><code class="language-vbnet">&#x27; Class: FinancialGoalTracker
&#x27; Tracks progress toward multiple financial goals
Option Explicit
Private Type Goal
    name As String
    targetAmount As Double
    currentAmount As Double
    monthlyDeposit As Double
    expectedReturn As Double
    targetDate As Date
    isOnTrack As Boolean
    monthsNeeded As Double
End Type
Private m_goals As Collection
Private Sub Class_Initialize()
    Set m_goals = New Collection
End Sub
Public Sub AddGoal(name As String, _
                  targetAmount As Double, _
                  currentAmount As Double, _
                  monthlyDeposit As Double, _
                  expectedReturn As Double, _
                  targetDate As Date)
    Dim goal As Goal
    goal.name = name
    goal.targetAmount = targetAmount
    goal.currentAmount = currentAmount
    goal.monthlyDeposit = monthlyDeposit
    goal.expectedReturn = expectedReturn
    goal.targetDate = targetDate
    &#x27; Calculate if on track
    goal.monthsNeeded = NPer(expectedReturn / 12, -monthlyDeposit, -currentAmount, targetAmount)
    Dim monthsAvailable As Long
    monthsAvailable = DateDiff(&quot;m&quot;, Date, targetDate)
    goal.isOnTrack = (goal.monthsNeeded &lt;= monthsAvailable)
    m_goals.Add goal, name
End Sub
Public Function GetGoalStatus(goalName As String) As String
    Dim goal As Goal
    Dim monthsAvailable As Long
    Dim result As String
    On Error Resume Next
    goal = m_goals(goalName)
    If Err.Number &lt;&gt; 0 Then
        GetGoalStatus = &quot;Goal not found&quot;
        Exit Function
    End If
    On Error GoTo 0
    monthsAvailable = DateDiff(&quot;m&quot;, Date, goal.targetDate)
    result = &quot;Goal: &quot; &amp; goal.name &amp; vbCrLf
    result = result &amp; &quot;Target: $&quot; &amp; Format(goal.targetAmount, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; &quot;Current: $&quot; &amp; Format(goal.currentAmount, &quot;#,##0.00&quot;) &amp; vbCrLf
    result = result &amp; &quot;Months Available: &quot; &amp; monthsAvailable &amp; vbCrLf
    result = result &amp; &quot;Months Needed: &quot; &amp; Format(goal.monthsNeeded, &quot;0.0&quot;) &amp; vbCrLf
    If goal.isOnTrack Then
        result = result &amp; &quot;Status: On track!&quot;
    Else
        Dim requiredMonthly As Double
        requiredMonthly = -PMT(goal.expectedReturn / 12, monthsAvailable, _
                              -goal.currentAmount, goal.targetAmount)
        result = result &amp; &quot;Status: Behind - Need $&quot; &amp; _
                 Format(requiredMonthly, &quot;#,##0.00&quot;) &amp; &quot;/month&quot;
    End If
    GetGoalStatus = result
End Function
Public Function GenerateAllGoalsReport() As String
    Dim report As String
    Dim goal As Goal
    Dim i As Long
    report = &quot;Financial Goals Progress Report&quot; &amp; vbCrLf
    report = report &amp; String(60, &quot;=&quot;) &amp; vbCrLf &amp; vbCrLf
    For i = 1 To m_goals.Count
        goal = m_goals(i)
        report = report &amp; GetGoalStatus(goal.name) &amp; vbCrLf &amp; vbCrLf
    Next i
    GenerateAllGoalsReport = report
End Function</code></pre>
<h2 id="error-handling">Error Handling</h2>
<pre><code class="language-vbnet">On Error Resume Next
Dim periods As Double
periods = NPer(rate, pmt, pv, fv, type)
If Err.Number &lt;&gt; 0 Then
    MsgBox &quot;Error calculating periods: &quot; &amp; Err.Description &amp; vbCrLf &amp; _
           &quot;This may occur if payment is too small to ever pay off the balance.&quot;
    &#x27; Payment must exceed interest to avoid infinite periods
End If
On Error GoTo 0</code></pre>
<h2 id="performance-considerations">Performance Considerations</h2>
<ul>
<li><code>NPer</code> uses iterative calculation - reasonably fast</li>
<li>More complex than simple arithmetic operations</li>
<li>For many calculations, consider caching results</li>
<li>Typically completes in microseconds</li>
<li>Performance similar to other financial functions (PMT, PV, FV)</li>
</ul>
<h2 id="best-practices">Best Practices</h2>
<ol>
<li><strong>Use consistent periods</strong> - Match rate and payment periods (monthly, yearly, etc.)</li>
<li><strong>Sign conventions</strong> - Money out is negative, money in is positive</li>
<li><strong>Validate inputs</strong> - Check that payment exceeds interest charge</li>
<li><strong>Handle errors</strong> - Wrap in error handling for invalid scenarios</li>
<li><strong>Round results</strong> - Round to appropriate precision for display</li>
<li><strong>Document assumptions</strong> - State whether payments are start/end of period</li>
<li><strong>Validate reasonableness</strong> - Check that results make sense</li>
<li><strong>Use with other functions</strong> - Combine with PMT, PV, FV for analysis</li>
<li><strong>Consider type parameter</strong> - Specify payment timing when relevant</li>
<li><strong>Format for users</strong> - Convert to years/months for clarity</li>
</ol>
<h2 id="comparison-with-related-functions">Comparison with Related Functions</h2>
<table>
<thead>
<tr>
<th>Function</th>
<th>Calculates</th>
<th>Given</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>NPer</code></strong></td>
<td>Number of periods</td>
<td>Rate, payment, present value, future value</td>
</tr>
<tr>
<td><strong>PMT</strong></td>
<td>Payment amount</td>
<td>Rate, periods, present value, future value</td>
</tr>
<tr>
<td><strong>PV</strong></td>
<td>Present value</td>
<td>Rate, periods, payment, future value</td>
</tr>
<tr>
<td><strong>FV</strong></td>
<td>Future value</td>
<td>Rate, periods, payment, present value</td>
</tr>
<tr>
<td><strong>Rate</strong></td>
<td>Interest rate</td>
<td>Periods, payment, present value, future value</td>
</tr>
</tbody>
</table>
<h2 id="platform-notes">Platform Notes</h2>
<ul>
<li>Available in VBA (Excel, Access, Word, etc.)</li>
<li>Available in VB6</li>
<li><strong>Not available in <code>VBScript</code></strong></li>
<li>Uses iterative algorithm to solve</li>
<li>Consistent with Excel's NPER function</li>
<li>Part of VBA financial functions library</li>
</ul>
<h2 id="limitations">Limitations</h2>
<ul>
<li>Assumes constant payment amounts</li>
<li>Assumes constant interest rate</li>
<li>Payment must exceed periodic interest or will fail/return error</li>
<li>Does not account for fees, taxes, or insurance</li>
<li>Cannot handle irregular payment schedules</li>
<li>Type parameter limited to 0 or 1</li>
<li>May return fractional periods</li>
</ul>
<h2 id="related-functions">Related Functions</h2>
<ul>
<li><strong>PMT</strong> - Calculates payment amount for a loan</li>
<li><strong>PV</strong> - Calculates present value of an investment</li>
<li><strong>FV</strong> - Calculates future value of an investment</li>
<li><strong>Rate</strong> - Calculates interest rate per period</li>
<li><strong><code>IPmt</code></strong> - Calculates interest payment for a specific period</li>
<li><strong><code>PPmt</code></strong> - Calculates principal payment for a specific period</li>
</ul>
<h2 id="vb6-parser-notes">VB6 Parser Notes</h2>
<p><code>NPer</code> is parsed as a regular function call (<code>CallExpression</code>). This module exists primarily
for documentation purposes to provide comprehensive reference material for VB6 developers
working with financial calculations, loan analysis, investment planning, and time-value-of-money
operations.</p>
        </article>
        
        <div style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border-color);">
            <p>
                <a href="index.html">← Back to Financial</a> |
                <a href="../index.html">View all functions</a>
            </p>
        </div>

    </main>

    <footer>
        <div class="container">
            <p>&copy; 2024-2026 VB6Parse Contributors. Licensed under the MIT License.</p>
        </div>
    </footer>
</body>
</html>