vb6parse 1.0.1

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
<!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 - left - String">
    <title>left - String - 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/string/index.html">String</a> / left</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="left-function">Left Function</h1>
<p>Returns a String containing a specified number of characters from the left side of a string.</p>
<h2 id="syntax">Syntax</h2>
<pre><code class="language-vbnet">Left(string, length)</code></pre>
<h2 id="parameters">Parameters</h2>
<ul>
<li><code>string</code> (Required): String expression from which leftmost characters are returned</li>
<li>If string contains Null, Null is returned</li>
<li><code>length</code> (Required): Long indicating how many characters to return</li>
<li>If 0, empty string ("") is returned</li>
<li>If greater than or equal to number of characters in string, entire string is returned</li>
<li>Must be non-negative (negative values cause error)</li>
</ul>
<h2 id="return-value">Return Value</h2>
<p>Returns a String (or Variant containing String):
- Contains the specified number of characters from the left side of the string
- Returns empty string if length is 0
- Returns entire string if length &gt;= Len(string)
- Returns Null if string argument is Null
- Always returns String type (Left$ variant returns String, not Variant)</p>
<h2 id="remarks">Remarks</h2>
<p>The Left function extracts characters from the beginning of a string:
- Returns leftmost characters up to specified length
- Complements Right function (which returns rightmost characters)
- Works with Mid function for complete substring extraction
- Zero-based extraction: Left("ABC", 2) returns "AB"
- Safe with lengths exceeding string length (returns full string)
- Null propagates through the function
- Negative length raises Error 5 (Invalid procedure call or argument)
- Common for extracting prefixes, file names, codes, etc.
- More efficient than Mid(string, 1, length) for left extraction
- Left$ variant returns String type (not Variant) for slight performance gain
- Cannot extract from right side (use Right for that)
- Cannot skip characters (use Mid for that)
- Does not modify original string (strings are immutable)</p>
<h2 id="typical-uses">Typical Uses</h2>
<ol>
<li><strong>Extract Prefix</strong>: Get first N characters of string</li>
<li><strong>Parse Codes</strong>: Extract code prefixes from identifiers</li>
<li><strong>Truncate Text</strong>: Limit string length for display</li>
<li><strong>File Extensions</strong>: Extract drive letter or path prefix</li>
<li><strong>Validation</strong>: Check string starts with specific pattern</li>
<li><strong>Data Parsing</strong>: Extract fixed-width field data</li>
<li><strong>Formatting</strong>: Create abbreviations or short forms</li>
<li><strong>Pattern Matching</strong>: Compare string prefixes</li>
</ol>
<h2 id="basic-usage-examples">Basic Usage Examples</h2>
<pre><code class="language-vbnet">&#x27; Example 1: Basic left extraction
Dim text As String
text = &quot;Hello World&quot;
Debug.Print Left(text, 5)            &#x27; &quot;Hello&quot;
Debug.Print Left(text, 3)            &#x27; &quot;Hel&quot;
Debug.Print Left(text, 1)            &#x27; &quot;H&quot;
&#x27; Example 2: Length exceeds string length
Debug.Print Left(&quot;ABC&quot;, 10)          &#x27; &quot;ABC&quot; - entire string
Debug.Print Left(&quot;Test&quot;, 4)          &#x27; &quot;Test&quot; - exact length
&#x27; Example 3: Zero length
Debug.Print Left(&quot;Hello&quot;, 0)         &#x27; &quot;&quot; - empty string
&#x27; Example 4: Extract file extension check
Dim fileName As String
fileName = &quot;C:\Data\file.txt&quot;
If Left(fileName, 3) = &quot;C:\&quot; Then
    Debug.Print &quot;File on C: drive&quot;
End If</code></pre>
<h2 id="common-patterns">Common Patterns</h2>
<pre><code class="language-vbnet">&#x27; Pattern 1: Extract first N characters
Function GetPrefix(text As String, length As Long) As String
    If length &lt;= 0 Then
        GetPrefix = &quot;&quot;
    Else
        GetPrefix = Left(text, length)
    End If
End Function
&#x27; Pattern 2: Truncate with ellipsis
Function Truncate(text As String, maxLength As Long) As String
    If Len(text) &lt;= maxLength Then
        Truncate = text
    Else
        Truncate = Left(text, maxLength - 3) &amp; &quot;...&quot;
    End If
End Function
&#x27; Pattern 3: Check if string starts with prefix
Function StartsWith(text As String, prefix As String) As Boolean
    StartsWith = (Left(text, Len(prefix)) = prefix)
End Function
&#x27; Pattern 4: Extract first word
Function GetFirstWord(text As String) As String
    Dim spacePos As Long
    spacePos = InStr(text, &quot; &quot;)
    If spacePos &gt; 0 Then
        GetFirstWord = Left(text, spacePos - 1)
    Else
        GetFirstWord = text
    End If
End Function
&#x27; Pattern 5: Extract initials
Function GetInitials(fullName As String) As String
    Dim parts() As String
    Dim i As Long
    Dim initials As String
    parts = Split(Trim(fullName), &quot; &quot;)
    initials = &quot;&quot;
    For i = LBound(parts) To UBound(parts)
        If Len(parts(i)) &gt; 0 Then
            initials = initials &amp; UCase(Left(parts(i), 1))
        End If
    Next i
    GetInitials = initials
End Function
&#x27; Pattern 6: Safe Left with Null check
Function SafeLeft(value As Variant, length As Long) As String
    If IsNull(value) Then
        SafeLeft = &quot;&quot;
    Else
        SafeLeft = Left(value, length)
    End If
End Function
&#x27; Pattern 7: Extract drive letter
Function GetDriveLetter(path As String) As String
    If Len(path) &gt;= 2 And Mid(path, 2, 1) = &quot;:&quot; Then
        GetDriveLetter = Left(path, 2)
    Else
        GetDriveLetter = &quot;&quot;
    End If
End Function
&#x27; Pattern 8: Pad left to fixed width
Function PadLeft(text As String, width As Long, Optional padChar As String = &quot; &quot;) As String
    If Len(text) &gt;= width Then
        PadLeft = Left(text, width)
    Else
        PadLeft = String(width - Len(text), padChar) &amp; text
    End If
End Function
&#x27; Pattern 9: Extract area code from phone
Function GetAreaCode(phone As String) As String
    Dim digitsOnly As String
    Dim i As Long
    Dim char As String
    &#x27; Extract digits only
    digitsOnly = &quot;&quot;
    For i = 1 To Len(phone)
        char = Mid(phone, i, 1)
        If char &gt;= &quot;0&quot; And char &lt;= &quot;9&quot; Then
            digitsOnly = digitsOnly &amp; char
        End If
    Next i
    &#x27; Get first 3 digits as area code
    If Len(digitsOnly) &gt;= 3 Then
        GetAreaCode = Left(digitsOnly, 3)
    Else
        GetAreaCode = &quot;&quot;
    End If
End Function
&#x27; Pattern 10: Create abbreviation
Function Abbreviate(text As String, maxLength As Long) As String
    If Len(text) &lt;= maxLength Then
        Abbreviate = text
    Else
        &#x27; Take first letter of each word
        Dim words() As String
        Dim i As Long
        Dim abbr As String
        words = Split(text, &quot; &quot;)
        abbr = &quot;&quot;
        For i = LBound(words) To UBound(words)
            If Len(words(i)) &gt; 0 Then
                abbr = abbr &amp; UCase(Left(words(i), 1))
                If Len(abbr) &gt;= maxLength Then Exit For
            End If
        Next i
        Abbreviate = abbr
    End If
End Function</code></pre>
<h2 id="advanced-usage-examples">Advanced Usage Examples</h2>
<pre><code class="language-vbnet">&#x27; Example 1: Fixed-width file parser
Public Class FixedWidthParser
    Private m_fieldLengths() As Long
    Public Sub SetFieldLengths(ParamArray lengths() As Variant)
        Dim i As Long
        ReDim m_fieldLengths(LBound(lengths) To UBound(lengths))
        For i = LBound(lengths) To UBound(lengths)
            m_fieldLengths(i) = CLng(lengths(i))
        Next i
    End Sub
    Public Function ParseLine(line As String) As Variant
        Dim fields() As String
        Dim i As Long
        Dim pos As Long
        ReDim fields(LBound(m_fieldLengths) To UBound(m_fieldLengths))
        pos = 1
        For i = LBound(m_fieldLengths) To UBound(m_fieldLengths)
            If pos &lt;= Len(line) Then
                fields(i) = Trim(Mid(line, pos, m_fieldLengths(i)))
            Else
                fields(i) = &quot;&quot;
            End If
            pos = pos + m_fieldLengths(i)
        Next i
        ParseLine = fields
    End Function
    Public Function GetField(line As String, fieldIndex As Long) As String
        Dim pos As Long
        Dim i As Long
        pos = 1
        For i = LBound(m_fieldLengths) To fieldIndex - 1
            pos = pos + m_fieldLengths(i)
        Next i
        If pos &lt;= Len(line) Then
            GetField = Trim(Mid(line, pos, m_fieldLengths(fieldIndex)))
        Else
            GetField = &quot;&quot;
        End If
    End Function
End Class
&#x27; Example 2: Text preview/truncation utility
Public Class TextPreview
    Public Function CreatePreview(text As String, maxLength As Long, _
                                  Optional ellipsis As String = &quot;...&quot;) As String
        If Len(text) &lt;= maxLength Then
            CreatePreview = text
            Exit Function
        End If
        &#x27; Try to break at word boundary
        Dim truncated As String
        Dim lastSpace As Long
        truncated = Left(text, maxLength - Len(ellipsis))
        lastSpace = InStrRev(truncated, &quot; &quot;)
        If lastSpace &gt; maxLength \ 2 Then
            &#x27; Break at word if space found in second half
            CreatePreview = Left(truncated, lastSpace - 1) &amp; ellipsis
        Else
            &#x27; Break at character
            CreatePreview = truncated &amp; ellipsis
        End If
    End Function
    Public Function WordWrap(text As String, lineWidth As Long) As String
        Dim result As String
        Dim remaining As String
        Dim line As String
        Dim spacePos As Long
        result = &quot;&quot;
        remaining = text
        Do While Len(remaining) &gt; lineWidth
            &#x27; Try to break at word
            line = Left(remaining, lineWidth)
            spacePos = InStrRev(line, &quot; &quot;)
            If spacePos &gt; 0 Then
                result = result &amp; Left(line, spacePos - 1) &amp; vbCrLf
                remaining = Mid(remaining, spacePos + 1)
            Else
                result = result &amp; line &amp; vbCrLf
                remaining = Mid(remaining, lineWidth + 1)
            End If
        Loop
        result = result &amp; remaining
        WordWrap = result
    End Function
End Class
&#x27; Example 3: Code prefix analyzer
Public Class CodeAnalyzer
    Private m_prefixes As Collection
    Private Sub Class_Initialize()
        Set m_prefixes = New Collection
    End Sub
    Public Sub RegisterPrefix(prefix As String, description As String)
        m_prefixes.Add Array(prefix, description), prefix
    End Sub
    Public Function GetCodeType(code As String) As String
        Dim i As Long
        Dim prefix As Variant
        Dim info As Variant
        For i = 1 To m_prefixes.Count
            info = m_prefixes(i)
            prefix = info(0)
            If Left(code, Len(prefix)) = prefix Then
                GetCodeType = info(1)
                Exit Function
            End If
        Next i
        GetCodeType = &quot;Unknown&quot;
    End Function
    Public Function ExtractPrefix(code As String, prefixLength As Long) As String
        ExtractPrefix = Left(code, prefixLength)
    End Function
    Public Function StripPrefix(code As String, prefixLength As Long) As String
        If Len(code) &gt; prefixLength Then
            StripPrefix = Mid(code, prefixLength + 1)
        Else
            StripPrefix = &quot;&quot;
        End If
    End Function
End Class
&#x27; Example 4: String comparison helper
Public Class StringComparer
    Public Function StartsWith(text As String, prefix As String, _
                               Optional ignoreCase As Boolean = False) As Boolean
        Dim textPrefix As String
        Dim comparePrefix As String
        If Len(prefix) = 0 Then
            StartsWith = True
            Exit Function
        End If
        If Len(text) &lt; Len(prefix) Then
            StartsWith = False
            Exit Function
        End If
        textPrefix = Left(text, Len(prefix))
        If ignoreCase Then
            StartsWith = (LCase(textPrefix) = LCase(prefix))
        Else
            StartsWith = (textPrefix = prefix)
        End If
    End Function
    Public Function GetCommonPrefix(str1 As String, str2 As String) As String
        Dim i As Long
        Dim minLen As Long
        minLen = IIf(Len(str1) &lt; Len(str2), Len(str1), Len(str2))
        For i = 1 To minLen
            If Left(str1, i) &lt;&gt; Left(str2, i) Then
                If i = 1 Then
                    GetCommonPrefix = &quot;&quot;
                Else
                    GetCommonPrefix = Left(str1, i - 1)
                End If
                Exit Function
            End If
        Next i
        GetCommonPrefix = Left(str1, minLen)
    End Function
    Public Function RemovePrefix(text As String, prefix As String, _
                                 Optional ignoreCase As Boolean = False) As String
        If StartsWith(text, prefix, ignoreCase) Then
            RemovePrefix = Mid(text, Len(prefix) + 1)
        Else
            RemovePrefix = text
        End If
    End Function
End Class</code></pre>
<h2 id="error-handling">Error Handling</h2>
<p>Left handles several special cases:</p>
<pre><code class="language-vbnet">&#x27; Empty string
Debug.Print Left(&quot;&quot;, 5)              &#x27; &quot;&quot; - empty string
&#x27; Zero length
Debug.Print Left(&quot;Hello&quot;, 0)         &#x27; &quot;&quot; - empty string
&#x27; Length exceeds string
Debug.Print Left(&quot;Hi&quot;, 10)           &#x27; &quot;Hi&quot; - entire string
&#x27; Null propagates
Dim value As Variant
value = Null
Debug.Print IsNull(Left(value, 3))   &#x27; True
&#x27; Negative length causes error
&#x27; Debug.Print Left(&quot;Test&quot;, -1)       &#x27; Error 5: Invalid procedure call
&#x27; Safe pattern with error handling
Function SafeLeft(text As Variant, length As Long) As String
    On Error Resume Next
    If IsNull(text) Then
        SafeLeft = &quot;&quot;
    ElseIf length &lt; 0 Then
        SafeLeft = &quot;&quot;
    Else
        SafeLeft = Left(text, length)
    End If
    On Error GoTo 0
End Function</code></pre>
<h2 id="performance-considerations">Performance Considerations</h2>
<ul>
<li><strong>Fast Operation</strong>: Left is a very fast intrinsic function</li>
<li><strong>String Creation</strong>: Creates new string (strings are immutable)</li>
<li><strong>Left$ Variant</strong>: Use Left$ for String return type (slightly faster)</li>
<li><strong>Repeated Calls</strong>: Cache result if using same substring multiple times
Performance tips:</li>
</ul>
<pre><code class="language-vbnet">&#x27; Efficient for single use
If Left(fileName, 2) = &quot;C:&quot; Then
&#x27; Cache if used multiple times
Dim prefix As String
prefix = Left(code, 3)
If prefix = &quot;ABC&quot; Or prefix = &quot;DEF&quot; Then</code></pre>
<h2 id="best-practices">Best Practices</h2>
<ol>
<li><strong>Validate Length</strong>: Ensure length is non-negative</li>
<li><strong><code>Null</code> Safety</strong>: Check for <code>Null</code> before calling <code>Left</code> if needed</li>
<li><strong><code>StartsWith</code> Pattern</strong>: Use <code>Left</code> for prefix checking</li>
<li><strong>Truncation</strong>: Consider word boundaries when truncating display text</li>
<li><strong>Use <code>Left$</code></strong>: For <code>String</code> variables, use <code>Left$</code> for type safety</li>
<li><strong>Combine with <code>Len</code></strong>: Check string length before extracting</li>
<li><strong>Fixed-Width Data</strong>: Use <code>Left</code> for fixed-width field extraction</li>
<li><strong>Path Manipulation</strong>: Use <code>Left</code> for drive/path prefix extraction</li>
</ol>
<h2 id="comparison-with-related-functions">Comparison with Related Functions</h2>
<table>
<thead>
<tr>
<th>Function</th>
<th>Purpose</th>
<th>Parameters</th>
<th>Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Left</code></td>
<td>Extract from left</td>
<td><code>(string, length)</code></td>
<td>Get prefix/first N chars</td>
</tr>
<tr>
<td><code>Right</code></td>
<td>Extract from right</td>
<td><code>(string, length)</code></td>
<td>Get suffix/last N chars</td>
</tr>
<tr>
<td><code>Mid</code></td>
<td>Extract from middle</td>
<td><code>(string, start, [length])</code></td>
<td>Get substring from any position</td>
</tr>
<tr>
<td><code>InStr</code></td>
<td>Find substring</td>
<td><code>([start,] string1, string2)</code></td>
<td>Locate substring position</td>
</tr>
<tr>
<td><code>Len</code></td>
<td>Get string length</td>
<td><code>(string)</code></td>
<td>Measure string</td>
</tr>
</tbody>
</table>
<h2 id="left-vs-mid">Left vs Mid</h2>
<pre><code class="language-vbnet">Dim text As String
text = &quot;Hello World&quot;
&#x27; Left - simpler for leftmost characters
Debug.Print Left(text, 5)            &#x27; &quot;Hello&quot;
&#x27; Mid - equivalent but more verbose
Debug.Print Mid(text, 1, 5)          &#x27; &quot;Hello&quot;
&#x27; Use Left for clarity when extracting from start
&#x27; Use Mid when start position is not 1</code></pre>
<h2 id="left-right-and-mid-together">Left, Right, and Mid Together</h2>
<pre><code class="language-vbnet">Dim text As String
text = &quot;ABCDEFGH&quot;
&#x27; Left - first 3 characters
Debug.Print Left(text, 3)            &#x27; &quot;ABC&quot;
&#x27; Right - last 3 characters
Debug.Print Right(text, 3)           &#x27; &quot;FGH&quot;
&#x27; Mid - middle characters
Debug.Print Mid(text, 3, 4)          &#x27; &quot;CDEF&quot;
&#x27; Combine for complex extraction
Dim part As String
part = Left(Right(text, 5), 2)       &#x27; &quot;DE&quot;</code></pre>
<h2 id="platform-and-version-notes">Platform and Version Notes</h2>
<ul>
<li>Available in all VB6 versions</li>
<li>Part of VBA core functions</li>
<li>Returns Variant containing String (Left$ returns String type)</li>
<li>Maximum string length is approximately 2GB (theoretical)</li>
<li>Practical limit is much lower due to memory constraints</li>
</ul>
<h2 id="limitations">Limitations</h2>
<ul>
<li>Cannot extract from right side (use Right function)</li>
<li>Cannot extract from middle with offset (use Mid function)</li>
<li>Negative length raises error (not treated as 0)</li>
<li>Creates new string (cannot modify in place)</li>
<li>No option for character vs byte extraction</li>
<li>No built-in word boundary awareness</li>
</ul>
<h2 id="related-functions">Related Functions</h2>
<ul>
<li><code>Right</code>: Extract characters from right side of string</li>
<li><code>Mid</code>: Extract substring from any position</li>
<li><code>Len</code>: Get length of string</li>
<li><code>InStr</code>: Find position of substring</li>
<li><code>Trim</code>/<code>LTrim</code>/<code>RTrim</code>: Remove whitespace</li>
</ul>
        </article>
        
        <div style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border-color);">
            <p>
                <a href="index.html">← Back to String</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>