diff --git a/docs/Features/Standard-Library/File-IO.md b/docs/Features/Standard-Library/File-IO.md index 81dd1b4..5c333fc 100644 --- a/docs/Features/Standard-Library/File-IO.md +++ b/docs/Features/Standard-Library/File-IO.md @@ -16,27 +16,4 @@ Open "C:\MyFile.txt" For Input Encoding utf-8 As #1 ## Supported Encodings -The full list of encoding options currently defined (and don't worry, these will come up in Intellisense) is: - -- `default_system_ansi` -- `utf_7`, `utf_7_bom` -- `utf_8`, `utf_8_bom` -- `utf_16`, `utf_16_bom` -- `us_ascii` -- `koi8_u`, `koi8_r` -- `big5` -- `iso_8859_1_latin1`, `iso_8859_2_latin2`, `iso_8859_3_latin3`, `iso_8859_4_latin4` -- `iso_8859_5_cyrillic`, `iso_8859_6_arabic`, `iso_8859_7_greek`, `iso_8859_8_hebrew` -- `iso_8859_9_latin5_turkish`, `iso_8859_10_latin6_nordic`, `iso_8859_11_thai` -- `iso_8859_13_latin8_baltic`, `iso_8859_14_latin8_celtic` -- `iso_8859_15_latin9_euro`, `iso_8859_16_latin10_balkan` -- `windows_1250_central_europe`, `windows_1251_cyrillic`, `windows_1252_western` -- `windows_1253_greek`, `windows_1254_turkish`, `windows_1255_hebrew`, `windows_1256_arabic` -- `windows_1257_baltic`, `windows_1258_vietnamese` -- `ibm_850_western_europe`, `ibm_852_central_and_eastern_europe` -- `ibm_855_cyrillic`, `ibm_856_hebrew`, `ibm_857_turkish`, `ibm_858_western_europe` -- `ibm_860_portuguese`, `ibm_861_icelandic`, `ibm_862_hebrew` -- `ibm_863_canadian`, `ibm_865_danish`, `ibm_866_cyrillic`, `ibm_869_greek` -- `ibm_932_japanese`, and `ibm_949_korean` - -Others with a similar format should be accepted depending on system support. +See the [TextEncodingConstants module](../../tB/Modules/TextEncodingConstants/). diff --git a/docs/Reference/Modules/Compilation/index.md b/docs/Reference/Modules/Compilation/index.md index 4c8cf9d..46c37ce 100644 --- a/docs/Reference/Modules/Compilation/index.md +++ b/docs/Reference/Modules/Compilation/index.md @@ -7,6 +7,37 @@ has_toc: false # Compilation module +The **Compilation** module groups together intrinsics that report on how — and from where — the running code was built. Most of its members are *compile-time* intrinsics: they do not look anything up at run time but instead bake a literal value into the compiled code at the point of the call, recording the surrounding project, component, procedure, or source file as it stood when the compiler ran. + +## Build identity + +[**CompilerVersion**](CompilerVersion) returns the build number of the twinBASIC compiler that produced the running code, and [**ProcessorArchitecture**](ProcessorArchitecture) returns a [**VbArchitecture**](../Constants/VbArchitecture) constant — **vbArchWin32** or **vbArchWin64** — identifying whether the binary was built for 32-bit or 64-bit execution. Together they characterise *which* compiler emitted the running code and *what kind* of process it is running in. + +```tb +Debug.Print "twinBASIC build #" & CompilerVersion() +If ProcessorArchitecture() = vbArchWin64 Then + Debug.Print "64-bit process" +Else + Debug.Print "32-bit process" +End If +``` + +## Lexical context + +The `Current...` family records the source location of the call site as a literal string, captured when the source is compiled. [**CurrentProjectName**](CurrentProjectName) names the project (executable or library) that owns the call, [**CurrentComponentName**](CurrentComponentName) names the enclosing module, class, or form, [**CurrentProcedureName**](CurrentProcedureName) names the surrounding **Sub**, **Function**, or **Property**, and [**CurrentSourceFile**](CurrentSourceFile) returns the full path of the source file as it was on the build machine. For COM classes, [**CurrentComponentCLSID**](CurrentComponentCLSID) returns the GUID supplied by the class's [`[ClassId(...)]`](../../Core/Attributes#classid) attribute, or the all-zero GUID when none is set. + +Because each value is fixed at compile time, wrapping a call in a helper records the *helper's* name rather than its caller's. These intrinsics are most useful in diagnostic output — logging, tracing, assertions — where they replace hard-coded identifier strings that would otherwise drift as code is renamed. + +```tb +Public Sub Log(Message As String) + Debug.Print CurrentProjectName() & "!" & _ + CurrentComponentName() & "." & _ + CurrentProcedureName() & ": " & Message +End Sub +``` + +## Members + - [CompilerVersion](CompilerVersion) -- returns the twinBASIC compiler version number - [CurrentComponentCLSID](CurrentComponentCLSID) -- returns the Class ID (CLSID) of the current class - [CurrentComponentName](CurrentComponentName) -- returns the name of the current component (module or class) diff --git a/docs/Reference/Modules/Conversion/index.md b/docs/Reference/Modules/Conversion/index.md index 21cd802..e76f6f4 100644 --- a/docs/Reference/Modules/Conversion/index.md +++ b/docs/Reference/Modules/Conversion/index.md @@ -7,6 +7,63 @@ has_toc: false # Conversion module +The **Conversion** module groups together the procedures that produce a value of one type from a value of another — coercing between the intrinsic numeric types, parsing numbers out of strings, formatting numbers as strings, and a handful of related utilities for handling **Null**, error values, and alternate numeric bases. + +## Coercing to a specific type + +The largest group is the family of **C**-prefixed functions, one per intrinsic data type. Each accepts any valid expression and produces a value of the named type, raising a run-time error if the conversion is not possible: [**CBool**](CBool), [**CByte**](CByte), [**CCur**](CCur), [**CDate**](CDate), [**CDbl**](CDbl), [**CDec**](CDec), [**CInt**](CInt), [**CLng**](CLng), [**CLngLng**](CLngLng), [**CLngPtr**](CLngPtr), [**CSng**](CSng), [**CStr**](CStr), and [**CVar**](CVar). + +Beyond their narrowing or widening behaviour, the C-prefix functions are *locale-aware* — they honour the current decimal separator and short date format — which makes them the right choice for parsing values that originated as user input. They also serve as documentation: writing `CLng(x)` makes the intended type of an intermediate result explicit even where the surrounding context would coerce *x* implicitly. + +```tb +Dim Amount As Currency +Amount = CCur("1,234.56") ' parses with the local decimal separator +``` + +Two further constructors return a **Variant** whose subtype is fixed: [**CVDate**](CVDate) builds a **Variant** of subtype **Date** (kept for compatibility with code written before **Date** became an intrinsic type), and [**CVErr**](CVErr) builds a **Variant** of subtype **Error** carrying a chosen error number — the canonical way for a **Variant**-returning function to signal "this call failed with this error code" without raising a run-time error. + +## Generic conversion + +[**CType**](CType) is a twinBASIC extension that takes its target type as a generic parameter, written `CType(Of `*type*`)(`*value*`)`. It plays the same role as the C-prefix functions but for any type known to the compiler, which makes it the standard cast for **Enum** values, interfaces, and user-defined types where no fixed-name function exists. **CType** doubles as a pointer-to-UDT cast — see [Enhanced Pointer Functionality](../../../Features/Language/Pointers#ctypeof-type). + +```tb +Dim day As VbDayOfWeek +day = CType(Of VbDayOfWeek)(1) +``` + +## Truncating to an integer + +[**Int**](Int) and [**Fix**](Fix) both discard the fractional part of a number, but they round in opposite directions for negative input. **Int** rounds toward negative infinity, so `Int(-8.4)` is `-9`; **Fix** truncates toward zero, so `Fix(-8.4)` is `-8`. For positive values the two coincide. Neither changes the data type of its argument, in contrast to [**CInt**](CInt) and [**CLng**](CLng), which both round and narrow to a specific integer type. + +```tb +Debug.Print Int(-8.4) ' -9 +Debug.Print Fix(-8.4) ' -8 +``` + +## Numbers, strings, and bases + +[**Str**](Str), [**Hex**](Hex), and [**Oct**](Oct) all return a printable string representation of a number — **Str** in decimal, **Hex** in base 16, and **Oct** in base 8. Going the other way, [**Val**](Val) and [**ValDec**](ValDec) parse leading digits out of a string, returning a **Double** or **Decimal** respectively; both stop at the first unrecognised character and both honour the `&H` and `&O` radix prefixes for hexadecimal and octal literals. + +These five functions are *culture-invariant* — they always use the period (`.`) as the decimal separator and never read or write a thousands separator — which makes them appropriate for round-tripping through a fixed file format or wire protocol. For locale-aware conversion to and from text, use [**CStr**](CStr) and [**CDbl**](CDbl) (or [**CDec**](CDec)) instead. + +```tb +Debug.Print Hex(255) ' "FF" +Debug.Print Oct(8) ' "10" +Debug.Print Val("&HFF") ' 255 +``` + +## Working with Null and error values + +[**Nz**](Nz) returns a substitute value when its argument is **Null**, leaving any other value unchanged. It is most useful for reading nullable columns from a database recordset, where directly concatenating or arithmetically combining the field with another value would otherwise propagate **Null** through the rest of the expression. + +[**Error**](Error) returns the descriptive text associated with an error number — the same text that would appear as the **Description** of an [**ErrObject**](../ErrObject) raised with that number. It is the function counterpart to the same-named [**Error** statement](../../Core/Error), which *raises* a run-time error rather than describing one. + +## Macintosh compatibility + +[**MacID**](MacID) packs a four-character Macintosh resource type or application signature into a **Long** for use with [**Dir**](../FileSystem/Dir), [**Kill**](../FileSystem/Kill), **Shell**, or [**AppActivate**](../Interaction/AppActivate). twinBASIC currently targets Windows, where the value has no special meaning to those functions; **MacID** is provided for source compatibility with VBA code originally written for the classic Mac. + +## Members + - [CBool](CBool) -- converts an expression to a **Boolean** - [CByte](CByte) -- converts an expression to a **Byte** - [CCur](CCur) -- converts an expression to a **Currency** diff --git a/docs/Reference/Modules/DateTime/index.md b/docs/Reference/Modules/DateTime/index.md index 7277b97..063c70d 100644 --- a/docs/Reference/Modules/DateTime/index.md +++ b/docs/Reference/Modules/DateTime/index.md @@ -7,6 +7,63 @@ has_toc: false # DateTime module +The **DateTime** module groups together the procedures for reading the system clock, building **Date** values from their components, parsing them out of strings, taking them apart again, and shifting them forward or backward by a chosen unit. A single setting — the [**Calendar**](Calendar) property — switches the whole module between the Gregorian and Hijri calendars. + +## Reading the system clock + +[**Now**](Now) returns the current system date *and* time as a single **Variant** of subtype **Date**; [**Date**](Date) returns just the date portion and [**Time**](Time) just the time portion. Each of the latter two has a `$`-suffixed sibling — **Date$** and **Time$** — that returns the same value as a formatted **String** rather than a **Date**. All four are also writable: assigning to them changes the system clock, subject to the operating system's privilege requirements. + +> [!NOTE] +> In twinBASIC, **Date**, **Date$**, **Time**, and **Time$** are implemented as module-level properties rather than the functions/statements they were in VBx. The syntax and semantics are otherwise unchanged. + +[**Timer**](Timer) returns a **Single** giving the number of seconds — with fractional precision — elapsed since midnight, and is the conventional way to measure elapsed time within a run. + +```tb +Dim Started As Single +Started = Timer +' ... do some work ... +Debug.Print "Elapsed: " & (Timer - Started) & " seconds" +``` + +## Building dates and times from components + +[**DateSerial**](DateSerial) builds a **Date** from year, month, and day arguments; [**TimeSerial**](TimeSerial) builds one from hour, minute, and second. Both honour out-of-range arguments by carrying — passing 13 as the month rolls into the next year, and passing 75 as the minute rolls into the next hour — which makes them well-suited to expressing relative dates as plain arithmetic on the components. + +```tb +Dim FirstOfNextMonth As Date +FirstOfNextMonth = DateSerial(Year(Now), Month(Now) + 1, 1) +``` + +[**DateValue**](DateValue) parses a date out of a string in the system's short date format — recognising both numeric forms and unambiguous month names — and discards any time portion. [**TimeValue**](TimeValue) is the corresponding parser for time strings; it discards any date portion. For values that originate as date literals in source code, the surrounding `#...#` syntax is usually a better fit than either parser. + +## Extracting parts of a date + +The single-component accessors each return one part of a **Date** as an **Integer**: [**Year**](Year), [**Month**](Month), [**Day**](Day), [**Weekday**](Weekday), [**Hour**](Hour), [**Minute**](Minute), and [**Second**](Second). [**DatePart**](DatePart) generalises the same idea, taking the chosen part as a string interval code (`"yyyy"`, `"q"`, `"m"`, `"d"`, ...) — useful when the unit itself is a parameter. + +```tb +Dim D As Date +D = #2/12/1969# +Debug.Print Year(D) ' 1969 +Debug.Print Month(D) ' 2 +Debug.Print Day(D) ' 12 +Debug.Print Weekday(D) ' 4 — Wednesday +``` + +## Date arithmetic + +[**DateAdd**](DateAdd) shifts a date by a chosen number of intervals — years, quarters, months, weeks, days, hours, minutes, or seconds — taking calendar irregularities (varying month lengths, leap years) into account, and clamping to the last day of the target month when a literal day-of-month would be invalid. [**DateDiff**](DateDiff) does the inverse: it returns the count of whole intervals between two dates. Both share the same string interval codes used by **DatePart**. + +```tb +Debug.Print DateAdd("m", 1, #1/31/2026#) ' 2/28/2026 — clamped to last day of February +Debug.Print DateDiff("d", #1/1/2026#, #5/9/2026#) ' 128 +``` + +## Calendar selection + +The [**Calendar**](Calendar) property selects the calendar — **vbCalGreg** (Gregorian, the default) or **vbCalHijri** (Hijri) — used by the rest of the module. The setting controls how **Date$** formats the system date, how arguments to **DateSerial**, **DateValue**, **DateAdd**, and **DateDiff** are interpreted, and how the parts returned by **DatePart**, **Year**, **Month**, **Day**, and **Weekday** are reported. + +## Members + - [Calendar](Calendar) -- returns or sets the calendar type (Gregorian or Hijri) - [Date](Date) -- sets or returns the current system date - [DateAdd](DateAdd) -- adds a time interval to a date diff --git a/docs/Reference/Modules/FileSystem/index.md b/docs/Reference/Modules/FileSystem/index.md index 60e357a..a1965f1 100644 --- a/docs/Reference/Modules/FileSystem/index.md +++ b/docs/Reference/Modules/FileSystem/index.md @@ -7,8 +7,72 @@ has_toc: false # FileSystem module +The **FileSystem** module groups together the procedures and statements for working with files and directories on disk. Its members divide cleanly into two camps: *pathname-based* operations that act on something named in the filesystem, and *file-number-based* operations that act on a handle previously returned by the **Open** statement. + +## Navigating directories + +[**ChDrive**](ChDrive) changes the current drive, [**ChDir**](ChDir) changes the current directory on a given drive, and [**CurDir**](CurDir) returns the path of the current drive — or of any other drive, if one is named. [**MkDir**](MkDir) and [**RmDir**](RmDir) create and remove directories. + +```tb +ChDrive "D" +ChDir "D:\Projects" +Debug.Print CurDir ' "D:\Projects" +MkDir "D:\Projects\Output" +``` + +## Inspecting files and directories + +[**Dir**](Dir) is the wildcard matcher: pass it a pathname containing `*` or `?` and it returns the first matching name, then call it again with no arguments to step through subsequent matches until it returns `""`. [**FileLen**](FileLen) returns the size of a file in bytes without opening it, and [**FileDateTime**](FileDateTime) returns its last-modified timestamp. [**GetAttr**](GetAttr) and [**SetAttr**](SetAttr) read and write the [**VbFileAttribute**](../Constants/VbFileAttribute) flag bits — read-only, hidden, system, archive — and **GetAttr** also reports whether a name refers to a directory by setting the **vbDirectory** bit. + +```tb +Dim Name As String +Name = Dir("C:\Logs\*.log") +Do While Name <> "" + Debug.Print Name & vbTab & FileLen("C:\Logs\" & Name) + Name = Dir +Loop +``` + +## Copying and deleting + +[**FileCopy**](FileCopy) copies one file to another, and [**Kill**](Kill) deletes files matching a wildcard pattern. Both operate by pathname and raise a run-time error when asked to act on a file the current process has open. + +```tb +FileCopy "C:\Data\report.xlsx", "C:\Backup\report.xlsx" +Kill "C:\Backup\*.tmp" +``` + +## Opening and tracking file numbers + +The lower-level read/write statements — **Open**, **Close**, **Get**, **Put**, **Print**, **Write**, **Input**, and **Line Input** — work in terms of a *file number* in the range 1–511. [**FreeFile**](FreeFile) returns the next number that isn't currently in use, sparing the caller from picking one by hand and racing other code to it. Once a file is open, [**FileAttr**](FileAttr) reports the access mode — **Input**, **Output**, **Random**, **Append**, or **Binary** — that the file number was opened with. [**Reset**](Reset) closes every file number currently open and flushes its buffers, and is most useful as a last-ditch cleanup before exit. + +```tb +Dim N As Long +N = FreeFile +Open "C:\Data\report.txt" For Input As #N +' ... read ... +Close #N +``` + +## Position within an open file + +For an open file number, [**EOF**](EOF) returns **True** once a sequential read has run past the last record, [**LOF**](LOF) returns the file's total length in bytes, and [**Loc**](Loc) returns the current read/write position. The unit of *position* depends on the open mode — record number for **Random**, byte offset for **Binary**, and the byte position divided by 128 for sequential modes — so the per-mode tables on each function's page are the authoritative reference. [**Seek**](Seek) doubles as a function and a statement: the function returns the position of the **next** read or write (whereas **Loc** reports the position of the *last*), and the statement repositions the file pointer ahead of the next operation. + +```tb +Dim N As Long, Line As String +N = FreeFile +Open "C:\Data\big.log" For Input As #N +Do While Not EOF(N) + Line Input #N, Line +Loop +Close #N +``` + +## Members + - [ChDir](ChDir) -- changes the current directory or folder - [ChDrive](ChDrive) -- changes the current drive +- [CurDir](CurDir) -- returns the current path - [Dir](Dir) -- returns the name of a file, directory, folder, or volume label that matches a pattern - [EOF](EOF) -- returns whether the end of a file opened for **Random** or sequential **Input** has been reached - [FileAttr](FileAttr) -- returns the file mode for files opened with the **Open** statement @@ -21,7 +85,6 @@ has_toc: false - [Loc](Loc) -- returns the current read/write position within an open file - [LOF](LOF) -- returns the size, in bytes, of an open file - [MkDir](MkDir) -- creates a new directory or folder -- [CurDir](CurDir) -- returns the current path - [Reset](Reset) -- closes all disk files opened by using the **Open** statement - [RmDir](RmDir) -- removes an existing directory or folder - [Seek](Seek) -- returns or sets the read/write position within an open file diff --git a/docs/Reference/Modules/Financial/index.md b/docs/Reference/Modules/Financial/index.md index d6c2f43..60ac9e3 100644 --- a/docs/Reference/Modules/Financial/index.md +++ b/docs/Reference/Modules/Financial/index.md @@ -7,16 +7,57 @@ has_toc: false # Financial module -- [DDB](DDB) -- depreciation of an asset via the Double-Declining Balance method -- [FV](FV) -- future value of an investment with constant deposits and interest -- [Pmt](Pmt) -- payment for a loan with constant payments and interest -- [IPmt](IPmt) -- interest payment for a loan with constant payments and interest -- [PPmt](PPmt) -- principal payment for a loan with constant payments and interest -- [SYD](SYD) -- sum-of-years' digits depreciation of an asset -- [SLN](SLN) -- straight-line depreciation of an asset in one period -- [PV](PV) -- present value of investment -- [IRR](IRR) -- internal rate of return for a series of cash flows -- [MIRR](MIRR) -- modified internal rate of return for a series of cash flow -- [Rate](Rate) -- interest rate per period of an annuity -- [NPV](NPV) -- net present value of an investment -- [NPer](NPer) -- number of periods for an investment with constant deposits and interest +The **Financial** module groups together the procedures that solve standard time-value-of-money problems — annuity calculations for loans and savings plans with fixed periodic cash flows, return and present-value analysis for irregular cash flow streams, and asset depreciation under three different accounting conventions. + +## Annuities + +An *annuity* is a series of fixed cash payments made at equally spaced intervals. Seven of the module's functions describe the same underlying annuity model and differ only in *which* of its quantities they solve for: [**FV**](FV) returns the future value (the cash balance after the final payment), [**PV**](PV) the present value (the value today of the future cash flows), [**Pmt**](Pmt) the periodic payment amount, [**NPer**](NPer) the number of periods, and [**Rate**](Rate) the interest rate per period. [**IPmt**](IPmt) and [**PPmt**](PPmt) decompose a single payment into its interest and principal portions. + +All seven take the same core arguments — *rate*, *nper*, *pmt*, *pv*, *fv*, *type* — in different orders, with the unknown one omitted. *rate* is the interest rate per period (an annual percentage divided by the number of periods per year); *nper* is the total number of payment periods; *pmt* is the payment per period; *pv* and *fv* are the present and future values; *type* is `0` if payments fall at the end of the period and `1` if at the beginning. **Rate** additionally accepts a *guess* argument — it solves its equation iteratively, and a starting estimate can be supplied when the default of 10 % fails to converge in twenty cycles. + +```tb +Const APR As Double = 0.06 +Dim Monthly As Double +Monthly = -Pmt(APR / 12, 30 * 12, 200000) ' fixed monthly payment on a 30-year, $200,000 mortgage at 6 % APR +``` + +## Variable cash flows + +For investments whose cash flows vary period to period, three functions take an array of values rather than a single payment amount. [**NPV**](NPV) returns the net present value of the cash flows discounted at a chosen rate; [**IRR**](IRR) returns the internal rate of return — the discount rate that would make **NPV** zero; and [**MIRR**](MIRR) returns the modified internal rate of return, where outflows and reinvested inflows are discounted at separate rates. The order of values within the array is significant — element *i* is the cash flow for period *i* — and the array must contain at least one negative entry (a payment) and one positive entry (a receipt). Like **Rate**, both **IRR** and **MIRR** are computed iteratively and accept an optional *guess*. + +```tb +Dim CashFlows(0 To 4) As Double +CashFlows(0) = -70000 ' initial outlay +CashFlows(1) = 22000 : CashFlows(2) = 25000 +CashFlows(3) = 28000 : CashFlows(4) = 31000 +Debug.Print IRR(CashFlows) ' approximate internal rate of return +Debug.Print NPV(0.0625, CashFlows) ' net present value at a 6.25 % discount rate +``` + +## Depreciation + +Three functions return the depreciation of an asset over a chosen period under three different accounting conventions, all parameterised by the asset's initial *cost*, its *salvage* value at the end of its useful life, and its *life* in periods. [**SLN**](SLN) applies straight-line depreciation, spreading the lost value uniformly across each period. [**DDB**](DDB) applies the double-declining balance method (or a chosen multiplier), front-loading the depreciation so it is highest in the first period and decreases geometrically thereafter. [**SYD**](SYD) applies sum-of-years' digits depreciation — also accelerated, but linearly tapered. + +**SLN** returns the same value for every period; **DDB** and **SYD** therefore both take an additional *period* argument naming which period to report. + +## Sign conventions and units + +Two conventions span the entire module. First, **cash flows carry a sign**: money paid *out* (mortgage payments, deposits to savings, investment outlays) is represented by a negative number, and money received (loan proceeds, savings withdrawals, dividends) by a positive number. The same convention applies whether the value appears as a single argument (*pmt*, *pv*, *fv*) or as an element of a cash flow array — entering a payment as a positive number is the most common cause of an unexpected result. + +Second, **rates and counts must share a time unit**. If *nper* is given in months, *rate* must be the monthly rate (typically the annual rate divided by twelve); if *nper* is given in years, *rate* must be the annual rate. The same applies to depreciation: the *life* of the asset and the *period* being queried must be expressed in the same units. + +## Members + +- [DDB](DDB) -- depreciation of an asset for a specified period via the double-declining balance method +- [FV](FV) -- future value of an annuity based on periodic fixed payments and a fixed interest rate +- [IPmt](IPmt) -- interest payment for a given period of an annuity +- [IRR](IRR) -- internal rate of return for a series of periodic cash flows +- [MIRR](MIRR) -- modified internal rate of return for a series of periodic cash flows +- [NPer](NPer) -- number of periods for an annuity based on periodic fixed payments and a fixed interest rate +- [NPV](NPV) -- net present value of an investment based on a series of periodic cash flows and a discount rate +- [Pmt](Pmt) -- payment for an annuity based on periodic fixed payments and a fixed interest rate +- [PPmt](PPmt) -- principal payment for a given period of an annuity +- [PV](PV) -- present value of an annuity based on periodic fixed payments and a fixed interest rate +- [Rate](Rate) -- interest rate per period for an annuity +- [SLN](SLN) -- straight-line depreciation of an asset for a single period +- [SYD](SYD) -- sum-of-years' digits depreciation of an asset for a specified period diff --git a/docs/Reference/Modules/Math/index.md b/docs/Reference/Modules/Math/index.md index 76e82ff..73d050d 100644 --- a/docs/Reference/Modules/Math/index.md +++ b/docs/Reference/Modules/Math/index.md @@ -7,14 +7,68 @@ has_toc: false # Math module +The **Math** module groups together the standard numeric functions — sign and magnitude, trigonometry, exponentials and logarithms, the square root, rounding to a chosen number of decimal places, and pseudo-random number generation. Most members return a **Double**, so intermediate results stay in floating point until they are written back to a narrower variable. + +## Sign and magnitude + +[**Abs**](Abs) returns the absolute value of its argument — its distance from zero, with the sign discarded — and preserves the argument's data type, so `Abs(-3#)` is a **Double** and `Abs(-3)` an **Integer**. [**Sgn**](Sgn) is the complement: it discards the magnitude and returns just the sign, as `-1`, `0`, or `+1`. Together they decompose a number into its sign and magnitude. + +```tb +Debug.Print Abs(-7.5) ' 7.5 +Debug.Print Sgn(-7.5) ' -1 +``` + +## Trigonometry + +[**Sin**](Sin), [**Cos**](Cos), and [**Tan**](Tan) take an angle in radians and return its sine, cosine, and tangent. [**Atn**](Atn) goes the other way — given a tangent, it returns the angle whose tangent that is, in the range `-pi/2` to `pi/2`. All four work exclusively in radians; multiply degrees by `pi / 180` to convert to radians, or radians by `180 / pi` to convert back. + +```tb +Const Pi As Double = 3.14159265358979 +Debug.Print Sin(Pi / 2) ' 1 +Debug.Print Atn(1) * 4 ' 3.14159265358979 — pi +``` + +The other inverse trigonometric functions (arcsine, arccosine) and the hyperbolic functions are not provided directly, but each can be derived from **Atn**, **Log**, **Exp**, and **Sqr** in a couple of lines — see the worked examples on [**Atn**](Atn), [**Log**](Log), and [**Cos**](Cos). + +## Exponentials and logarithms + +[**Exp**](Exp) raises *e* (≈ 2.71828) to a chosen power, and [**Log**](Log) is its inverse, returning the natural (base-*e*) logarithm. To compute a logarithm in another base, divide by **Log** of that base: `Log(x) / Log(10)` for base 10, `Log(x) / Log(2)` for base 2, and so on. + +```tb +Debug.Print Exp(1) ' 2.71828182845905 — e +Debug.Print Log(100) / Log(10) ' 2 — base-10 log of 100 +``` + +## Square root + +[**Sqr**](Sqr) returns the square root of a non-negative number as a **Double**. Passing a negative value raises a run-time error rather than returning a complex or **NaN** result; if a calculation may legitimately produce a negative input, guard the call with [**Sgn**](Sgn) or a comparison to zero. + +## Rounding + +[**Round**](Round) rounds a number to a chosen number of decimal places using *banker's rounding* — when the value lies exactly half-way between two possible results, it rounds toward the nearest **even** digit, so `Round(0.5, 0)` is `0` and `Round(1.5, 0)` is `2`. This avoids the systematic upward bias of always-round-half-up and matches VBA's behaviour. For *truncation* rather than rounding, see [**Int**](../Conversion/Int) and [**Fix**](../Conversion/Fix) in the [**Conversion**](../Conversion/) module; for narrowing-with-rounding to a specific integer type, see [**CInt**](../Conversion/CInt) and [**CLng**](../Conversion/CLng). + +## Random numbers + +[**Randomize**](Randomize) seeds the pseudo-random number generator, and [**Rnd**](Rnd) draws from it, returning a **Single** in the half-open range `[0, 1)`. Without an explicit call to **Randomize**, **Rnd** produces the same sequence every time the program runs — convenient for reproducible tests; for unpredictable output, call **Randomize** once at startup with no argument so the system timer is used as the seed. + +The standard idiom for a uniformly distributed integer between *lower* and *upper* (inclusive) combines **Rnd** with [**Int**](../Conversion/Int): + +```tb +Randomize +Dim Roll As Long +Roll = Int((6 - 1 + 1) * Rnd + 1) ' a die roll, 1..6 +``` + +## Members + - [Abs](Abs) -- returns the absolute value of a number -- [Atn](Atn) -- returns the arctangent of a number +- [Atn](Atn) -- returns the arctangent of a number, in radians - [Cos](Cos) -- returns the cosine of an angle -- [Exp](Exp) -- returns _e_ raised to a power -- [Log](Log) -- returns the natural (base _e_) logarithm of a number +- [Exp](Exp) -- returns *e* raised to a power +- [Log](Log) -- returns the natural (base-*e*) logarithm of a number - [Randomize](Randomize) -- initialises the random-number generator -- [Rnd](Rnd) -- returns a random number in the range [0.0, 1.0) -- [Round](Round) -- rounds a number to a given number of decimal places +- [Rnd](Rnd) -- returns a pseudo-random number in the range `[0, 1)` +- [Round](Round) -- rounds a number to a chosen number of decimal places, using banker's rounding - [Sgn](Sgn) -- returns the sign of a number - [Sin](Sin) -- returns the sine of an angle - [Sqr](Sqr) -- returns the square root of a number diff --git a/docs/Reference/Modules/Strings/index.md b/docs/Reference/Modules/Strings/index.md index 6e87aa8..79a4d82 100644 --- a/docs/Reference/Modules/Strings/index.md +++ b/docs/Reference/Modules/Strings/index.md @@ -7,44 +7,100 @@ has_toc: false # Strings module -Procedures that check properties of strings: +The **Strings** module groups together the runtime's text-processing primitives — measuring strings, looking inside them, building new ones from old ones, splitting and joining arrays of them, and formatting non-string values as text. Most members come in two callable forms: a `$`-suffixed form (e.g. **Left$**) that returns a **String**, and an unsuffixed form (e.g. **Left**) that returns a **Variant** (**String**) and propagates **Null** through the call. Several also have a `B` variant — **AscB**, **ChrB**, **InStrB**, **LeftB**, **LenB**, **MidB**, **RightB** — that operates on byte positions rather than character positions, for use with byte-buffer data held in a **String**. -* [Len](Len) -- returns the length of a string -* [Asc](Asc) -- returns the character code of the first letter in a string -* [StrComp](StrComp) -- compares two strings -* [InStr](InStr) -- returns the position of one string within another -* [InStrRev](InStrRev) -- returns the position of one string within another, searching from the end +## Length and character codes -Procedures that create strings: +[**Len**](Len) returns the number of characters in a string, or — when given a non-string variable — the number of bytes the variable occupies. [**Asc**](Asc) returns the character code of a string's first character; [**Chr**](Chr) is its inverse, building a single-character string from a code point. The `W` variants ([**AscW**](Asc), [**ChrW**](Chr)) work in Unicode regardless of the system code page. -- [Chr](Chr) -- returns the character having a given code -- [Space](Space) -- returns a string of spaces -- [String](String) -- returns a string of repeating characters +```tb +Debug.Print Len("Hello") ' 5 +Debug.Print Asc("A") ' 65 +Debug.Print Chr(65) ' "A" +``` -Procedures that return modified strings: +## Searching and comparing -- [Left](Left) -- returns a leftmost substring of a string -- [Mid](Mid) -- returns a substring of a string -- [Right](Right) -- returns a rightmost substring of a string +[**StrComp**](StrComp) compares two strings and returns -1, 0, or 1 to report which is greater (or equal). [**InStr**](InStr) and [**InStrRev**](InStrRev) return the position of one string inside another, scanning forward from a chosen start position or backward from one. All three accept an optional *compare* argument controlling whether the comparison is case-sensitive (**vbBinaryCompare**), case-insensitive (**vbTextCompare**), or governed by the surrounding [**Option Compare**](../../Core/Option) setting (**vbUseCompareOption**). Note that **InStrRev** swaps the order of the haystack and needle arguments relative to **InStr**. -- [LTrim](LTrim) -- removes leading spaces from a string -- [RTrim](RTrim) -- removes trailing spaces from a string -- [Trim](Trim) -- removes leading and trailing spaces from a string +```tb +Debug.Print InStr("Hello, world", "o") ' 5 (first match, forward) +Debug.Print InStrRev("Hello, world", "o") ' 9 (first match, reverse) +Debug.Print StrComp("ABC", "abc", vbTextCompare) ' 0 (equal under text compare) +``` -- [StrReverse](StrReverse) -- reverses the order of characters of a string -- [LCase](LCase) -- returns a string converted to lowercase -- [UCase](UCase) -- returns a string converted to uppercase +## Substrings, padding, and trimming -- [StrConv](StrConv) -- converts a string to a specified format -- [Join](Join) -- concatenates a string array using a given delimiter -- [Split](Split) -- splits a string into a string array -- [Replace](Replace) -- replaces substrings within a string -- [Filter](Filter) -- filters a string array into a subset according to criteria +[**Left**](Left), [**Mid**](Mid), and [**Right**](Right) extract a substring from the start, middle, or end of a string. **Mid** doubles as an l-value via the [**Mid =**](../../Core/Mid-equals) statement, which writes characters back into a string in place. [**Space**](Space) returns a run of spaces and [**String**](String) returns a run of any chosen character — both useful for padding fixed-width output. [**LTrim**](LTrim), [**RTrim**](RTrim), and [**Trim**](Trim) strip leading, trailing, or both kinds of whitespace from a string. + +```tb +Dim S As String +S = " Hello, world " +Debug.Print "[" & Trim(S) & "]" ' "[Hello, world]" +Debug.Print Left(Trim(S), 5) ' "Hello" +Debug.Print String(3, "*") & " " & Space(2) & "!" ' "*** !" +``` + +## Case folding and other transformations + +[**LCase**](LCase) and [**UCase**](UCase) fold a string to lowercase or uppercase. [**StrReverse**](StrReverse) reverses the character order. [**StrConv**](StrConv) bundles a wider set of conversions — case folding, proper-casing, narrow/wide and Hiragana/Katakana mapping for DBCS locales, and Unicode-to-ANSI byte-array round-tripping — selected by an additive flag argument. + +```tb +Debug.Print UCase("Hello") ' "HELLO" +Debug.Print StrReverse("Hello") ' "olleH" +Debug.Print StrConv("hello world", vbProperCase) ' "Hello World" +``` + +## Splitting, joining, replacing, filtering + +[**Split**](Split) breaks a string apart at a delimiter into a zero-based array of substrings; [**Join**](Join) reverses the operation, gluing an array back together with a chosen separator between elements. [**Replace**](Replace) substitutes one substring for another across a string, optionally limited to a fixed number of replacements or starting from a given offset. [**Filter**](Filter) reduces a string array to only those elements that contain — or, with *include* set to **False**, do not contain — a chosen substring. +```tb +Dim Parts() As String +Parts = Split("red,green,blue", ",") +Debug.Print Join(Parts, " / ") ' "red / green / blue" +Debug.Print Replace("red,green,blue", ",", "; ") ' "red; green; blue" +``` + +## Formatting values as text + +[**Format**](Format) is the general-purpose formatter: it takes any expression — number, date, or string — together with a named or user-defined format string, and returns the rendered text. The four named-formatter functions [**FormatCurrency**](FormatCurrency), [**FormatNumber**](FormatNumber), [**FormatPercent**](FormatPercent), and [**FormatDateTime**](FormatDateTime) wrap the most common cases with explicit parameters in place of a format string, so the call site reads as the intent rather than as a recipe. [**MonthName**](MonthName) and [**WeekdayName**](WeekdayName) return the localised name (or abbreviation) of a month or day of the week, given its numeric index. + +```tb +Debug.Print Format(1234.5, "#,##0.00") ' "1,234.50" +Debug.Print FormatCurrency(1234.5) ' "$1,234.50" (US locale) +Debug.Print FormatDateTime(Now, vbLongDate) ' "Saturday, May 9, 2026" +Debug.Print MonthName(1) ' "January" +``` + +## Members + +- [Asc](Asc) -- returns the character code of the first character in a string +- [Chr](Chr) -- returns the character associated with a character code +- [Filter](Filter) -- returns a subset of a string array matching (or not matching) a substring - [Format](Format) -- formats an expression according to a format expression - [FormatCurrency](FormatCurrency) -- formats an expression as a currency string - [FormatDateTime](FormatDateTime) -- formats an expression as a date/time string - [FormatNumber](FormatNumber) -- formats an expression as a numeric string - [FormatPercent](FormatPercent) -- formats an expression as a percent string +- [InStr](InStr) -- returns the position of one string within another +- [InStrRev](InStrRev) -- returns the position of one string within another, searching from the end +- [Join](Join) -- concatenates a string array using a given delimiter +- [LCase](LCase) -- returns a string converted to lowercase +- [Left](Left) -- returns a leftmost substring of a string +- [Len](Len) -- returns the length of a string, or the storage size of a variable +- [LTrim](LTrim) -- removes leading spaces from a string +- [Mid](Mid) -- returns a substring of a string - [MonthName](MonthName) -- returns the name of the specified month +- [Replace](Replace) -- replaces substrings within a string +- [Right](Right) -- returns a rightmost substring of a string +- [RTrim](RTrim) -- removes trailing spaces from a string +- [Space](Space) -- returns a string of spaces +- [Split](Split) -- splits a string into a string array on a delimiter +- [StrComp](StrComp) -- compares two strings +- [StrConv](StrConv) -- converts a string to a specified format +- [String](String) -- returns a string of repeating characters +- [StrReverse](StrReverse) -- reverses the order of characters of a string +- [Trim](Trim) -- removes leading and trailing spaces from a string +- [UCase](UCase) -- returns a string converted to uppercase - [WeekdayName](WeekdayName) -- returns the name of the specified day of the week diff --git a/docs/Reference/Modules/TextEncodingConstants/index.md b/docs/Reference/Modules/TextEncodingConstants/index.md new file mode 100644 index 0000000..0fc5ab2 --- /dev/null +++ b/docs/Reference/Modules/TextEncodingConstants/index.md @@ -0,0 +1,104 @@ +--- +title: TextEncodingConstants Module +parent: Modules +permalink: /tB/Modules/TextEncodingConstants/ +has_toc: false +--- + +# TextEncodingConstants module + +The `Open` statement supports Unicode through the use of a new `Encoding` keyword and variable, and allows you to specify a wide range of encoding options in addition to standard Unicode options. + +The **TextEncodingConstants** module provides the predefined identifier strings recognised by the **Encoding** clause of the **Open** statement: + +```tb +Open "C:\MyFile.txt" For Input Encoding utf_8 As #1 +``` + +The constants below name the well-known encodings; other system-supported encodings with similar identifier strings are also accepted at runtime. + +The members are marked **[Hidden, Restricted]** — they are omitted from general IntelliSense, but the IDE surfaces them specifically after the **Encoding** keyword. + +## Default and Unicode + +| Constant | Value | Description | +|----------|-------|-------------| +| **default_system_ansi**{: #default_system_ansi } | `"default"` | The system default ANSI code page. | +| **utf_7**{: #utf_7 } | `"utf-7"` | UTF-7. | +| **utf_7_bom**{: #utf_7_bom } | `"utf-7 bom"` | UTF-7 with byte-order mark. | +| **utf_8**{: #utf_8 } | `"utf-8"` | UTF-8. | +| **utf_8_bom**{: #utf_8_bom } | `"utf-8 bom"` | UTF-8 with byte-order mark. | +| **utf_16**{: #utf_16 } | `"utf-16"` | UTF-16 (little-endian). | +| **utf_16_bom**{: #utf_16_bom } | `"utf-16 bom"` | UTF-16 with byte-order mark. | +| **us_ascii**{: #us_ascii } | `"us-ascii"` | 7-bit US-ASCII. | + +## KOI8 (Cyrillic) + +| Constant | Value | Description | +|----------|-------|-------------| +| **koi8_r**{: #koi8_r } | `"koi8_r"` | KOI8-R, Russian. | +| **koi8_u**{: #koi8_u } | `"koi8_u"` | KOI8-U, Ukrainian. | + +## Big5 + +| Constant | Value | Description | +|----------|-------|-------------| +| **big5**{: #big5 } | `"big5"` | Big5, Traditional Chinese. | + +## ISO 8859 + +| Constant | Value | Description | +|----------|-------|-------------| +| **iso_8859_1_latin1**{: #iso_8859_1_latin1 } | `"iso-8859-1"` | Latin-1, Western European. | +| **iso_8859_2_latin2**{: #iso_8859_2_latin2 } | `"iso-8859-2"` | Latin-2, Central European. | +| **iso_8859_3_latin3**{: #iso_8859_3_latin3 } | `"iso-8859-3"` | Latin-3, South European (Esperanto, Maltese). | +| **iso_8859_4_latin4**{: #iso_8859_4_latin4 } | `"iso-8859-4"` | Latin-4, North European. | +| **iso_8859_5_cyrillic**{: #iso_8859_5_cyrillic } | `"iso-8859-5"` | Cyrillic. | +| **iso_8859_6_arabic**{: #iso_8859_6_arabic } | `"iso-8859-6"` | Arabic. | +| **iso_8859_7_greek**{: #iso_8859_7_greek } | `"iso-8859-7"` | Greek. | +| **iso_8859_8_hebrew**{: #iso_8859_8_hebrew } | `"iso-8859-8"` | Hebrew. | +| **iso_8859_9_latin5_turkish**{: #iso_8859_9_latin5_turkish } | `"iso-8859-9"` | Latin-5, Turkish. | +| **iso_8859_10_latin6_nordic**{: #iso_8859_10_latin6_nordic } | `"iso-8859-10"` | Latin-6, Nordic. | +| **iso_8859_11_thai**{: #iso_8859_11_thai } | `"iso-8859-11"` | Thai. | +| **iso_8859_13_latin8_baltic**{: #iso_8859_13_latin8_baltic } | `"iso-8859-13"` | Latin-7, Baltic Rim. | +| **iso_8859_14_latin8_celtic**{: #iso_8859_14_latin8_celtic } | `"iso-8859-14"` | Latin-8, Celtic. | +| **iso_8859_15_latin9_euro**{: #iso_8859_15_latin9_euro } | `"iso-8859-15"` | Latin-9, Western European with euro sign. | +| **iso_8859_16_latin10_balkan**{: #iso_8859_16_latin10_balkan } | `"iso-8859-16"` | Latin-10, South-Eastern European. | + +## Windows code pages + +| Constant | Value | Description | +|----------|-------|-------------| +| **windows_1250_central_europe**{: #windows_1250_central_europe } | `"windows-1250"` | Central European. | +| **windows_1251_cyrillic**{: #windows_1251_cyrillic } | `"windows-1251"` | Cyrillic. | +| **windows_1252_western**{: #windows_1252_western } | `"windows-1252"` | Western European. | +| **windows_1253_greek**{: #windows_1253_greek } | `"windows-1253"` | Greek. | +| **windows_1254_turkish**{: #windows_1254_turkish } | `"windows-1254"` | Turkish. | +| **windows_1255_hebrew**{: #windows_1255_hebrew } | `"windows-1255"` | Hebrew. | +| **windows_1256_arabic**{: #windows_1256_arabic } | `"windows-1256"` | Arabic. | +| **windows_1257_baltic**{: #windows_1257_baltic } | `"windows-1257"` | Baltic. | +| **windows_1258_vietnamese**{: #windows_1258_vietnamese } | `"windows-1258"` | Vietnamese. | + +## IBM/OEM code pages + +| Constant | Value | Description | +|----------|-------|-------------| +| **ibm_850_western_europe**{: #ibm_850_western_europe } | `"850"` | OEM Multilingual Latin-1, Western European. | +| **ibm_852_central_and_eastern_europe**{: #ibm_852_central_and_eastern_europe } | `"852"` | OEM Latin-2, Central and Eastern European. | +| **ibm_855_cyrillic**{: #ibm_855_cyrillic } | `"855"` | OEM Cyrillic (primarily pre-Unicode Russian). | +| **ibm_856_hebrew**{: #ibm_856_hebrew } | `"856"` | Hebrew. | +| **ibm_857_turkish**{: #ibm_857_turkish } | `"857"` | OEM Turkish (Latin-5). | +| **ibm_858_western_europe**{: #ibm_858_western_europe } | `"858"` | OEM Multilingual Latin-1 with euro sign. | +| **ibm_860_portuguese**{: #ibm_860_portuguese } | `"860"` | Portuguese. | +| **ibm_861_icelandic**{: #ibm_861_icelandic } | `"861"` | Icelandic. | +| **ibm_862_hebrew**{: #ibm_862_hebrew } | `"862"` | Hebrew. | +| **ibm_863_canadian**{: #ibm_863_canadian } | `"863"` | French Canadian. | +| **ibm_865_danish**{: #ibm_865_danish } | `"865"` | Nordic (Danish, Norwegian). | +| **ibm_866_cyrillic**{: #ibm_866_cyrillic } | `"866"` | Russian. | +| **ibm_869_greek**{: #ibm_869_greek } | `"869"` | Modern Greek. | +| **ibm_932_japanese**{: #ibm_932_japanese } | `"932"` | Japanese (Shift-JIS, Microsoft variant). | +| **ibm_949_korean**{: #ibm_949_korean } | `"949"` | Korean (Unified Hangul Code). | + +## See Also + +- [File I/O encoding options](../../../Features/Standard-Library/File-IO) diff --git a/docs/Reference/Modules/index.md b/docs/Reference/Modules/index.md index dca2b78..374f053 100644 --- a/docs/Reference/Modules/index.md +++ b/docs/Reference/Modules/index.md @@ -4,7 +4,6 @@ parent: Reference Section permalink: /tB/Modules --- -> [!WARNING] -> Work in Progress +# Core VBA Modules -# Core Modules +These modules are in the VBA built-in package. diff --git a/docs/Reference/Modules/todo.md b/docs/Reference/Modules/todo.md index 95dfbf3..28d7742 100644 --- a/docs/Reference/Modules/todo.md +++ b/docs/Reference/Modules/todo.md @@ -2,7 +2,6 @@ title: General TODO List for /tB/Modules/ nav_exclude: true redirect_from: - - /tB/Modules/TextEncodingConstants - /tB/Modules/AmbientProperties - /tB/Modules/AsyncProperty - /tB/Modules/ContainedControls