Interface IFileChannel
One file number that an Open statement associated with an external data file
(MS-VBAL §5.4.5), and the processing modes it was opened under.
public interface IFileChannel
Remarks
The association "remains in effect until they are explicitly disassociated using a
close-statement" (§5.4.5.1) — so a channel outlives the procedure that opened it
and belongs to the session, not to a call frame.
Properties
Access
What later statements may do with the channel. Implied by Mode when the Open
declared no Access clause.
VBFileAccessMode Access { get; }
Property Value
FileNumber
The file number source refers to this channel by — #1's 1.
int FileNumber { get; }
Property Value
Input
The channel as a character-input source, for Line Input # and Input #.
IFileChannelInput Input { get; }
Property Value
Remarks
Reads at the same file-pointer-position Output writes at: MS-VBAL
§5.4.5 gives a channel one position and not one per direction, which is what makes an
Append channel able to read back what it appended.
👉 As with Output, a caller is expected to have asked FileStatementAccess whether the statement is valid on this channel first.
Lock
What the channel locks against other processes. Shared when the
Open declared no lock.
VBFileLockMode Lock { get; }
Property Value
Locks
The ranges of this channel's file currently locked against other agents (MS-VBAL §5.4.5.4), in no particular order.
IEnumerable<FileRecordRange> Locks { get; }
Property Value
Remarks
"Multiple lock ranges established by multiple lock statements can be simultaneously active", and each
"remains in effect until it is removed by an Unlock statement... or specifies a record range
that evaluates to the same start record and end record" — so which ranges are held is not bookkeeping,
it is what decides whether the next Unlock is legal.
Mode
How data is read from and written to the file. Random when the
Open declared no For clause (§5.4.5.1).
VBFileMode Mode { get; }
Property Value
Output
The channel as a character-output target, for Print # and Write #.
IFileChannelOutput Output { get; }
Property Value
Remarks
The same IRuntimeOutput the session's own output is, so MS-VBAL
§5.4.5.8's output rules - print zones, the numeric space, Spc, Tab, a trailing
; - are evaluated once and written wherever they are aimed. A channel counts its own line
position, which is what those rules are relative to.
👉 A caller is expected to have asked FileStatementAccess whether the statement is valid on this channel first. Writing to one opened for reading fails rather than corrupting it, but reporting which statement was wrong is the caller's job, not this one's.
Path
The complete path specification the channel was opened on.
string Path { get; }
Property Value
Position
The current file-pointer-position, one-based — counted in records when the channel was opened Random and in bytes otherwise (MS-VBAL §5.4.5.3).
long Position { get; }
Property Value
RecordLength
The Len = record length, or 0 when the Open declared none. Ignored for
Binary, which the specification says to disregard it for.
int RecordLength { get; }
Property Value
Methods
LockRange(FileRecordRange)
Locks range of the file against other agents (MS-VBAL §5.4.5.4).
VBRuntimeErrorId? LockRange(FileRecordRange range)
Parameters
rangeFileRecordRangeThe range to lock, or EntireFile. A channel opened Input, Output or Append locks the entire file whatever is asked for, which the specification states outright.
Returns
- VBRuntimeErrorId?
The error that stopped it, or
null. "Start record MUST be greater than or equal to 1, and less than or equal to end record. If not, an error is raised" — unnamed there, and MS-VBA raises63.
Seek(long)
Repositions the channel so the next operation happens at position
(MS-VBAL §5.4.5.3).
VBRuntimeErrorId? Seek(long position)
Parameters
Returns
- VBRuntimeErrorId?
The error that stopped it, or
null. A position of0or less is one — the specification says "an error is raised" without naming it, and MS-VBA raises63,Bad record number.
Remarks
A position past the end of the file extends it — "the extended content of the file is implementation defined and can be undefined" — except on a channel whose access is Read, which the specification exempts.
TryReadRecord(VBType, int, out VBTypedValue?)
Reads one record at the current file-pointer-position — what a Get statement does
(MS-VBAL §5.4.5.12).
bool TryReadRecord(VBType declaredType, int currentLength, out VBTypedValue? value)
Parameters
declaredTypeVBTypeThe declared type of the variable being read into, which decides how many bytes the record occupies — except for a
Variant, where the record's own descriptor decides.currentLengthintThe length of the variable's current value, which is how many bytes a
Stringread from a Binary channel takes.valueVBTypedValueThe value read.
Returns
- bool
falseat end of file, or for a declared type the format has no row for.
TryReadRecordInto(VBUserDefinedTypeValue)
Reads one record into the fields of userDefinedType, in declaration order — what a
Get whose variable is a UDT does (MS-VBAL §5.4.5.12).
bool TryReadRecordInto(VBUserDefinedTypeValue userDefinedType)
Parameters
userDefinedTypeVBUserDefinedTypeValueThe UDT value whose fields are filled.
Returns
- bool
falseat end of file, or for a field whose type the format has no row for.
Remarks
Reads into the value rather than producing a new one, because that is what the statement
describes and what a UDT variable is: it has location identity, so a Get fills the variable the
program already has rather than replacing it. Each field is read by its own row of the format, so a
record written by a Put of the same type reads straight back.
TryWriteRecord(VBTypedValue, bool, out int)
Writes one record at the current file-pointer-position, in the byte format
MS-VBAL §5.4.5.11's tables define — what a Put statement does.
bool TryWriteRecord(VBTypedValue value, bool isVariant, out int written)
Parameters
valueVBTypedValueThe value to write.
isVariantboolWhether the
dataexpression's declared type isVariant, which the format precedes with a two-byte type descriptor.writtenintHow many bytes reached the file, which
Putchecks against a record length.
Returns
- bool
falsefor a value the format has no row for — an object, or a UDT.
Remarks
Record I/O is bytes rather than characters, so it does not go through Output: a record's width comes from the value's declared type and not from how it prints, and nothing about it is relative to a line.
UnlockRange(FileRecordRange)
Releases a lock this channel holds (MS-VBAL §5.4.5.5).
VBRuntimeErrorId? UnlockRange(FileRecordRange range)
Parameters
rangeFileRecordRangeThe range to release, which "MUST designate a range that is identical to a start record to end record range of a previously executed
Lockstatement", or EntireFile.
Returns
- VBRuntimeErrorId?
The error that stopped it, or
null. Asking for a range noLockestablished is one, and so is the mismatch the specification names last: "if a record range is provided for only theLockstatement or theUnlockstatement designating the same currently open file number".