Questions similar to this appear on the Bentley Discussion Groups. These appeared in the VBA discussion group.
Q Configuration Variables (CfgVars)
A MicroStation configuration variables (CfgVars) are used to customise a workspace. They specify files, folders, and other settings specify to a workspace defined by a CAD administrator. There is more information about configuration variables here, and also in your MicroStation and MicroStation VBA help documentation.
Use the ConfigurationVariableValue
and the ExpandConfigurationValue
methods of the Workspace
object to get the value of a CfgVar.
ConfigurationVariableValue
obtains the value of a single variable;
by default, it evaluates its current value.
An argument to ConfigurationVariableValue
would be something like "MS_TAGOUTPUT".
ExpandConfigurationValue
obtains the value of a compound variable, by which we mean a variable that is defined in terms of other variables.
An argument to ExpandConfigurationValue
would be something like "$(_USTN_USER)$(_USTN_USERNAME).txt".
Let's take an example. The variable MS_DEF
specifies the default folder where MicroStation looks for DGN files.
It's value will be set to something like V:\Projects\Project1\DGN\models\
(that's just an example: your CAD
directory structure is likely to be quite different). Whenever MicroStation comes across MS_DEF
in your workspace,
it knows how to expand that variable to the folder path in order to find a given DGN file.
An argument to ConfigurationVariableValue
would be something like "MS_TAGOUTPUT".
In VBA, you can use ActiveWorkspace.ConfigurationVariableValue
to emulate MicroStation …
Sub TraceMsDef () Const strMS_DEF As String = "MS_DEF" Dim folder As String folder = ActiveWorkspace.ConfigurationVariableValue (strMS_DEF, True) Debug.Print strMS_DEF & "=" & folder End Sub
Configuration variables are often defined in terms of other variables. For example, you might have something like this in your configuration file …
PROJECT_ROOT = V:/Projects/ PROJECT_NAME = Project1 MS_DEF = $(PROJECT_ROOT)$(PROJECT_NAME)/DGN/Models/
Use ExpandConfigurationValue
to convert this compound variable to a value …
Sub TraceMsDef () Const strMS_DEF As String = "MS_DEF" Dim folder As String folder = ActiveWorkspace.ExpandConfigurationValue (strMS_DEF) Debug.Print strMS_DEF & "=" & folder End Sub
A configuration variable may be defined, but is it valid? Suppose a CfgVar points to some folder, but that folder does not exist.
Suppose that we have this scenario, where MS_CELL
is pointing to …
V:\Projects\Workspace\Standards\cells\
but the actual directory name is this (note that the final s is omitted) …
V:\Projects\Workspace\Standards\cell\
The Configuration Validator helps, by verifying the existence of the folder, folders or file to which a CfgVar points.
Often, you want to determine whether a configuration variable is defined or not.
Method IsConfigurationVariableDefined
of the Workspace
is just what you need …
Sub TestCfgVars () TestCfgVar "MS_DEF" TestCfgVar "NOT_DEFINED" End Sub Sub TestCfgVar (strVarName As String) If (IsConfigurationVariableDefined (strVarName)) Then Debug.Print "'" & strVarName & "' is defined" Else Debug.Print "'" & strVarName & "' is not defined" End If End Sub
Operating system environment variables are typically set when you log on to your computer.
If your computer is running Windows you can see environment variable settings in the Advanced tab of
My Computer, or by using the SET
command from a Windows command prompt.
Suppose you want the Windows USERNAME
and COMPUTERNAME
environment variables.
At a Windows command prompt, you can see those names using the SET
command. For example …
C:\>set username USERNAME=CONNECT C:\>set computername COMPUTERNAME=CELERATRIX64
MicroStation evaluates operating system environment variables when it cannot find a MicroStation configuration variable of the same name. You can take advantage of this in VBA …
Sub TraceLogonInfo () Dim computerName As String Dim userName As String Const strCOMPUTERNAME As String = "COMPUTERNAME" Const strUSERNAME As String = "USERNAME" computerName = ActiveWorkspace.ConfigurationVariableValue (strCOMPUTERNAME, True) Debug.Print strCOMPUTERNAME & "=" & computerName userName = ActiveWorkspace.ConfigurationVariableValue (strUSERNAME, True) Debug.Print strUSERNAME & "=" & userName End Sub
Curiously, there's no way in MicroStation VBA to obtain a list of MicroStation configuration variables.
There is an MDL function mdlSystem_getCfgVarByIndex
to get a configuration variable from its index, but that's only useful if you
know beforehand the index of the variable you want to see.
Catch-22!
What's more, that function is hard to use from VBA.
It uses C pointers and pointer addresses that VBA can't easily handle.
Fortunately for you, Bentley Systems staffer
Yongan Fu
came up with a solution.
First, declare the MDL function at the beginning of your VBA project, before any other code …
Declare PtrSafe Function mdlSystem_getCfgVarByIndex Lib "stdmdlbltin.dll" ( _ ByRef name As Long, _ ByRef translation As Long, _ ByRef level As Long, _ ByRef lock_ As Long, _ ByVal index As Long) As Long
Here's a VBA function that wraps the MDL.
Yongan's vital contribution was to figure out the incantation required to convert an
MDL address-of-pointer to a Unicode String
…
' ---------------------------------------------------------------------
' GetCfgVarByIndex
' arg1 String [out] Name of variable at index
' arg2 String [out] Value of variable at index
' arg3 Long [ind] Zero-based index into configuration variable table
' Returns True if index is valid
' ---------------------------------------------------------------------
Private Function GetCfgVarByIndex( _
ByRef name As String, _
ByRef translation As String, _
ByVal index As Long) As Boolean
GetCfgVarByIndex = False
Dim address1 As Long
Dim address2 As Long
If (0 = mdlSystem_getCfgVarByIndex(address1, address2, 0, 0, index)) Then
name = GetCExpressionValue("(char*)" & address1)
translation = GetCExpressionValue("(char*)" & address2)
Debug.Print name & " = " & translation
GetCfgVarByIndex = True
End If
End Function
Here's a VBA function that lists all configuration variables …
Sub TestGetCfgVarNameByIndex() Dim index As Long index = 0 Dim name As String Dim value As String Do While GetCfgVarNameByIndex(name, value, index) index = index + 1 Debug.Print "CfgVar [" & CStr(index) & "] " & name & "=" & value Loop End Sub