diff --git a/docs/Reference/Categories.md b/docs/Reference/Categories.md index e332ee2..300ad8f 100644 --- a/docs/Reference/Categories.md +++ b/docs/Reference/Categories.md @@ -45,6 +45,13 @@ Statements: * [On ... GoTo](../tB/Core/On-GoTo), [On ... GoSub](../tB/Core/On-GoSub) - transfer execution to a location selected by an expression * [Stop](../tB/Core/Stop) - interrupt execution +Inline conditional functions — expression-level alternatives to the **If...Then...Else** and **Select Case** statements above: + +* [If](../tB/Modules/Interaction/If) - evaluate an expression and return one of two values; only the chosen branch is evaluated (twinBASIC addition) +* [IIf](../tB/Modules/Interaction/IIf) - evaluate an expression and return one of two values; both branches are always evaluated +* [Choose](../tB/Modules/Interaction/Choose) - return one value from a list, selected by 1-based index +* [Switch](../tB/Modules/Interaction/Switch) - return the value paired with the first **True** condition in a list of (condition, value) pairs + See also: * [End](../tB/Core/End) - terminate execution. @@ -132,24 +139,57 @@ Procedures: Procedures: * [Load](../tB/Core/Load), [Unload](../tB/Core/Unload) - load/unload a form or control into memory -* [GetSetting](../tB/Core/GetSetting), [SaveSetting](../tB/Core/SaveSetting) - retrieve/store a string value from/to the system registry -* [DeleteSetting](../tB/Core/DeleteSetting) - remove value from the system registry +* [GetSetting](../tB/Modules/Interaction/GetSetting), [SaveSetting](../tB/Modules/Interaction/SaveSetting) - retrieve/store a string value from/to the system registry +* [GetAllSettings](../tB/Modules/Interaction/GetAllSettings) - retrieve every key/value pair in a section of an application's registry entry +* [DeleteSetting](../tB/Modules/Interaction/DeleteSetting) - remove value from the system registry -## Events and Interaction +## Events Statements: * [RaiseEvent](../tB/Core/RaiseEvent) - raise an event that may be handled by event handlers +Procedures: + +* [RaiseEventByName](../tB/Modules/Interaction/RaiseEventByName) - raise an event by name on an object, taking arguments as a **Variant** array +* [RaiseEventByName2](../tB/Modules/Interaction/RaiseEventByName2) - raise an event by name on an object, taking a variable-length argument list + See also * [Event](../tB/Core/Event) - declare an event +## User Dialogs + +Procedures: + +* [MsgBox](../tB/Modules/Interaction/MsgBox) - display a modal message dialog and return the button the user clicked +* [InputBox](../tB/Modules/Interaction/InputBox) - prompt the user for a line of text and return what was entered +* [Beep](../tB/Modules/Interaction/Beep) - sound a system beep + +## Process Control + +Procedures: + +* [Shell](../tB/Modules/Interaction/Shell) - run another program asynchronously and return its task ID +* [AppActivate](../tB/Modules/Interaction/AppActivate) - change the focus to, or activate, a named window +* [SendKeys](../tB/Modules/Interaction/SendKeys) - send keystrokes to the active window +* [DoEvents](../tB/Modules/Interaction/DoEvents) - yield control to the message loop so pending events can be processed + +## COM and Automation + +Procedures: + +* [CreateObject](../tB/Modules/Interaction/CreateObject) - create a new instance of a COM/Automation object +* [GetObject](../tB/Modules/Interaction/GetObject) - obtain a reference to an Automation object loaded from a file or already running +* [CallByName](../tB/Modules/Interaction/CallByName) - invoke a method or property on an object dynamically by name +* [CallByDispId](../tB/Modules/Interaction/CallByDispId) - invoke a method or property on an object dynamically by IDispatch dispatch ID (twinBASIC addition) + +## Command Line and Environment + Procedures: -* [AppActivate](../tB/Core/AppActivate) - change the focus to, or activate, a named window -* [Beep](../tB/Core/Beep) - sound a system beep -* [SendKeys](../tB/Core/SendKeys) - send keystrokes to the active window +* [Command$, Command](../tB/Modules/Interaction/Command) - return the command-line arguments passed to the program +* [Environ$, Environ](../tB/Modules/Interaction/Environ) - return the value of a process environment variable ## Colours @@ -174,6 +214,7 @@ Procedures: * [Round](../tB/Modules/Math/Round) - round the number to a given number of decimal places * [Rnd](../tB/Modules/Math/Rnd) - generate a random number in the range [0.0, 1.0) * [Randomize](../tB/Modules/Math/Randomize) - seed the random number generator +* [Partition](../tB/Modules/Interaction/Partition) - return a string label identifying which of a series of equal-width numeric ranges a value falls into (histogram-style bucketing) See also: diff --git a/docs/Reference/Core/todo.md b/docs/Reference/Core/todo.md index 5192a01..ea9a668 100644 --- a/docs/Reference/Core/todo.md +++ b/docs/Reference/Core/todo.md @@ -42,7 +42,6 @@ redirect_from: - /tB/Core/RSet - /tB/Core/SavePicture - /tB/Core/Select-Case - - /tB/Core/SendKeys - /tB/Core/Set - /tB/Core/Static - /tB/Core/Sub diff --git a/docs/Reference/Modules/Interaction/CallByDispId.md b/docs/Reference/Modules/Interaction/CallByDispId.md new file mode 100644 index 0000000..3d449e7 --- /dev/null +++ b/docs/Reference/Modules/Interaction/CallByDispId.md @@ -0,0 +1,43 @@ +--- +title: CallByDispId +parent: Interaction Module +permalink: /tB/Modules/Interaction/CallByDispId +--- +# CallByDispId +{: .no_toc } + +Calls a method, or reads or writes a property, on an object — looked up by raw IDispatch dispatch ID at run time. **CallByDispId** is a twinBASIC addition; the by-name variant, [**CallByName**](CallByName), exists in VBA as well. + +Syntax: **CallByDispId(** *object* **,** *dispid* **,** *calltype* [ **,** *args* ... ] **)** + +*object* +: *required* **Object**. The object whose member is to be invoked. + +*dispid* +: *required* **Long**. The IDispatch dispatch ID (`DISPID`) of the method or property to invoke. + +*calltype* +: *required* A [**VbCallType**](../Constants/VbCallType) value indicating the kind of member: `vbMethod`, `vbGet`, `vbLet`, or `vbSet`. + +*args* +: *optional* The arguments to pass to the method, **Property Get**, **Property Let**, or **Property Set**. + +The return value is a **Variant** containing whatever the call returned. For methods that return nothing, or for property assignments, the result is **Empty**. + +**CallByDispId** skips the name lookup that [**CallByName**](CallByName) performs, which is useful in two situations: when you already know the dispatch ID and want to avoid the cost of a `GetIDsOfNames` round trip, and when the target member is not exposed by name (e.g. a default member with `DISPID_VALUE = 0`, an explicit-DISPID extension, or a hidden/restricted member). + +### Example + +This example invokes the default member of an object — `DISPID_VALUE`, defined as 0 — by dispatch ID. + +```tb +Const DISPID_VALUE As Long = 0 + +Dim Result As Variant +Result = CallByDispId(SomeObject, DISPID_VALUE, vbGet) +``` + +### See Also + +- [CallByName](CallByName) function +- [VbCallType](../Constants/VbCallType) enumeration diff --git a/docs/Reference/Modules/Interaction/CallByName.md b/docs/Reference/Modules/Interaction/CallByName.md new file mode 100644 index 0000000..3f0feb3 --- /dev/null +++ b/docs/Reference/Modules/Interaction/CallByName.md @@ -0,0 +1,44 @@ +--- +title: CallByName +parent: Interaction Module +permalink: /tB/Modules/Interaction/CallByName +redirect_from: +- /tB/Core/CallByName +--- +# CallByName +{: .no_toc } + +Calls a method, or reads or writes a property, on an object — looked up by name at run time. + +Syntax: **CallByName(** *object* **,** *procname* **,** *calltype* [ **,** *args* ... ] **)** + +*object* +: *required* **Object**. The object whose member is to be invoked. + +*procname* +: *required* **String**. The name of the method or property to invoke on *object*. + +*calltype* +: *required* A [**VbCallType**](../Constants/VbCallType) value indicating the kind of member: `vbMethod`, `vbGet`, `vbLet`, or `vbSet`. + +*args* +: *optional* The arguments to pass to the method, **Property Get**, **Property Let**, or **Property Set**. + +The return value is a **Variant** containing whatever the call returned. For methods that return nothing, or for property assignments, the result is **Empty**. + +### Example + +These three calls drive a control by name. The first sets its **MousePointer** property to the crosshair cursor, the second reads the same property back out, and the third invokes the **Move** method to reposition the control. + +```tb +CallByName Text1, "MousePointer", vbLet, vbCrosshair +Result = CallByName(Text1, "MousePointer", vbGet) +CallByName Text1, "Move", vbMethod, 100, 100 +``` + +### See Also + +- [CallByDispId](CallByDispId) function +- [VbCallType](../Constants/VbCallType) enumeration + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Choose.md b/docs/Reference/Modules/Interaction/Choose.md new file mode 100644 index 0000000..c6b29e4 --- /dev/null +++ b/docs/Reference/Modules/Interaction/Choose.md @@ -0,0 +1,42 @@ +--- +title: Choose +parent: Interaction Module +permalink: /tB/Modules/Interaction/Choose +redirect_from: +- /tB/Core/Choose +--- +# Choose +{: .no_toc } + +Selects and returns a value from a list of arguments by 1-based index. + +Syntax: **Choose(** *index* **,** *choice-1* [ **,** *choice-2* **, ...** [ **,** *choice-n* ] ] **)** + +*index* +: *required* Numeric expression that evaluates to a value between 1 and the number of available choices. + +*choice* +: *required* **Variant** expression containing one of the possible choices. + +If *index* is 1, **Choose** returns *choice-1*; if *index* is 2, it returns *choice-2*; and so on. If *index* is less than 1 or greater than the number of choices listed, **Choose** returns **Null**. Non-integer values of *index* are rounded to the nearest whole number before being evaluated. + +> [!NOTE] +> **Choose** evaluates *every* choice in the list, not only the one it returns. Watch for side effects: a [**MsgBox**](MsgBox) call inside any of the choices is invoked once per choice, not just for the selected one. To avoid this — for example, when one of the branches would error out — use the short-circuiting [**If**](If) function instead. + +### Example + +This example uses **Choose** to map a 1-based option index to a name. + +```tb +Function GetChoice(Ind As Integer) As String + GetChoice = Choose(Ind, "Speedy", "United", "Federal") +End Function +``` + +### See Also + +- [If](If) function +- [IIf](IIf) function +- [Switch](Switch) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Command.md b/docs/Reference/Modules/Interaction/Command.md new file mode 100644 index 0000000..1ae937e --- /dev/null +++ b/docs/Reference/Modules/Interaction/Command.md @@ -0,0 +1,64 @@ +--- +title: Command +parent: Interaction Module +permalink: /tB/Modules/Interaction/Command +redirect_from: +- /tB/Core/Command +--- +# Command, Command$ +{: .no_toc } + +Returns the argument portion of the command line used to launch the program. + +Syntax: + +- **Command$()** +- **Command()** + +The `$`-suffixed form returns a **String**; the unsuffixed form returns a **Variant** (**String**). + +For applications compiled to an executable, **Command** returns any arguments that appear after the name of the application on the command line. For example, with the command line: + +``` +MyApp /switch arg1 arg2 +``` + +**Command** returns `"/switch arg1 arg2"`. + +### Example + +This example uses **Command** to retrieve the command-line arguments and split them into an array. + +```tb +Function GetCommandLine(Optional MaxArgs As Variant) As Variant + Dim Ch As String, CmdLine As String, CmdLnLen As Long + Dim InArg As Boolean, I As Long, NumArgs As Long + + If IsMissing(MaxArgs) Then MaxArgs = 10 + ReDim ArgArray(MaxArgs) + + NumArgs = 0 + InArg = False + CmdLine = Command() + CmdLnLen = Len(CmdLine) + + For I = 1 To CmdLnLen + Ch = Mid(CmdLine, I, 1) + If Ch <> " " And Ch <> vbTab Then + If Not InArg Then + If NumArgs = MaxArgs Then Exit For + NumArgs = NumArgs + 1 + InArg = True + End If + ArgArray(NumArgs) = ArgArray(NumArgs) & Ch + Else + InArg = False + End If + Next I + + ReDim Preserve ArgArray(NumArgs) + GetCommandLine = ArgArray() +End Function +``` + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/CreateObject.md b/docs/Reference/Modules/Interaction/CreateObject.md new file mode 100644 index 0000000..b89692d --- /dev/null +++ b/docs/Reference/Modules/Interaction/CreateObject.md @@ -0,0 +1,51 @@ +--- +title: CreateObject +parent: Interaction Module +permalink: /tB/Modules/Interaction/CreateObject +redirect_from: +- /tB/Core/CreateObject +--- +# CreateObject +{: .no_toc } + +Creates and returns a reference to a new instance of a COM/Automation object. + +Syntax: **CreateObject(** *class* [ **,** *servername* ] **)** + +*class* +: *required* **Variant** (**String**). The application name and class of the object to create, in the form *appname*.*objecttype* — for example, `"Excel.Application"`. A CLSID may also be supplied in the form `"new:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"`. + +*servername* +: *optional* **Variant** (**String**). The name of the network server on which to create the object — the same as the *Machine Name* portion of a UNC share name. For a share named `\\MyServer\Public`, *servername* is `"MyServer"`. If *servername* is omitted or supplied as a zero-length string (`""`), the object is created on the local machine. + +To use the returned object, assign it to an object variable. Declaring the variable `As Object` causes late binding (binding occurs at run time); declaring it with a specific class type produces early binding (binding occurs at compile time), which is faster and gives access to IntelliSense for the object's members but limits the variable to that one type. + +```tb +Dim ExcelApp As Object +Set ExcelApp = CreateObject("Excel.Application") +ExcelApp.Visible = True +``` + +If a remote *servername* is supplied but the remote machine doesn't exist or is unreachable, a run-time error occurs. If an object has registered itself as single-instance, only one instance is ever created, no matter how many times **CreateObject** is invoked. + +> [!NOTE] +> Use **CreateObject** when you want a new instance of the object. To attach to an *already-running* instance — or to start the object's application with a particular file loaded — use [**GetObject**](GetObject) instead. + +### Example + +This example creates a Microsoft Excel **Application** object, makes it visible, and then closes it via **Quit**, releasing the reference at the end. + +```tb +Dim XlApp As Object +Set XlApp = CreateObject("Excel.Application") +XlApp.Visible = True +' ... drive Excel through XlApp ... +XlApp.Quit +Set XlApp = Nothing +``` + +### See Also + +- [GetObject](GetObject) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/DoEvents.md b/docs/Reference/Modules/Interaction/DoEvents.md new file mode 100644 index 0000000..d0aa77a --- /dev/null +++ b/docs/Reference/Modules/Interaction/DoEvents.md @@ -0,0 +1,41 @@ +--- +title: DoEvents +parent: Interaction Module +permalink: /tB/Modules/Interaction/DoEvents +redirect_from: +- /tB/Core/DoEvents +--- +# DoEvents +{: .no_toc } + +Yields execution so the operating system can dispatch pending window messages and other events. + +Syntax: **DoEvents()** + +Returns an **Integer** indicating the number of open forms in the application; returns 0 in hosts that do not maintain a forms collection. + +**DoEvents** passes control to the operating system. Control is returned to the caller after the operating system has finished processing the events in its queue and after any keystrokes pending in the [**SendKeys**](SendKeys) queue have been delivered. + +**DoEvents** is most useful for simple things like keeping a UI responsive during a tight loop, or letting the user cancel a long-running operation. For genuinely long-running work, prefer a timer or a background worker (e.g. an out-of-process ActiveX EXE) so the operating system handles the multitasking. + +> [!NOTE] +> Whenever you yield the processor inside an event procedure, make sure that procedure cannot be re-entered from a different code path before the original call returns; otherwise the program may behave unpredictably. Likewise, avoid **DoEvents** when other applications might interact with your procedure in unforeseen ways during the time you have yielded control. + +### Example + +This example yields to the operating system once every 1000 iterations of a loop. + +```tb +Dim I As Long, OpenForms As Long +For I = 1 To 150000 + If I Mod 1000 = 0 Then + OpenForms = DoEvents() + End If +Next I +``` + +### See Also + +- [SendKeys](SendKeys) statement + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Environ.md b/docs/Reference/Modules/Interaction/Environ.md new file mode 100644 index 0000000..7481f51 --- /dev/null +++ b/docs/Reference/Modules/Interaction/Environ.md @@ -0,0 +1,53 @@ +--- +title: Environ +parent: Interaction Module +permalink: /tB/Modules/Interaction/Environ +redirect_from: +- /tB/Core/Environ +--- +# Environ, Environ$ +{: .no_toc } + +Returns the value associated with an operating-system environment variable, looked up either by name or by 1-based position in the environment-string table. + +Syntax: + +- **Environ$(** *envstring* **)**, **Environ(** *envstring* **)** +- **Environ$(** *number* **)**, **Environ(** *number* **)** + +*envstring* +: *required* String expression containing the name of an environment variable. + +*number* +: *required* Numeric expression giving the 1-based position of an entry in the process environment-string table. *number* may be any numeric expression and is rounded to a whole number before being evaluated. + +The `$`-suffixed forms return a **String**; the unsuffixed forms return a **Variant** (**String**). + +When called with *envstring*, **Environ** returns the value assigned to that environment variable — that is, the text following the equal sign (`=`) in the environment-string table for that variable. If *envstring* can't be found in the table, a zero-length string (`""`) is returned. + +When called with *number*, **Environ** returns the entire entry at that position, including the variable name, the equal sign, and the value (e.g. `"PATH=C:\Windows;C:\Windows\System32"`). If there is no entry at that position, a zero-length string is returned. + +### Example + +This example walks the environment-string table to find the entry number and the value length for `PATH`. + +```tb +Dim EnvString As String, Indx As Long, PathLen As Long +Indx = 1 +Do + EnvString = Environ(Indx) + If Left(EnvString, 5) = "PATH=" Then + PathLen = Len(Environ("PATH")) + Debug.Print "PATH entry = " & Indx & " and length = " & PathLen + Exit Do + Else + Indx = Indx + 1 + End If +Loop Until EnvString = "" + +If PathLen = 0 Then + Debug.Print "No PATH environment variable exists." +End If +``` + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/GetAllSettings.md b/docs/Reference/Modules/Interaction/GetAllSettings.md new file mode 100644 index 0000000..9b151f0 --- /dev/null +++ b/docs/Reference/Modules/Interaction/GetAllSettings.md @@ -0,0 +1,51 @@ +--- +title: GetAllSettings +parent: Interaction Module +permalink: /tB/Modules/Interaction/GetAllSettings +redirect_from: +- /tB/Core/GetAllSettings +--- +# GetAllSettings +{: .no_toc } + +Returns every key and its value in a section of an application's entry in the Windows registry. + +Syntax: **GetAllSettings(** *appname* **,** *section* **)** + +*appname* +: *required* String expression containing the name of the application or project whose key settings are requested. + +*section* +: *required* String expression containing the name of the section whose key settings are requested. + +Returns a **Variant** whose contents are a two-dimensional array of strings: each row holds one key and its value, in columns 0 and 1 respectively. **GetAllSettings** returns an uninitialized **Variant** if either *appname* or *section* does not exist. + +The root of these registry settings is: `Computer\HKEY_CURRENT_USER\Software\VB and VBA Program Settings`. + +### Example + +This example first uses [**SaveSetting**](SaveSetting) to make entries in the Windows registry for the application, then uses **GetAllSettings** to display every key/value in a section, and finally uses [**DeleteSetting**](DeleteSetting) to remove the application's entries. Note that the *appname* and *section* names themselves are not retrieved. + +```tb +' Place some settings in the registry. +SaveSetting AppName := "MyApp", Section := "Startup", _ + Key := "Top", Setting := "75" +SaveSetting "MyApp", "Startup", "Left", "50" + +' Retrieve them. +Dim MySettings As Variant, IntSettings As Long +MySettings = GetAllSettings(AppName := "MyApp", Section := "Startup") +For IntSettings = LBound(MySettings, 1) To UBound(MySettings, 1) + Debug.Print MySettings(IntSettings, 0), MySettings(IntSettings, 1) +Next IntSettings + +DeleteSetting "MyApp", "Startup" +``` + +### See Also + +- [DeleteSetting](DeleteSetting) statement +- [GetSetting](GetSetting) function +- [SaveSetting](SaveSetting) statement + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/GetObject.md b/docs/Reference/Modules/Interaction/GetObject.md new file mode 100644 index 0000000..d940db4 --- /dev/null +++ b/docs/Reference/Modules/Interaction/GetObject.md @@ -0,0 +1,77 @@ +--- +title: GetObject +parent: Interaction Module +permalink: /tB/Modules/Interaction/GetObject +redirect_from: +- /tB/Core/GetObject +--- +# GetObject +{: .no_toc } + +Returns a reference to a COM/Automation object — either an already-running instance, or one bound to a file. + +Syntax: **GetObject(** [ *pathname* ] [ **,** *class* ] **)** + +*pathname* +: *optional* **Variant** (**String**). The full path and name of a file containing the object to retrieve. If *pathname* is omitted, *class* is required. + +*class* +: *optional* **Variant** (**String**). The class of the object to retrieve, in the form *appname*.*objecttype* — for example, `"Excel.Application"`. + +To assign the returned reference to a variable, use **Set**: + +```tb +Dim CADObject As Object +Set CADObject = GetObject("C:\CAD\SCHEMA.CAD") +``` + +When the call is made with a *pathname*, the application registered for that file is started (if it isn't already running), and the object inside the file is activated. + +If *pathname* is a zero-length string (`""`), **GetObject** returns a *new* instance of the type named by *class*. If *pathname* is omitted altogether, **GetObject** attempts to attach to a *currently running* instance of the type named by *class*; if no such instance exists, a run-time error occurs. + +Some applications support activating a *part* of a file. Append `!` and an application-specific identifier to the file name — for example, the third layer of a CAD drawing: + +```tb +Set LayerObject = GetObject("C:\CAD\SCHEMA.CAD!Layer3") +``` + +If you don't specify *class*, the operating system determines the application to start and the object to activate based on the file name you provide. Some files, however, may support more than one class of object. To be specific, supply both arguments: + +```tb +Dim MyObject As Object +Set MyObject = GetObject("C:\Drawings\Sample.drw", "Figment.Drawing") +``` + +> [!NOTE] +> Use **GetObject** when there is already a current instance of the object, or when you want to create the object with a file already loaded. If there is no current instance and you don't want the object started with a file loaded, use [**CreateObject**](CreateObject) instead. + +For an object registered as single-instance, **GetObject** with the zero-length-string syntax always returns the same instance, and the form with *pathname* omitted causes an error. + +### Example + +This example uses **GetObject** to attach to a Microsoft Excel **Worksheet** opened from a file. The first call (without *pathname*) tries to attach to a running Excel; the second call opens the file. If Excel was not already running when the script started, it is closed at the end via **Application.Quit**. + +```tb +Dim MyXl As Object +Dim ExcelWasNotRunning As Boolean + +On Error Resume Next +Set MyXl = GetObject(, "Excel.Application") +If Err.Number <> 0 Then ExcelWasNotRunning = True +Err.Clear +On Error GoTo 0 + +Set MyXl = GetObject("C:\Reports\MyTest.xls") +MyXl.Application.Visible = True +MyXl.Parent.Windows(1).Visible = True +' ... drive the workbook through MyXl ... + +If ExcelWasNotRunning Then MyXl.Application.Quit +Set MyXl = Nothing +``` + +### See Also + +- [CreateObject](CreateObject) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/IIf.md b/docs/Reference/Modules/Interaction/IIf.md new file mode 100644 index 0000000..f4f4d7c --- /dev/null +++ b/docs/Reference/Modules/Interaction/IIf.md @@ -0,0 +1,43 @@ +--- +title: IIf +parent: Interaction Module +permalink: /tB/Modules/Interaction/IIf +redirect_from: +- /tB/Core/IIf +--- +# IIf +{: .no_toc } + +Returns one of two values, depending on the evaluation of an expression. + +Syntax: **IIf(** *expr* **,** *truepart* **,** *falsepart* **)** + +*expr* +: *required* Expression to evaluate. + +*truepart* +: *required* Value or expression returned if *expr* is **True**. + +*falsepart* +: *required* Value or expression returned if *expr* is **False**. + +> [!NOTE] +> **IIf** always evaluates both *truepart* and *falsepart*, even though it returns only one of them. Watch for side effects: if the unused branch would raise an error (for example, division by zero), the error still occurs. Use the short-circuiting [**If**](If) function — a twinBASIC addition — when you need to guard against errors in the unused branch. + +### Example + +This example uses **IIf** to return the word "Large" if the amount is greater than 1000, and "Small" otherwise. + +```tb +Function CheckIt(TestMe As Integer) As String + CheckIt = IIf(TestMe > 1000, "Large", "Small") +End Function +``` + +### See Also + +- [If](If) function +- [Choose](Choose) function +- [Switch](Switch) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/If.md b/docs/Reference/Modules/Interaction/If.md new file mode 100644 index 0000000..a6bdc93 --- /dev/null +++ b/docs/Reference/Modules/Interaction/If.md @@ -0,0 +1,58 @@ +--- +title: If +parent: Interaction Module +permalink: /tB/Modules/Interaction/If +redirect_from: +- /tB/Core/If +--- +# If +{: .no_toc } + +Returns one of two values depending on a condition, evaluating only the branch it returns. **If** is a twinBASIC addition; in VBA, the closest equivalent is [**IIf**](IIf), which always evaluates both branches. + +Syntax: + +- **If(** *expression* **,** *truepart* **,** *falsepart* **)** +- **If(** *expressiontruepart* **,** *falsepart* **)** + +*expression* +: *required* Expression evaluated for its truth value. May be any expression that converts to **Boolean**. + +*truepart* +: *required* Value or expression returned when *expression* is **True**. In the three-argument form this is evaluated only when *expression* is **True**. + +*falsepart* +: *required* Value or expression returned when *expression* is **False**, or when *expressiontruepart* is **Null**, **Empty**, or **Nothing**. Evaluated only when actually needed. + +*expressiontruepart* +: *required* (in the two-argument form) Expression that serves as both the test and the value to return when it is "set". The function returns *expressiontruepart* unless it is **Null**, **Empty**, or a **Nothing** object reference, in which case it returns *falsepart*. Useful for null-coalescing — for example, `If(MaybeNothing, FallbackValue)`. + +The three-argument form is the inline conditional: it returns *truepart* when *expression* is **True**, *falsepart* otherwise, and only the chosen branch is evaluated. This makes expressions such as `If(Divisor <> 0, 100 / Divisor, "n/a")` safe even when *Divisor* is zero. + +> [!NOTE] +> **If** uses special internal bindings in the compiler and may not behave exactly like a regular function — in particular, `Application.Run "If", ...` and other reflective callers will not invoke it. + +### Example + +```tb +Dim Divisor As Long +Divisor = 0 + +' Three-argument form — short-circuits, so the division never happens when Divisor = 0. +Dim Result As Variant +Result = If(Divisor <> 0, 100 / Divisor, "n/a") ' "n/a" + +' Two-argument form — null-coalescing. +Dim MaybeName As Variant +MaybeName = Null +Debug.Print If(MaybeName, "Anonymous") ' "Anonymous" + +MaybeName = "Alice" +Debug.Print If(MaybeName, "Anonymous") ' "Alice" +``` + +### See Also + +- [IIf](IIf) function +- [Choose](Choose) function +- [Switch](Switch) function diff --git a/docs/Reference/Modules/Interaction/InputBox.md b/docs/Reference/Modules/Interaction/InputBox.md new file mode 100644 index 0000000..0bcae33 --- /dev/null +++ b/docs/Reference/Modules/Interaction/InputBox.md @@ -0,0 +1,81 @@ +--- +title: InputBox +parent: Interaction Module +permalink: /tB/Modules/Interaction/InputBox +redirect_from: +- /tB/Core/InputBox +--- +# InputBox +{: .no_toc } + +Displays a prompt in a dialog, waits for the user to type text or click a button, and returns a **String** containing the contents of the text box. + +Syntax: **InputBox(** *prompt* [ **,** *title* ] [ **,** *default* ] [ **,** *xpos* ] [ **,** *ypos* ] [ **,** *helpfile* **,** *context* ] **)** + +*prompt* +: *required* String expression displayed as the message in the dialog box. The maximum length of *prompt* is approximately 1024 characters, depending on the width of the characters used. To break *prompt* across multiple lines, separate the lines with a carriage return (`Chr(13)`), a linefeed (`Chr(10)`), or a CR-LF combination (`vbCrLf`). + +*title* +: *optional* String expression displayed in the title bar of the dialog box. If omitted, the application name is used. + +*default* +: *optional* String expression displayed in the text box as the initial response. If omitted, the text box is displayed empty. + +*xpos* +: *optional* Numeric expression specifying, in twips, the horizontal distance of the left edge of the dialog from the left edge of the screen. If omitted, the dialog is horizontally centered. + +*ypos* +: *optional* Numeric expression specifying, in twips, the vertical distance of the top edge of the dialog from the top of the screen. If omitted, the dialog is positioned approximately one-third of the way down the screen. + +*helpfile* +: *optional* String expression that identifies the Help file to use to provide context-sensitive Help for the dialog box. If *helpfile* is supplied, *context* must also be supplied. + +*context* +: *optional* Numeric expression giving the Help context number assigned to the relevant Help topic. If *context* is supplied, *helpfile* must also be supplied. + +If the user clicks **OK** or presses ENTER, **InputBox** returns whatever is in the text box. If the user clicks **Cancel**, the function returns a zero-length string (`""`). + +> [!NOTE] +> A zero-length return value alone cannot distinguish "user cancelled" from "user submitted an empty string". To tell them apart, capture the result in a **Variant** and test the underlying **BSTR** pointer with **StrPtr**: a cancelled dialog returns a null pointer, while an empty submitted string returns a pointer to an allocated zero-length **BSTR**. +> +> ```tb +> Dim Reply As Variant +> Reply = InputBox("Enter your name:") +> If StrPtr(Reply) = 0 Then +> ' User cancelled. +> ElseIf Reply = "" Then +> ' User submitted an empty string. +> Else +> ' User entered: Reply. +> End If +> ``` + +The text box accepts at most 255 characters; the returned string is truncated to 254 characters. The text box does not accept line breaks (e.g. SHIFT+ENTER); pasted text containing a line break is truncated at the break. + +When both *helpfile* and *context* are supplied, the user can press F1 to view the relevant Help topic. + +### Example + +This example shows several ways of calling **InputBox**. If *xpos* and *ypos* are omitted the dialog is centered on its respective axis. The variable `MyValue` ends up containing whatever the user typed when **OK** or ENTER was pressed, or a zero-length string when **Cancel** was pressed. + +```tb +Dim Message As String, Title As String, Default As String, MyValue As String +Message = "Enter a value between 1 and 3" +Title = "InputBox Demo" +Default = "1" + +' Display message, title, and default value. +MyValue = InputBox(Message, Title, Default) + +' Use a Help file and context. The Help button is added automatically. +MyValue = InputBox(Message, Title, , , , "DEMO.HLP", 10) + +' Display the dialog at screen position (100, 100). +MyValue = InputBox(Message, Title, Default, 100, 100) +``` + +### See Also + +- [MsgBox](MsgBox) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/MsgBox.md b/docs/Reference/Modules/Interaction/MsgBox.md new file mode 100644 index 0000000..c00b0cd --- /dev/null +++ b/docs/Reference/Modules/Interaction/MsgBox.md @@ -0,0 +1,63 @@ +--- +title: MsgBox +parent: Interaction Module +permalink: /tB/Modules/Interaction/MsgBox +redirect_from: +- /tB/Core/MsgBox +--- +# MsgBox +{: .no_toc } + +Displays a message in a modal dialog with a chosen set of buttons, waits for the user to click a button, and returns a [**VbMsgBoxResult**](../Constants/VbMsgBoxResult) value identifying that button. + +Syntax: **MsgBox(** *prompt* [ **,** *buttons* ] [ **,** *title* ] [ **,** *helpfile* **,** *context* ] **)** + +*prompt* +: *required* String expression displayed as the message in the dialog box. The maximum length of *prompt* is approximately 1024 characters, depending on the width of the characters used. To break *prompt* across multiple lines, separate the lines with a carriage return (`Chr(13)`), a linefeed (`Chr(10)`), or a CR-LF combination (`vbCrLf`). + +*buttons* +: *optional* A [**VbMsgBoxStyle**](../Constants/VbMsgBoxStyle) value that specifies the number and type of buttons to display, the icon style, the identity of the default button, and the modality of the message box. If omitted, *buttons* defaults to `vbOKOnly`. + +*title* +: *optional* String expression displayed in the title bar of the dialog box. If omitted, the application name is used. + +*helpfile* +: *optional* String expression that identifies the Help file to use to provide context-sensitive Help for the dialog box. If *helpfile* is supplied, *context* must also be supplied. + +*context* +: *optional* Numeric expression giving the Help context number assigned to the relevant Help topic. If *context* is supplied, *helpfile* must also be supplied. + +The *buttons* argument is a combination of values from the [**VbMsgBoxStyle**](../Constants/VbMsgBoxStyle) enumeration: one *button group* value (`vbOKOnly`, `vbOKCancel`, `vbAbortRetryIgnore`, `vbYesNoCancel`, `vbYesNo`, `vbRetryCancel`, `vbCancelTryAgainContinue`), optionally combined with one *icon* value (`vbCritical`, `vbQuestion`, `vbExclamation`, `vbInformation`), one *default-button* value (`vbDefaultButton1` through `vbDefaultButton4`), one *modality* value (`vbApplicationModal`, `vbSystemModal`), and any of the option flags (`vbMsgBoxHelpButton`, `vbMsgBoxSetForeground`, `vbMsgBoxRight`, `vbMsgBoxRtlReading`). Combine values with **Or** or addition. + +The return value is one of the constants from the [**VbMsgBoxResult**](../Constants/VbMsgBoxResult) enumeration, identifying which button the user clicked. + +If the dialog box displays a **Cancel** button, pressing the ESC key has the same effect as clicking **Cancel**. When both *helpfile* and *context* are supplied, the user can press F1 to view the relevant Help topic; if the dialog also contains a **Help** button, clicking it invokes context-sensitive Help. The dialog stays open and **MsgBox** does not return until one of the non-Help buttons is clicked. + +> [!NOTE] +> To pass any argument by name (other than the first), use **MsgBox** in an expression context — for example, assign its result to a variable. To skip a positional argument, include the corresponding comma delimiter. + +### Example + +This example displays a critical-error message in a dialog with **Yes** and **No** buttons; the **No** button is the default. The value returned by **MsgBox** depends on the button the user clicks. + +```tb +Dim Style As VbMsgBoxStyle +Dim Response As VbMsgBoxResult + +Style = vbYesNo Or vbCritical Or vbDefaultButton2 +Response = MsgBox("Do you want to continue?", Style, "MsgBox Demonstration") + +If Response = vbYes Then + ' User chose Yes — perform the action. +Else + ' User chose No — back out. +End If +``` + +### See Also + +- [InputBox](InputBox) function +- [VbMsgBoxStyle](../Constants/VbMsgBoxStyle) enumeration +- [VbMsgBoxResult](../Constants/VbMsgBoxResult) enumeration + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Partition.md b/docs/Reference/Modules/Interaction/Partition.md new file mode 100644 index 0000000..a2a2c7b --- /dev/null +++ b/docs/Reference/Modules/Interaction/Partition.md @@ -0,0 +1,56 @@ +--- +title: Partition +parent: Interaction Module +permalink: /tB/Modules/Interaction/Partition +redirect_from: +- /tB/Core/Partition +--- +# Partition +{: .no_toc } + +Returns a **Variant** (**String**) labelling which of a series of equal-width numeric ranges a value falls into. + +Syntax: **Partition(** *number* **,** *start* **,** *stop* **,** *interval* **)** + +*number* +: *required* The value to evaluate against the ranges. + +*start* +: *required* The number that begins the overall range. May not be less than 0. + +*stop* +: *required* The number that ends the overall range. May not be less than or equal to *start*. + +*interval* +: *required* The width of each individual range. May not be less than 1. + +The return value identifies the particular range in which *number* falls, formatted as `": "`. **Partition** is most useful in queries — for example, an SQL `SELECT` that groups orders by freight-cost band. + +The following table shows how the ranges are determined for three sample sets of *start*, *stop*, and *interval*. The *Before First* column is what **Partition** returns for a *number* below *start*; the *After Last* column is what it returns for a *number* above *stop*. + +| *start* | *stop* | *interval* | Before First | First Range | Last Range | After Last | +|--------:|-------:|-----------:|:-------------|:------------|:-----------|:-----------| +| 0 | 99 | 5 | `" :-1"` | `" 0: 4"` | `" 95: 99"`| `" 100: "` | +| 20 | 199 | 10 | `" : 19"` | `" 20: 29"`| `" 190:199"`| `" 200: "` | +| 100 | 1010 | 20 | `" : 99"` | `" 100: 119"`| `"1000:1010"`| `"1011: "` | + +In the third row, *start* and *stop* don't divide evenly by *interval*: the last range extends to *stop* (covering 11 numbers) even though *interval* is 20. + +If necessary, **Partition** pads each end of the range with leading spaces so that there are the same number of characters to the left and right of the colon as there are characters in *stop*, plus one. This keeps the labels in the right order under a plain text sort. + +If *interval* is 1, the range collapses to *number:number*, regardless of *start* and *stop*. + +Any argument may be a decimal value, but is rounded to the nearest even integer before processing. If any argument is **Null**, **Partition** returns **Null**. + +### Example + +This example uses **Partition** in an SQL `SELECT` to count the orders whose freight cost falls into each of several ranges. With *start* = 0, *stop* = 500, *interval* = 50, the first range is `" 0: 49"`, and so on up to 500. + +```sql +SELECT DISTINCTROW Partition([Freight], 0, 500, 50) AS Range, + Count(Orders.Freight) AS [Count] +FROM Orders +GROUP BY Partition([Freight], 0, 500, 50); +``` + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/RaiseEventByName.md b/docs/Reference/Modules/Interaction/RaiseEventByName.md new file mode 100644 index 0000000..5cc3d86 --- /dev/null +++ b/docs/Reference/Modules/Interaction/RaiseEventByName.md @@ -0,0 +1,40 @@ +--- +title: RaiseEventByName +parent: Interaction Module +permalink: /tB/Modules/Interaction/RaiseEventByName +--- +# RaiseEventByName +{: .no_toc } + +Raises an event by name on an object, with the event arguments supplied as a **Variant** array. **RaiseEventByName** is a twinBASIC addition; the equivalent at compile time is the **RaiseEvent** statement, which requires the event name to be known when the code is written. + +Syntax: **RaiseEventByName(** *object* **,** *procname* [ **,** *argsarray* ] **)** + +*object* +: *required* **Object**. The object on which to raise the event. The object must declare a public event with the matching *procname* and an arity matching the number of items in *argsarray*. + +*procname* +: *required* **String**. The name of the event to raise. + +*argsarray* +: *optional* **Variant**. A one-dimensional array containing the arguments to pass to the event handler(s), in declaration order. Pass an uninitialized **Variant** for an event that takes no parameters. + +Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler — useful only when the event has a `ByRef` "out" or "cancel" parameter. + +> [!NOTE] +> The variable-length-argument variant of this function — [**RaiseEventByName2**](RaiseEventByName2) — accepts arguments directly via **ParamArray**, which is usually more readable when the event signature is fixed. Use **RaiseEventByName** when the argument list is itself constructed dynamically. + +If *procname* doesn't match any event declared on *object*, or the supplied arity doesn't match the event declaration, a run-time error occurs. + +### Example + +```tb +Dim Args(0) As Variant +Args(0) = "Some argument value" +RaiseEventByName MyControl, "ValueChanged", Args +``` + +### See Also + +- [RaiseEventByName2](RaiseEventByName2) function +- [CallByName](CallByName) function diff --git a/docs/Reference/Modules/Interaction/RaiseEventByName2.md b/docs/Reference/Modules/Interaction/RaiseEventByName2.md new file mode 100644 index 0000000..09ec9b1 --- /dev/null +++ b/docs/Reference/Modules/Interaction/RaiseEventByName2.md @@ -0,0 +1,38 @@ +--- +title: RaiseEventByName2 +parent: Interaction Module +permalink: /tB/Modules/Interaction/RaiseEventByName2 +--- +# RaiseEventByName2 +{: .no_toc } + +Raises an event by name on an object, with the event arguments supplied as a variable-length argument list. **RaiseEventByName2** is a twinBASIC addition; the equivalent at compile time is the **RaiseEvent** statement, which requires the event name to be known when the code is written. + +Syntax: **RaiseEventByName2(** *object* **,** *procname* [ **,** *arg1* **,** *arg2* **, ...** ] **)** + +*object* +: *required* **Object**. The object on which to raise the event. The object must declare a public event with the matching *procname* and an arity matching the number of arguments supplied. + +*procname* +: *required* **String**. The name of the event to raise. + +*arg1*, *arg2*, ... +: *optional* **ParamArray** of **Variant**. The arguments to pass to the event handler(s), in declaration order. + +Returns a **Variant**. The returned value is the value left in the last `ByRef` event argument by the handler — useful only when the event has a `ByRef` "out" or "cancel" parameter. + +> [!NOTE] +> The array-based variant of this function — [**RaiseEventByName**](RaiseEventByName) — takes the argument list as a single packed **Variant** array, which is more convenient when the argument list is itself constructed dynamically. Use **RaiseEventByName2** when the argument list is fixed at the call site. + +If *procname* doesn't match any event declared on *object*, or the supplied arity doesn't match the event declaration, a run-time error occurs. + +### Example + +```tb +RaiseEventByName2 MyControl, "ValueChanged", "First argument", 123, True +``` + +### See Also + +- [RaiseEventByName](RaiseEventByName) function +- [CallByName](CallByName) function diff --git a/docs/Reference/Modules/Interaction/SendKeys.md b/docs/Reference/Modules/Interaction/SendKeys.md new file mode 100644 index 0000000..32e011c --- /dev/null +++ b/docs/Reference/Modules/Interaction/SendKeys.md @@ -0,0 +1,88 @@ +--- +title: SendKeys +parent: Interaction Module +permalink: /tB/Modules/Interaction/SendKeys +redirect_from: +- /tB/Core/SendKeys +--- +# SendKeys +{: .no_toc } + +Sends one or more keystrokes to the active window as if typed at the keyboard. + +Syntax: **SendKeys** *string* [ **,** *wait* ] + +*string* +: *required* String expression specifying the keystrokes to send. + +*wait* +: *optional* **Boolean** specifying the wait mode. If **False** (default), control is returned to the procedure as soon as the keys have been queued. If **True**, the keystrokes must be processed by the receiving window before control returns. + +Each key is represented by one or more characters. To specify a single keyboard character, use the character itself — for example, `"A"` for the letter A, or `"ABC"` for A, B, then C in sequence. + +The plus sign (`+`), caret (`^`), percent sign (`%`), tilde (`~`), and parentheses `( )` have special meanings to **SendKeys**. To send one of these characters as itself, enclose it in braces: for example, `"{+}"` for the plus sign. Brackets `[ ]` have no special meaning to **SendKeys** itself, but you must enclose them in braces because other applications may treat them specially during dynamic data exchange (DDE). To send brace characters, use `{% raw %}"{{}"{% endraw %}` and `"{% raw %}{}}{% endraw %}"`. + +To send keys that don't correspond to a printable character, use the codes in the following table: + +| Key | Code | +|:--|:--| +| BACKSPACE | `{BACKSPACE}`, `{BS}`, or `{BKSP}` | +| BREAK | `{BREAK}` | +| CAPS LOCK | `{CAPSLOCK}` | +| DEL or DELETE | `{DELETE}` or `{DEL}` | +| DOWN ARROW | `{DOWN}` | +| END | `{END}` | +| ENTER | `{ENTER}` or `~` | +| ESC | `{ESC}` | +| HELP | `{HELP}` | +| HOME | `{HOME}` | +| INS or INSERT | `{INSERT}` or `{INS}` | +| LEFT ARROW | `{LEFT}` | +| NUM LOCK | `{NUMLOCK}` | +| PAGE DOWN | `{PGDN}` | +| PAGE UP | `{PGUP}` | +| PRINT SCREEN | `{PRTSC}` | +| RIGHT ARROW | `{RIGHT}` | +| SCROLL LOCK | `{SCROLLLOCK}` | +| TAB | `{TAB}` | +| UP ARROW | `{UP}` | +| F1–F16 | `{F1}` … `{F16}` | + +To combine a key with SHIFT, CTRL, or ALT, prefix the key code with one or more of the following modifier codes: + +| Key | Code | +|:--|:--| +| SHIFT | `+` | +| CTRL | `^` | +| ALT | `%` | + +To hold one or more modifiers down while a sequence of keys is pressed, enclose the keys in parentheses. For example, `"+(EC)"` holds SHIFT down while E and C are pressed. + +To repeat a key, use the form `{key number}` — for example, `"{LEFT 42}"` to press LEFT 42 times, or `"{h 10}"` to type `h` ten times. The space between *key* and *number* is required. + +> [!NOTE] +> **SendKeys** can't send keystrokes to applications that aren't running in Windows, and it cannot send the PRINT SCREEN key (`{PRTSC}`) to any application. + +### Example + +This example uses [**Shell**](Shell) to launch the Windows Calculator and **SendKeys** to drive it: it adds the numbers 1 through 100, takes the running total, then closes Calculator with ALT+F4. Because [**AppActivate**](AppActivate) changes the focus, the example must be run, not single-stepped. + +```tb +Dim TaskId As Double, I As Long +TaskId = Shell("CALC.EXE", vbNormalFocus) +AppActivate TaskId + +For I = 1 To 100 + SendKeys I & "{+}", True +Next I + +SendKeys "=", True +SendKeys "%{F4}", True +``` + +### See Also + +- [AppActivate](AppActivate) statement +- [Shell](Shell) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Shell.md b/docs/Reference/Modules/Interaction/Shell.md new file mode 100644 index 0000000..a8d39de --- /dev/null +++ b/docs/Reference/Modules/Interaction/Shell.md @@ -0,0 +1,41 @@ +--- +title: Shell +parent: Interaction Module +permalink: /tB/Modules/Interaction/Shell +redirect_from: +- /tB/Core/Shell +--- +# Shell +{: .no_toc } + +Runs an executable program asynchronously and returns a **Double** containing the new process's task ID, or zero if the program could not be started. + +Syntax: **Shell(** *pathname* [ **,** *windowstyle* ] **)** + +*pathname* +: *required* **Variant** (**String**). Name of the program to execute, optionally including a directory or drive, plus any required arguments or command-line switches. + +*windowstyle* +: *optional* A [**VbAppWinStyle**](../Constants/VbAppWinStyle) value specifying the style of window in which the program is run. If omitted, the program is started minimized with focus (`vbMinimizedFocus`). + +If **Shell** successfully launches the named program, it returns the new process's task ID — a unique number identifying the running program. If **Shell** can't start the named program, a run-time error is raised. + +> [!NOTE] +> By default, **Shell** runs other programs *asynchronously*: a program started with **Shell** may not have finished — or even fully started — by the time the statements following **Shell** are executed. To wait for the program to finish, hold on to the returned task ID and poll the process by way of the Win32 `OpenProcess`/`WaitForSingleObject` APIs (or use a higher-level helper). + +### Example + +This example uses **Shell** to run Notepad with a normal-sized focused window. + +```tb +Dim TaskId As Double +TaskId = Shell("C:\Windows\Notepad.exe", vbNormalFocus) +``` + +### See Also + +- [AppActivate](AppActivate) statement +- [SendKeys](SendKeys) statement +- [VbAppWinStyle](../Constants/VbAppWinStyle) enumeration + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/Switch.md b/docs/Reference/Modules/Interaction/Switch.md new file mode 100644 index 0000000..3826f09 --- /dev/null +++ b/docs/Reference/Modules/Interaction/Switch.md @@ -0,0 +1,46 @@ +--- +title: Switch +parent: Interaction Module +permalink: /tB/Modules/Interaction/Switch +redirect_from: +- /tB/Core/Switch +--- +# Switch +{: .no_toc } + +Evaluates a list of *(condition, value)* pairs and returns the value paired with the first condition that evaluates to **True**. + +Syntax: **Switch(** *expr-1* **,** *value-1* [ **,** *expr-2* **,** *value-2* **, ...** [ **,** *expr-n* **,** *value-n* ] ] **)** + +*expr* +: *required* **Variant** expression to evaluate. + +*value* +: *required* Value or expression to be returned if the corresponding *expr* is **True**. + +The argument list consists of pairs of conditions and values. Conditions are evaluated from left to right, and the value associated with the first condition that evaluates to **True** is returned. If the parts aren't properly paired (i.e. an odd number of arguments is supplied) a run-time error occurs. + +**Switch** returns **Null** if none of the conditions is **True**, or if the first **True** condition has a corresponding *value* of **Null**. + +> [!NOTE] +> **Switch** evaluates *every* condition expression and *every* value, not only the ones it ends up using. Watch for side effects: if any of the value expressions would raise an error (for example, division by zero), the error occurs even when **Switch** would not have returned that value. + +### Example + +This example uses **Switch** to return the language associated with a city name. + +```tb +Function MatchUp(CityName As String) As Variant + MatchUp = Switch(CityName = "London", "English", _ + CityName = "Rome", "Italian", _ + CityName = "Paris", "French") +End Function +``` + +### See Also + +- [Choose](Choose) function +- [If](If) function +- [IIf](IIf) function + +{% include VBA-Attribution.md %} diff --git a/docs/Reference/Modules/Interaction/index.md b/docs/Reference/Modules/Interaction/index.md index 344b151..2075ddb 100644 --- a/docs/Reference/Modules/Interaction/index.md +++ b/docs/Reference/Modules/Interaction/index.md @@ -7,14 +7,83 @@ has_toc: false # Interaction module +The **Interaction** module groups together standalone procedures for everything that happens at the edges of a program — talking to the user, branching on a value, launching another process, reading the environment or the registry, and creating, calling into, or raising events on COM objects. + +## Asking the user something + +[**MsgBox**](MsgBox) shows a modal dialog with a message, an icon, and a chosen set of buttons; it returns a [**VbMsgBoxResult**](../Constants/VbMsgBoxResult) value identifying the button that was clicked. [**InputBox**](InputBox) shows a similar dialog with a text-entry field and returns the string the user typed (or an empty string if the user cancels). [**Beep**](Beep) sounds the system alert tone — useful as an audible cue when a long-running operation finishes. + +```tb +Dim Answer As VbMsgBoxResult +Answer = MsgBox("Save changes before closing?", vbYesNoCancel + vbQuestion, "Confirm") +``` + +## Choosing a value + +The module offers four ways to pick one of several values inline: + +- [**If**](If) is the short-circuiting inline conditional — a twinBASIC addition. Only the branch matching the condition is evaluated, so `If(Divisor <> 0, 100 / Divisor, "n/a")` is safe even when *Divisor* is zero. +- [**IIf**](IIf) is the historical VBA inline conditional. Both *truepart* and *falsepart* are always evaluated, so it cannot guard against errors in the unused branch. +- [**Choose**](Choose) returns the *index*-th item from a list of values — a one-based equivalent of array indexing for a fixed-length argument list. +- [**Switch**](Switch) walks pairs of *(condition, value)* arguments and returns the value paired with the first **True** condition — a compact stand-in for an **If...ElseIf** ladder. + +```tb +Dim Status As Variant +Status = Switch(Age < 13, "Child", _ + Age < 20, "Teenager", _ + Age < 65, "Adult", _ + True, "Senior") +``` + +[**Partition**](Partition) is a related utility: it returns a printable label identifying which of a series of equal-width numeric ranges a value falls into. + +## Launching and steering other processes + +[**Shell**](Shell) starts another program asynchronously and returns the new process's task ID; [**AppActivate**](AppActivate) brings an already-running application's window to the foreground, by title or by task ID. [**SendKeys**](SendKeys) feeds keystrokes to whichever window currently has focus, and [**DoEvents**](DoEvents) yields control back to the message loop so paint, input, and timer events can be dispatched in the middle of a long computation. + +## The environment and the command line + +[**Command$**](Command) and [**Command**](Command) return the command-line arguments passed to the program when it was started. [**Environ$**](Environ) and [**Environ**](Environ) return the value of a process environment variable, looked up either by name or by 1-based index in the environment block. + +## Per-user application settings + +The registry-setting helpers read and write per-user values under `HKEY_CURRENT_USER\Software\VB and VBA Program Settings`, mirroring the storage convention used by VB6. [**SaveSetting**](SaveSetting) writes a single key, [**GetSetting**](GetSetting) reads it back (with an optional default for missing keys), [**GetAllSettings**](GetAllSettings) returns every key-value pair in a section as a two-column **Variant** array, and [**DeleteSetting**](DeleteSetting) removes a key, an entire section, or every setting belonging to an application. + +```tb +SaveSetting "MyApp", "Window", "Maximised", "True" +Debug.Print GetSetting("MyApp", "Window", "Maximised", "False") ' "True" +DeleteSetting "MyApp", "Window", "Maximised" +``` + +## COM objects and dynamic dispatch + +[**CreateObject**](CreateObject) instantiates a new COM/Automation object given its ProgID or CLSID — optionally on a remote machine when a *servername* is supplied. [**GetObject**](GetObject) is the dual: it either binds to a file (loading the application that owns it) or attaches to an already-running instance of an object class. + +Once an object reference is in hand, [**CallByName**](CallByName) and [**CallByDispId**](CallByDispId) invoke a method or property on it dynamically, when the member to call is only known at run time — by name in the first case, or by raw IDispatch dispatch ID in the second. [**RaiseEventByName**](RaiseEventByName) and [**RaiseEventByName2**](RaiseEventByName2) raise an event on an object by event-name string — the run-time equivalent of the **RaiseEvent** statement, useful when the event being raised isn't known at compile time. The two forms differ only in how the event arguments are supplied: as a packed **Variant** array, or as a variable-length argument list. + +## Members + - [AppActivate](AppActivate) -- activates an application window - [Beep](Beep) -- sounds a tone through the computer's speaker +- [CallByDispId](CallByDispId) -- invokes a method or property on an object dynamically by IDispatch dispatch ID +- [CallByName](CallByName) -- invokes a method or property on an object dynamically by name +- [Choose](Choose) -- returns one value from a list, selected by 1-based index +- [Command$, Command](Command) -- returns the command-line arguments passed to the program +- [CreateObject](CreateObject) -- creates a new instance of a COM/Automation object - [DeleteSetting](DeleteSetting) -- deletes a section or key setting from an application's entry in the Windows registry +- [DoEvents](DoEvents) -- yields control to the message loop so pending events can be processed +- [Environ$, Environ](Environ) -- returns the value of a process environment variable +- [GetAllSettings](GetAllSettings) -- returns every key/value pair in a section of an application's registry entry +- [GetObject](GetObject) -- returns a reference to an Automation object loaded from a file or already running - [GetSetting](GetSetting) -- returns a key setting value from an application's entry in the Windows registry -- [SaveSetting](SaveSetting) -- saves or creates an application entry in the application's entry in the Windows registry - -> [!WARNING] -> Work in Progress Below - -- [SendKeys](SendKeys) -- [Shell](Shell) +- [If](If) -- evaluates an expression and returns one of two values, with short-circuit evaluation +- [IIf](IIf) -- evaluates an expression and returns one of two values; both branches are always evaluated +- [InputBox](InputBox) -- prompts the user for a line of text and returns what was entered +- [MsgBox](MsgBox) -- displays a modal message dialog and returns the button the user clicked +- [Partition](Partition) -- returns a string identifying the range a number falls into +- [RaiseEventByName](RaiseEventByName) -- raises an event by name on an object, taking arguments as a **Variant** array +- [RaiseEventByName2](RaiseEventByName2) -- raises an event by name on an object, taking a variable-length argument list +- [SaveSetting](SaveSetting) -- saves or creates a key setting in an application's entry in the Windows registry +- [SendKeys](SendKeys) -- sends keystrokes to the active window +- [Shell](Shell) -- runs another program asynchronously and returns its task ID +- [Switch](Switch) -- returns the value paired with the first **True** condition in a list of (condition, value) pairs diff --git a/docs/Reference/Modules/todo.md b/docs/Reference/Modules/todo.md index 1a922cc..cca7cee 100644 --- a/docs/Reference/Modules/todo.md +++ b/docs/Reference/Modules/todo.md @@ -2,10 +2,6 @@ title: General TODO List for /tB/Modules/ nav_exclude: true redirect_from: - - /tB/Core/Shell - - /tB/Core/SendKeys - - /tB/Modules/Interaction/Shell - - /tB/Modules/Interaction/SendKeys - /tB/Modules/TextEncodingConstants - /tB/Modules/_HiddenModule - /tB/Modules/AmbientProperties diff --git a/docs/Reference/Procedures and Functions.md b/docs/Reference/Procedures and Functions.md index 09fa36b..7171ca9 100644 --- a/docs/Reference/Procedures and Functions.md +++ b/docs/Reference/Procedures and Functions.md @@ -13,17 +13,19 @@ permalink: /Reference/Procedures-and-Functions ## A - [Abs](../tB/Modules/Math/Abs) -- returns the absolute value of a number -- [AppActivate](../tB/Core/AppActivate) -- activates an application window +- [AppActivate](../tB/Modules/Interaction/AppActivate) -- activates an application window - [Asc, AscB, AscW](../tB/Modules/Strings/Asc) -- returns the character code of the first letter in a string - [Atn](../tB/Modules/Math/Atn) -- returns the arctangent of a number ## B -- [Beep](../tB/Core/Beep) -- sounds a tone through the computer’s speaker +- [Beep](../tB/Modules/Interaction/Beep) -- sounds a tone through the computer’s speaker ## C - [Calendar](../tB/Modules/DateTime/Calendar) -- returns or sets the calendar type (Gregorian or Hijri) +- [CallByDispId](../tB/Modules/Interaction/CallByDispId) -- invokes a method or property on an object dynamically by IDispatch dispatch ID +- [CallByName](../tB/Modules/Interaction/CallByName) -- invokes a method or property on an object dynamically by name - [CBool](../tB/Modules/Conversion/CBool) -- coerces an expression to a **Boolean** - [CByte](../tB/Modules/Conversion/CByte) -- coerces an expression to a **Byte** - [CCur](../tB/Modules/Conversion/CCur) -- coerces an expression to a **Currency** @@ -33,13 +35,16 @@ permalink: /Reference/Procedures-and-Functions - [ChDir](../tB/Core/ChDir) -- changes the current directory or folder - [ChDrive](../tB/Core/ChDrive) -- changes the current drive - [CurDir](../tB/Core/CurDir) -- returns the current path +- [Choose](../tB/Modules/Interaction/Choose) -- returns one value from a list, selected by 1-based index - [Chr$, Chr, ChrB$, ChrB, ChrW$, ChrW](../tB/Modules/Strings/Chr) -- returns the character associated with a given character code - [CInt](../tB/Modules/Conversion/CInt) -- coerces an expression to an **Integer** - [CLng](../tB/Modules/Conversion/CLng) -- coerces an expression to a **Long** - [CLngLng](../tB/Modules/Conversion/CLngLng) -- coerces an expression to a **LongLong** - [CLngPtr](../tB/Modules/Conversion/CLngPtr) -- coerces an expression to a **LongPtr** +- [Command$, Command](../tB/Modules/Interaction/Command) -- returns the command-line arguments passed to the program - [CompilerVersion](../tB/Modules/Compilation/CompilerVersion) -- returns the twinBASIC compiler version number - [Cos](../tB/Modules/Math/Cos) -- returns the cosine of an angle +- [CreateObject](../tB/Modules/Interaction/CreateObject) -- creates a new instance of a COM/Automation object - [CSng](../tB/Modules/Conversion/CSng) -- coerces an expression to a **Single** - [CStr](../tB/Modules/Conversion/CStr) -- coerces an expression to a **String** - [CType](../tB/Modules/Conversion/CType) -- generic type conversion supporting the **CType(Of *type*)** cast operator @@ -62,11 +67,13 @@ permalink: /Reference/Procedures-and-Functions - [DateValue](../tB/Modules/DateTime/DateValue) -- converts a string to a date - [Day](../tB/Modules/DateTime/Day) -- returns the day of the month from a date value - [DDB](../tB/Modules/Financial/DDB) -- returns the depreciation of an asset via the double-declining balance method -- [DeleteSetting](../tB/Core/DeleteSetting) -- deletes a section or key setting from an application’s entry in the Windows registry +- [DeleteSetting](../tB/Modules/Interaction/DeleteSetting) -- deletes a section or key setting from an application’s entry in the Windows registry - [Dir](../tB/Core/Dir) -- returns the name of a file, directory, folder, or volume label that matches a pattern +- [DoEvents](../tB/Modules/Interaction/DoEvents) -- yields control to the message loop so pending events can be processed ## E +- [Environ$, Environ](../tB/Modules/Interaction/Environ) -- returns the value of a process environment variable - [EOF](../tB/Modules/FileSystem/EOF) -- returns whether the end of a file has been reached - [Erl](../tB/Modules/Information/Erl) -- returns the line number where the most recent run-time error occurred - [Err](../tB/Modules/Information/Err) -- returns the **ErrObject** describing the current run-time error state @@ -91,8 +98,10 @@ permalink: /Reference/Procedures-and-Functions ## G +- [GetAllSettings](../tB/Modules/Interaction/GetAllSettings) -- returns every key/value pair in a section of an application's registry entry - [GetAttr](../tB/Modules/FileSystem/GetAttr) -- returns the attributes of a file or directory -- [GetSetting](../tB/Core/GetSetting) -- returns a string key setting value from an application’s entry in the Windows registry +- [GetObject](../tB/Modules/Interaction/GetObject) -- returns a reference to an Automation object loaded from a file or already running +- [GetSetting](../tB/Modules/Interaction/GetSetting) -- returns a string key setting value from an application’s entry in the Windows registry ## H @@ -101,7 +110,10 @@ permalink: /Reference/Procedures-and-Functions ## I +- [If](../tB/Modules/Interaction/If) -- evaluates an expression and returns one of two values, with short-circuit evaluation +- [IIf](../tB/Modules/Interaction/IIf) -- evaluates an expression and returns one of two values; both branches are always evaluated - [IMEStatus](../tB/Modules/Information/IMEStatus) -- returns the status of the Input Method Editor +- [InputBox](../tB/Modules/Interaction/InputBox) -- prompts the user for a line of text and returns what was entered - [InStr$, InStrB, InStr](../tB/Modules/Strings/InStr) -- returns the position of one string within another - [InStrRev](../tB/Modules/Strings/InStrRev) -- returns the position of one string within another, searching from the end - [Int](../tB/Modules/Conversion/Int) -- returns the integer portion of a number, rounding toward negative infinity @@ -146,6 +158,7 @@ permalink: /Reference/Procedures-and-Functions - [MkDir](../tB/Core/MkDir) -- creates a new directory or folder - [Month](../tB/Modules/DateTime/Month) -- returns the month of the year from a date value - [MonthName](../tB/Modules/Strings/MonthName) -- returns the name of the specified month +- [MsgBox](../tB/Modules/Interaction/MsgBox) -- displays a modal message dialog and returns the button the user clicked ## N @@ -161,6 +174,7 @@ permalink: /Reference/Procedures-and-Functions ## P +- [Partition](../tB/Modules/Interaction/Partition) -- returns a string identifying the range a number falls into - [Pmt](../tB/Modules/Financial/Pmt) -- returns the payment for an annuity based on periodic fixed payments and a fixed interest rate - [PPmt](../tB/Modules/Financial/PPmt) -- returns the principal payment for a given period of an annuity - [ProcessorArchitecture](../tB/Modules/Compilation/ProcessorArchitecture) -- returns the processor architecture of the running application @@ -172,6 +186,8 @@ permalink: /Reference/Procedures-and-Functions ## R +- [RaiseEventByName](../tB/Modules/Interaction/RaiseEventByName) -- raises an event by name on an object, taking arguments as a **Variant** array +- [RaiseEventByName2](../tB/Modules/Interaction/RaiseEventByName2) -- raises an event by name on an object, taking a variable-length argument list - [Randomize](../tB/Modules/Math/Randomize) -- initializes the random-number generator - [Rate](../tB/Modules/Financial/Rate) -- returns the interest rate per period for an annuity - [Replace](../tB/Modules/Strings/Replace) -- replaces a substring within a string with another substring @@ -191,13 +207,13 @@ permalink: /Reference/Procedures-and-Functions ## S - SavePicture -- [SaveSetting](../tB/Core/SaveSetting) -- saves or creates an application entry in the application’s entry in the Windows registry +- [SaveSetting](../tB/Modules/Interaction/SaveSetting) -- saves or creates an application entry in the application’s entry in the Windows registry - [Second](../tB/Modules/DateTime/Second) -- returns the second of the minute from a time value - [Seek](../tB/Modules/FileSystem/Seek) -- returns or sets the read/write position within an open file -- [SendKeys](../tB/Core/SendKeys) +- [SendKeys](../tB/Modules/Interaction/SendKeys) -- sends keystrokes to the active window - [SetAttr](../tB/Modules/FileSystem/SetAttr) -- sets attribute information for a file - [Sgn](../tB/Modules/Math/Sgn) -- returns a value indicating the sign of a number -- [Shell](../tB/Core/Shell) +- [Shell](../tB/Modules/Interaction/Shell) -- runs another program asynchronously and returns its task ID - [Sin](../tB/Modules/Math/Sin) -- returns the sine of an angle - [SLN](../tB/Modules/Financial/SLN) -- returns the straight-line depreciation of an asset for a single period - [Space$, Space](../tB/Modules/Strings/Space) -- returns a string of spaces @@ -208,6 +224,7 @@ permalink: /Reference/Procedures-and-Functions - [StrConv](../tB/Modules/Strings/StrConv) -- converts a string to a specified format - [String$, String](../tB/Modules/Strings/String) -- returns a string of repeating characters - [StrReverse](../tB/Modules/Strings/StrReverse) -- reverses the order of characters in a string +- [Switch](../tB/Modules/Interaction/Switch) -- returns the value paired with the first **True** condition in a list of (condition, value) pairs - [SYD](../tB/Modules/Financial/SYD) -- returns the sum-of-years' digits depreciation of an asset for a specified period ## T