<!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 - loc - File">
<title>loc - File - 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/file/index.html">File</a> / loc</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="loc-function">Loc Function</h1>
<p>Returns a Long specifying the current read/write position within an open file.</p>
<h2 id="syntax">Syntax</h2>
<pre><code class="language-vbnet">Loc(filenumber)</code></pre>
<h2 id="parameters">Parameters</h2>
<ul>
<li><code>filenumber</code> (Required): Integer file number used in the Open statement</li>
<li>Must be a valid file number from a currently open file</li>
<li>File numbers typically obtained from <code>FreeFile</code> function</li>
</ul>
<h2 id="return-value">Return Value</h2>
<p>Returns a Long:
- For Random mode: Record number of last record read or written
- For Sequential mode: Current byte position divided by 128
- For Binary mode: Position of last byte read or written
- Returns 0 if no read/write operations have occurred yet
- Returns value based on last I/O operation</p>
<h2 id="remarks">Remarks</h2>
<p>The Loc function returns the current position in an open file:
- Behavior varies based on file access mode
- For Random access: Returns record number (1-based)
- For Sequential access: Returns byte position / 128 (approximation)
- For Binary access: Returns byte position (0-based)
- Does not move the file pointer
- Read-only operation (non-destructive)
- Useful for tracking progress in file operations
- Returns position of last operation, not next operation
- For Random files, increments after Get/Put
- For Binary files, tracks exact byte position
- For Sequential files, provides approximate position
- Essential for file I/O progress tracking
- Used with Seek to navigate files
- Different from Seek function (which also sets position)
- LOF function returns file length, Loc returns position
- Error 52 if file number not open
- Error 68 if device unavailable
- Common in loops reading/writing files
- Helps detect end-of-file conditions
- Used for progress bars during file operations</p>
<h2 id="typical-uses">Typical Uses</h2>
<ol>
<li><strong>Track Random File Position</strong></li>
</ol>
<pre><code class="language-vbnet"> currentRecord = Loc(1)
```
2. **Track Binary File Position**
```vb
bytesProcessed = Loc(fileNum)
```
3. **Progress Calculation**
```vb
percentComplete = (Loc(1) / LOF(1)) * 100
```
4. **Check if Data Written**
```vb
If Loc(fileNum) > 0 Then
' File has been written to
End If
```
5. **Loop Until End**
```vb
Do While Loc(1) < LOF(1)
Get #1, , record
Loop
```
6. **Record Number Display**
```vb
lblRecordNum.Caption = "Record: " & Loc(1)
```
7. **Byte Position Check**
```vb
Debug.Print "Position: " & Loc(fileNum)
```
8. **Progress Bar Update**
```vb
ProgressBar1.Value = (Loc(1) / totalRecords) * 100
```
## Basic Examples
### Example 1: Random File Position</code></pre>
<p>vb
Type CustomerRecord
ID As Long
Name As String * 50
End Type
Dim customer As CustomerRecord
Dim fileNum As Integer
fileNum = FreeFile
Open "customers.dat" For Random As #fileNum Len = Len(customer)
' Read records
Do While Not EOF(fileNum)
Get #fileNum, , customer
Debug.Print "Record: " & Loc(fileNum)
Loop
Close #fileNum</p>
<pre><code>### Example 2: Binary File Progress</code></pre>
<p>vb
Dim fileNum As Integer
Dim data As Byte
Dim fileSize As Long
fileNum = FreeFile
Open "data.bin" For Binary As #fileNum
fileSize = LOF(fileNum)
Do While Loc(fileNum) < fileSize
Get #fileNum, , data
' Update progress
If Loc(fileNum) Mod 1024 = 0 Then
Debug.Print "Progress: " & (Loc(fileNum) / fileSize) * 100 & "%"
End If
Loop
Close #fileNum</p>
<pre><code>### Example 3: Sequential File Position</code></pre>
<p>vb
Dim fileNum As Integer
Dim line As String
fileNum = FreeFile
Open "log.txt" For Input As #fileNum
Do While Not EOF(fileNum)
Line Input #fileNum, line
' Approximate position (bytes / 128)
Debug.Print "Position: " & Loc(fileNum)
Loop
Close #fileNum</p>
<pre><code>### Example 4: Track Write Position</code></pre>
<p>vb
Dim fileNum As Integer
Dim i As Integer
fileNum = FreeFile
Open "output.bin" For Binary As #fileNum
For i = 1 To 100
Put #fileNum, , i
Debug.Print "Wrote to position: " & Loc(fileNum)
Next i
Close #fileNum</p>
<pre><code>## Common Patterns
### Pattern 1: `CalculateProgress`</code></pre>
<p>vb
Function CalculateProgress(ByVal fileNum As Integer) As Single
Dim currentPos As Long
Dim totalSize As Long
currentPos = Loc(fileNum)
totalSize = LOF(fileNum)
If totalSize > 0 Then
CalculateProgress = (currentPos / totalSize) * 100
Else
CalculateProgress = 0
End If
End Function</p>
<pre><code>### Pattern 2: `IsFilePositionChanged`</code></pre>
<p>vb
Function IsFilePositionChanged(ByVal fileNum As Integer, _
ByVal lastPosition As Long) As Boolean
IsFilePositionChanged = (Loc(fileNum) <> lastPosition)
End Function</p>
<pre><code>### Pattern 3: `GetCurrentRecord`</code></pre>
<p>vb
Function GetCurrentRecord(ByVal fileNum As Integer) As Long
' For Random access files
GetCurrentRecord = Loc(fileNum)
End Function</p>
<pre><code>### Pattern 4: `GetBytesProcessed`</code></pre>
<p>vb
Function GetBytesProcessed(ByVal fileNum As Integer) As Long
' For Binary access files
GetBytesProcessed = Loc(fileNum)
End Function</p>
<pre><code>### Pattern 5: `UpdateProgressBar`</code></pre>
<p>vb
Sub UpdateProgressBar(ByVal fileNum As Integer, _
ByVal progressBar As ProgressBar)
Dim percent As Single
percent = (Loc(fileNum) / LOF(fileNum)) * 100
If percent <= 100 Then
progressBar.Value = percent
End If
DoEvents
End Sub</p>
<pre><code>### Pattern 6: `ReadFileWithProgress`</code></pre>
<p>vb
Sub ReadFileWithProgress(ByVal filename As String)
Dim fileNum As Integer
Dim data As Byte
Dim lastPercent As Integer
Dim currentPercent As Integer
fileNum = FreeFile
Open filename For Binary As #fileNum
Do While Loc(fileNum) < LOF(fileNum)
Get #fileNum, , data
ProcessByte data
currentPercent = Int((Loc(fileNum) / LOF(fileNum)) * 100)
If currentPercent <> lastPercent Then
Debug.Print "Progress: " & currentPercent & "%"
lastPercent = currentPercent
End If
Loop
Close #fileNum
End Sub</p>
<pre><code>### Pattern 7: `GetRecordPosition`</code></pre>
<p>vb
Function GetRecordPosition(ByVal fileNum As Integer) As String
Dim current As Long
Dim total As Long
current = Loc(fileNum)
total = LOF(fileNum) / Len(recordVariable)
GetRecordPosition = current & " of " & total
End Function</p>
<pre><code>### Pattern 8: `SafeLoc`</code></pre>
<p>vb
Function SafeLoc(ByVal fileNum As Integer) As Long
On Error Resume Next
SafeLoc = Loc(fileNum)
If Err.Number <> 0 Then
SafeLoc = -1
Err.Clear
End If
End Function</p>
<pre><code>### Pattern 9: `IsAtEndOfFile`</code></pre>
<p>vb
Function IsAtEndOfFile(ByVal fileNum As Integer) As Boolean
' For Binary mode
IsAtEndOfFile = (Loc(fileNum) >= LOF(fileNum))
End Function</p>
<pre><code>### Pattern 10: `LogFilePosition`</code></pre>
<p>vb
Sub LogFilePosition(ByVal fileNum As Integer, _
ByVal operation As String)
Debug.Print operation & " - Position: " & Loc(fileNum) & _
" of " & LOF(fileNum)
End Sub</p>
<pre><code>## Advanced Examples
### Example 1: File Reader with Progress</code></pre>
<p>vb
' Class: BinaryFileReader
Private m_fileNum As Integer
Private m_filename As String
Private m_fileSize As Long
Public Sub OpenFile(ByVal filename As String)
m_filename = filename
m_fileNum = FreeFile
Open filename For Binary As #m_fileNum
m_fileSize = LOF(m_fileNum)
End Sub
Public Function ReadByte() As Byte
If Not IsEOF Then
Get #m_fileNum, , ReadByte
End If
End Function
Public Property Get Position() As Long
Position = Loc(m_fileNum)
End Property
Public Property Get Size() As Long
Size = m_fileSize
End Property
Public Property Get Progress() As Single
If m_fileSize > 0 Then
Progress = (Loc(m_fileNum) / m_fileSize) * 100
Else
Progress = 0
End If
End Property
Public Property Get IsEOF() As Boolean
IsEOF = (Loc(m_fileNum) >= m_fileSize)
End Property
Public Sub CloseFile()
If m_fileNum > 0 Then
Close #m_fileNum
m_fileNum = 0
End If
End Sub
Private Sub Class_Terminate()
CloseFile
End Sub</p>
<pre><code>### Example 2: Random File Navigator</code></pre>
<p>vb
' Class: RandomFileNavigator
Private m_fileNum As Integer
Private m_recordLength As Integer
Private m_totalRecords As Long
Public Sub OpenFile(ByVal filename As String, _
ByVal recordLength As Integer)
m_recordLength = recordLength
m_fileNum = FreeFile
Open filename For Random As #m_fileNum Len = recordLength
m_totalRecords = LOF(m_fileNum) / recordLength
End Sub
Public Property Get CurrentRecord() As Long
CurrentRecord = Loc(m_fileNum)
End Property
Public Property Get TotalRecords() As Long
TotalRecords = m_totalRecords
End Property
Public Property Get ProgressPercent() As Single
If m_totalRecords > 0 Then
ProgressPercent = (Loc(m_fileNum) / m_totalRecords) * 100
Else
ProgressPercent = 0
End If
End Property
Public Function IsFirstRecord() As Boolean
IsFirstRecord = (Loc(m_fileNum) = 1)
End Function
Public Function IsLastRecord() As Boolean
IsLastRecord = (Loc(m_fileNum) = m_totalRecords)
End Function
Public Sub CloseFile()
If m_fileNum > 0 Then
Close #m_fileNum
m_fileNum = 0
End If
End Sub
Private Sub Class_Terminate()
CloseFile
End Sub</p>
<pre><code>### Example 3: File Copy with Progress</code></pre>
<p>vb
Sub CopyFileWithProgress(ByVal sourceFile As String, _
ByVal destFile As String, _
Optional progressBar As ProgressBar = Nothing)
Dim sourceNum As Integer, destNum As Integer
Dim buffer As Byte
Dim totalSize As Long
Dim lastPercent As Integer
Dim currentPercent As Integer
sourceNum = FreeFile
Open sourceFile For Binary As #sourceNum
totalSize = LOF(sourceNum)
destNum = FreeFile
Open destFile For Binary As #destNum
Do While Loc(sourceNum) < totalSize
Get #sourceNum, , buffer
Put #destNum, , buffer
If Not progressBar Is Nothing Then
currentPercent = Int((Loc(sourceNum) / totalSize) * 100)
If currentPercent <> lastPercent Then
progressBar.Value = currentPercent
lastPercent = currentPercent
DoEvents
End If
End If
Loop
Close #sourceNum
Close #destNum
End Sub</p>
<pre><code>### Example 4: File Processing Monitor</code></pre>
<p>vb
' Form with lblStatus, lblProgress, ProgressBar1
Private m_fileNum As Integer
Private m_totalSize As Long
Private Sub ProcessLargeFile(ByVal filename As String)
Dim data As Byte
Dim startTime As Single
m_fileNum = FreeFile
Open filename For Binary As #m_fileNum
m_totalSize = LOF(m_fileNum)
startTime = Timer
Timer1.Enabled = True
Do While Loc(m_fileNum) < m_totalSize
Get #m_fileNum, , data
ProcessData data
Loop
Timer1.Enabled = False
Close #m_fileNum
lblStatus.Caption = "Complete!"
End Sub
Private Sub Timer1_Timer()
UpdateProgress
End Sub
Private Sub UpdateProgress()
Dim percent As Single
Dim bytesProcessed As Long
On Error Resume Next
bytesProcessed = Loc(m_fileNum)
If m_totalSize > 0 Then
percent = (bytesProcessed / m_totalSize) * 100
ProgressBar1.Value = percent
lblProgress.Caption = Format(percent, "0.0") & "% - " & _
FormatBytes(bytesProcessed) & " of " & _
FormatBytes(m_totalSize)
End If
End Sub
Private Function FormatBytes(ByVal bytes As Long) As String
If bytes < 1024 Then
FormatBytes = bytes & " bytes"
ElseIf bytes < 1048576 Then
FormatBytes = Format(bytes / 1024, "0.0") & " KB"
Else
FormatBytes = Format(bytes / 1048576, "0.0") & " MB"
End If
End Function</p>
<pre><code>## Error Handling</code></pre>
<p>vb
' Error 52: Bad file name or number
On Error Resume Next
pos = Loc(999)
If Err.Number = 52 Then
MsgBox "File not open!"
End If
' Error 68: Device unavailable
pos = Loc(fileNum)
If Err.Number = 68 Then
MsgBox "Device unavailable!"
End If
' Safe position retrieval
Function GetSafePosition(ByVal fileNum As Integer) As Long
On Error Resume Next
GetSafePosition = Loc(fileNum)
If Err.Number <> 0 Then
GetSafePosition = -1
Err.Clear
End If
End Function</p>
<pre><code>## Performance Considerations
- **Very Fast**: Loc is a simple file pointer query
- **No I/O**: Does not perform actual file operations
- **Frequent Calls**: Safe to call in tight loops
- **Progress Updates**: Use modulo to update UI less frequently
- **`DoEvents`**: Call `DoEvents` when updating UI to maintain responsiveness
## Best Practices
1. **Use with LOF** for calculating percentage complete
2. **Check file is open** before calling Loc
3. **Update progress periodically** not on every byte
4. **Cache in variable** if using multiple times
5. **Use for Binary/Random** files (Sequential returns approximation)
6. **Combine with EOF** for robust loop conditions
7. **Handle errors** for unopened files
8. **Use `DoEvents`** when updating UI in loops
9. **Consider mode** when interpreting return value
10. **Document units** (bytes, records, or approximation)
## Comparison with Related Functions
| Function | Purpose | Read/Write | Return Value |
|----------|---------|------------|--------------|
| **Loc** | Get position | Read-only | Position |
| **Seek** (function) | Get position | Read-only | Position + 1 |
| **Seek** (statement) | Set position | Write | N/A |
| **LOF** | Get file length | Read-only | Total bytes |
| **EOF** | Check end | Read-only | Boolean |
## Loc vs Seek Function</code></pre>
<p>vb
' Loc - returns position of last operation
currentPos = Loc(fileNum)
' Seek - returns next read/write position (Loc + 1)
nextPos = Seek(fileNum)
' For Binary mode:
' After reading byte at position 100:
' Loc returns 100
' Seek returns 101</p>
<pre><code>## Mode-Specific Behavior</code></pre>
<p>vb
' Random mode - record number
Open "data.dat" For Random As #1 Len = 128
Get #1, 5, record
Debug.Print Loc(1) ' Returns 5 (record number)
' Binary mode - byte position
Open "data.bin" For Binary As #1
Get #1, , buffer
Debug.Print Loc(1) ' Returns bytes read
' Sequential mode - approximate (bytes / 128)
Open "text.txt" For Input As #1
Line Input #1, line
Debug.Print Loc(1) ' Returns approximate position
```</p>
<h2 id="platform-notes">Platform Notes</h2>
<ul>
<li>Available in all VB6 versions</li>
<li>Part of VBA core library</li>
<li>Returns Long (max 2GB file support)</li>
<li>For files > 2GB, result may overflow</li>
<li>Windows-specific file I/O</li>
<li>Behavior identical across Windows versions</li>
<li>Sequential mode approximation may vary</li>
<li>Random mode most reliable</li>
<li>Binary mode exact for files < 2GB</li>
</ul>
<h2 id="limitations">Limitations</h2>
<ul>
<li><strong>2GB Limit</strong>: Long type limits file size to ~2GB</li>
<li><strong>Sequential Approximation</strong>: Not exact for Input/Output/Append modes</li>
<li><strong>Division by 128</strong>: Sequential mode uses this approximation</li>
<li><strong>No String Files</strong>: Works with file numbers only</li>
<li><strong>Requires Open File</strong>: Error if file not open</li>
<li><strong>Mode Dependent</strong>: Return value meaning varies by mode</li>
<li><strong>No Directory</strong>: Only for files, not directories</li>
<li><strong>Last Operation</strong>: Returns position of last I/O, not current</li>
</ul>
<h2 id="related-functions">Related Functions</h2>
<ul>
<li><code>Seek</code>: Get/set file position (next position, not last)</li>
<li><code>LOF</code>: Get length of file</li>
<li><code>EOF</code>: Check if at end of file</li>
<li><code>Open</code>: Open file for I/O</li>
<li><code>Close</code>: Close file</li>
<li><code>Get</code>: Read from file (updates Loc)</li>
<li><code>Put</code>: Write to file (updates Loc)</li>
<li><code>FreeFile</code>: Get available file number</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 File</a> |
<a href="../index.html">View all functions</a>
</p>
</div>
</main>
<footer>
<div class="container">
<p>© 2024-2026 VB6Parse Contributors. Licensed under the MIT License.</p>
</div>
</footer>
</body>
</html>