Variables and Constants
Master the fundamental building blocks of data management in Visual Basic 2026 — declare variables with Dim, understand scope levels, name identifiers using best-practice conventions, define unchanging values with Const, and leverage read-only fields and enumerations, with GitHub Copilot assistance throughout.
9.1 Variables — Declaration and Initialisation
A variable is declared with the Dim keyword, a name, and optionally a type and an initial value. VB 2026 also supports type inference — if you assign a value immediately, the compiler can deduce the type from context.
' ── Explicit type declaration ────────────────────────── Dim age As Integer ' default value: 0 Dim price As Decimal ' default value: 0D Dim name As String ' default value: Nothing Dim isActive As Boolean ' default value: False ' ── Declaration with initialisation ─────────────────── Dim score As Integer = 100 Dim taxRate As Decimal = 0.06D Dim greeting As String = "Hello, World!" Dim today As Date = DateTime.Today ' ── Type inference (compiler deduces type) ───────────── Dim count = 42 ' Integer Dim pi = 3.14159 ' Double Dim city = "Kuala Lumpur" ' String ' ── Multiple declarations on one line ────────────────── Dim x As Integer, y As Integer, z As Integer Dim firstName As String, lastName As String ' ── Re-assigning values ───────────────────────────────── score = 200 name = "Alice" age = age + 1 ' increment age += 1 ' shorthand compound assignment
Numeric variables default to 0, Boolean to False, and String/Object to Nothing. Reading a String variable that is Nothing then calling a method like .Length throws a NullReferenceException. Always initialise String variables to "" (empty string) if you will use them before assigning a real value, or use String.IsNullOrEmpty() to check safely.
Enter values, assign them to typed variables, and see the declaration syntax, default values, and compound assignment operators in action.
9.2 Variable Scope — Where Variables Live
Scope defines where in the code a variable can be accessed. VB 2026 has three main scope levels. The golden rule: declare variables in the smallest scope that meets your needs.
Public or Friend outside any class. Use sparingly — creates tight coupling between forms.Private or Dim at the top of the class. Used to share state between button click handlers.' ── Module-level (global across all forms) ────────────── ' In a separate Module file: Module AppGlobals Public AppName As String = "My App 2026" Public Version As String = "1.0.0" End Module ' ── Form-level (shared between all subs in this form) ─── Public Class Form1 Private _clickCount As Integer = 0 ' form-level: persists between clicks Private _userName As String = "" ' form-level: accessible by all handlers Private _totalSales As Decimal = 0D ' form-level: accumulates across events ' ── Local scope — lives only inside this Sub ──────────── Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click Dim amount As Decimal ' local: only exists in this Sub If Decimal.TryParse(txtAmount.Text, amount) Then _totalSales += amount ' update form-level variable _clickCount += 1 lblTotal.Text = $"Total: {_totalSales:C} ({_clickCount} sales)" End If End Sub Private Sub btnReset_Click(sender As Object, e As EventArgs) Handles btnReset.Click _totalSales = 0D ' both handlers can access form-level vars _clickCount = 0 lblTotal.Text = "Total: RM 0.00 (0 sales)" End Sub End Class
Static Variables — Persist Between Calls
A Static variable is declared inside a procedure but retains its value between calls — unlike a regular local variable which resets each time the procedure runs.
Private Sub btnClick_Click(sender As Object, e As EventArgs) Handles btnClick.Click ' Static — retains value between button clicks Static clickCount As Integer = 0 clickCount += 1 lblCount.Text = $"Button clicked {clickCount} time(s)" End Sub ' Compare: regular Dim resets to 0 every click Private Sub btnClickNormal_Click(sender As Object, e As EventArgs) Handles btnClickNormal.Click Dim clickCount As Integer = 0 ' always resets — always shows "1" clickCount += 1 lblNormal.Text = $"Count: {clickCount}" ' always "Count: 1" End Sub
Click each button multiple times. See the difference between a local variable (resets every click), a static variable (persists), and a form-level variable (shared between handlers).
9.3 Naming Conventions
Good variable names are self-documenting. VB 2026 follows camelCase for local variables and parameters, _camelCase for private form-level fields, and PascalCase for constants and public members.
| Context | Convention | ✅ Good Examples | ❌ Bad Examples |
|---|---|---|---|
| Local variable | camelCase | totalPrice, itemCount, isValid | TotalPrice, total_price, tp |
| Private field | _camelCase | _clickCount, _userName, _total | clickCount, m_count, X |
| Constant | PascalCase or ALL_CAPS | MaxItems, TaxRate, PI, MAX_SIZE | maxitems, maxI, x |
| Boolean variable | camelCase + is/has/can prefix | isLoggedIn, hasPermission, canEdit | loggedIn, flag, b |
| Public property/method | PascalCase | CustomerName, CalculateTotal | customerName, calcTotal |
Variable names must: start with a letter or underscore, contain only letters, digits, and underscores, not be a VB keyword (Dim, String, If, etc.), and not exceed 1023 characters. VB is case-insensitive — Name and name refer to the same variable. Use consistent casing by convention, but know the compiler treats them identically.
Type a variable name and choose its context. The checker validates against VB 2026 rules and naming conventions.
9.4 Constants — Values That Never Change
A constant is declared with the Const keyword. Its value is set once at declaration and can never be changed — attempting to do so causes a compiler error. Constants make code self-documenting, prevent accidental modification, and allow the compiler to optimise by substituting the literal value at compile time.
' ── Local constants (inside a Sub/Function) ──────────── Private Sub CalcCircle_Click(sender As Object, e As EventArgs) Handles btnCalc.Click Const Pi As Double = 3.14159265358979 Const MaxDiameter As Integer = 1000 Dim radius As Double If Double.TryParse(txtRadius.Text, radius) Then Dim area = Pi * radius ^ 2 Dim circumference = 2 * Pi * radius lblArea.Text = $"Area: {area:F4} | Circumference: {circumference:F4}" End If End Sub ' ── Form-level constants (shared by all procedures) ──── Public Class Form1 Private Const MaxStudents As Integer = 40 Private Const PassMark As Integer = 50 Private Const GSTRate As Decimal = 0.06D Private Const AppTitle As String = "Student Portal 2026" Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.Text = AppTitle lblMax.Text = $"Max students: {MaxStudents}" End Sub Private Sub btnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click Dim mark As Integer If Integer.TryParse(txtMark.Text, mark) Then Dim result = If(mark >= PassMark, "PASS ✔", "FAIL ✘") lblResult.Text = $"{mark}/100 — {result} (Pass mark: {PassMark})" End If End Sub End Class
Module-Level Constants — Application-Wide
For constants used across multiple forms, declare them in a Module using Public Const. Change the value in one place and it updates everywhere automatically — a major maintenance advantage.
' AppConstants.vb — a dedicated Module for all app-wide constants Module AppConstants ' Application identity Public Const AppName As String = "School Management 2026" Public Const Version As String = "3.1.0" Public Const CompanyName As String = "EduSoft Sdn Bhd" ' Business rules — change here to affect the whole app Public Const MaxStudents As Integer = 40 Public Const PassMark As Integer = 50 Public Const DistinctionMark As Integer = 75 Public Const GSTRate As Decimal = 0.06D Public Const MaxLoginAttempts As Integer = 3 ' Mathematical constants Public Const Pi As Double = 3.14159265358979 Public Const GoldenRatio As Double = 1.61803398874989 End Module ' Usage in any form — reference directly by name ' Me.Text = AppConstants.AppName ' lblPass.Text = $"Pass mark: {AppConstants.PassMark}"
Enter a radius. The calculator uses Const Pi = 3.14159265358979 — try changing Pi to 3 in the trace to see the impact of using a wrong value.
9.5 ReadOnly Fields and Enumerations
ReadOnly — Runtime Constants
Const values must be known at compile time (literal values only). When a "constant" needs to be calculated at runtime — like today's date or an object instance — use ReadOnly instead:
Public Class Form1 ' ReadOnly — set in the constructor or field initialiser, then fixed Private ReadOnly _appStartTime As Date = DateTime.Now Private ReadOnly _machineId As String = Environment.MachineName Private ReadOnly _maxItems As Integer Public Sub New() ' Constructor — ReadOnly can be set here too InitializeComponent() _maxItems = GetMaxItemsFromConfig() End Sub Private Function GetMaxItemsFromConfig() As Integer Return 100 ' could read from file, database, registry... End Function End Class
Enumerations — Named Integer Constants
An Enum groups related constants under one type name, making code far more readable than bare integer values. The compiler assigns integer values starting at 0 (or from whatever you specify).
' Define an Enum — usually at module/class level Enum DayOfWeek Monday = 1 Tuesday = 2 Wednesday = 3 Thursday = 4 Friday = 5 Saturday = 6 Sunday = 7 End Enum Enum StudentGrade Fail = 0 ' 0–49 Pass = 1 ' 50–64 Credit = 2 ' 65–74 Distinction = 3 ' 75–84 HighDist = 4 ' 85–100 End Enum ' Using enums — much clearer than using raw integers Private Sub btnGrade_Click(sender As Object, e As EventArgs) Handles btnGrade.Click Dim mark As Integer If Not Integer.TryParse(txtMark.Text, mark) Then Return Dim grade As StudentGrade Select Case mark Case 0 To 49 : grade = StudentGrade.Fail Case 50 To 64 : grade = StudentGrade.Pass Case 65 To 74 : grade = StudentGrade.Credit Case 75 To 84 : grade = StudentGrade.Distinction Case Else : grade = StudentGrade.HighDist End Select lblGrade.Text = $"Mark: {mark} → Grade: {grade}" ' displays "Grade: Distinction" End Sub
Use Const for literal values known at compile time (Pi, MaxItems, PassMark). Use ReadOnly when the value depends on runtime information (today's date, machine name, config file values). Use Enum when you have a fixed set of named choices (grades, day of week, status codes) — it gives you IntelliSense autocomplete and prevents invalid values.
Enter a mark and name. The app uses Const PassMark = 50, Const DistinctionMark = 75 and a StudentGrade Enum to display the grade.
9.6 GitHub Copilot — Variables & Constants
' Create a Module called AppConstants with constants for a school app: max students, pass mark, distinction mark, GST rate, and app name'' Create a Module called AppConstants with constants for a school app: max students, pass mark, distinction mark, GST rate, and app name Module AppConstants Public Const AppName As String = "School Management System" Public Const MaxStudents As Integer = 40 Public Const PassMark As Integer = 50 Public Const DistinctionMark As Integer = 75 Public Const GSTRate As Decimal = 0.06D End Module
' Define a StudentGrade enum and a function that takes a mark as Integer and returns the correct StudentGrade'' Define a StudentGrade enum and a function that takes a mark as Integer and returns the correct StudentGrade Enum StudentGrade Fail : Pass : Credit : Distinction : HighDistinction End Enum Private Function GetGrade(mark As Integer) As StudentGrade Select Case mark Case 0 To 49 : Return StudentGrade.Fail Case 50 To 64 : Return StudentGrade.Pass Case 65 To 74 : Return StudentGrade.Credit Case 75 To 84 : Return StudentGrade.Distinction Case Else : Return StudentGrade.HighDistinction End Select End Function
Try these in the Copilot Chat panel while working on variables and constants:
- "Convert all my magic numbers in this form to named constants"
- "Create a form-level counter that increments on every button click and resets on double-click"
- "Show me all the places in my code where I'm using the number 50 and replace them with PassMark"
- "Create an Enum for OrderStatus with values Pending, Processing, Shipped, Delivered, Cancelled"
📘 Lesson Summary
- Declare variables with
Dim name As Type. Without an explicit type, use type inference:Dim x = 42→ Integer. Always initialise String variables to""to avoid NullReferenceException. - Scope rule: declare variables in the smallest possible scope. Local (
Diminside a Sub) → Form-level (Privateat class level) → Module-level (Publicin a Module). - A Static variable is declared inside a procedure but retains its value between calls — useful for counters and accumulators without promoting to form-level.
- Use camelCase for local variables (
totalPrice), _camelCase for private fields (_clickCount), and prefix Boolean variables withis/has/can(isLoggedIn). - Declare constants with
Const— they can never be re-assigned. The compiler substitutes literal values at compile time for maximum performance. - Put shared constants in a dedicated Module (e.g.
AppConstants.vb). Changing one value updates the whole application — no hunting for magic numbers. - Use
ReadOnlywhen the "constant" must be calculated at runtime (e.g.DateTime.Now, machine name, or config values read from a file). - Enumerations (Enum) group related integer constants under a meaningful type — they prevent invalid values, give IntelliSense autocomplete, and make
Select Caseblocks far more readable. - GitHub Copilot can generate entire constants modules, Enum definitions, and scope-appropriate variable declarations from a single descriptive comment.
Exercises
Exercise 9.1 — Sales Commission Calculator
- Declare
Constvalues for commission tiers: Base (5%), Silver (7%), Gold (10%), Platinum (15%) - Use a form-level variable
_totalSales As Decimalthat accumulates across multiple transactions - Each time the user enters a sale amount and clicks Add, update the total and show which commission tier applies
- Use a Static variable inside the click handler to count the number of sales entered this session
- Copilot challenge: Ask Copilot to "add a SalesStatus Enum with tiers Base, Silver, Gold, Platinum and use it to colour the commission label"
Exercise 9.2 — Application Settings Module
- Create a Module called
AppSettingswith constants: AppName, Version, MaxUsers, DefaultTimeout, and CompanyName - Create a Settings form that displays all constants in Labels — users can see them but not edit them
- Use the constants in the main form's title bar, About dialog, and status strip
- Demonstrate that changing a constant value in one place updates every form automatically
- Copilot challenge: Ask Copilot to "add a ReadOnly property that returns formatted version info: AppName v1.0 — Company (current year)"
Exercise 9.3 — Traffic Light Enum
- Define a
TrafficLightEnum with values: Red, Yellow, Green - Create a PictureBox or coloured Panel that changes colour based on the current Enum value
- Add Next and Reset buttons — Next cycles Red → Green → Yellow → Red using
Mod - Display the current state and what action it means (Stop / Caution / Go) in a Label
- Copilot challenge: Ask Copilot to "add a Timer that automatically cycles the traffic light every 3 seconds"
Related Resources
← Lesson 8
Data Types — Integer, Double, Decimal, String, Boolean, Date.
Lesson 10 →
Arrays — collections of variables with a shared name and index.
MS Docs — Variables
Official Microsoft reference for variable declaration and scope in VB.NET.
MS Docs — Constants & Enums
Official Microsoft reference for Const, ReadOnly, and Enum in VB.NET.
Featured Books
Visual Basic 2022 Made Easy
Comprehensive coverage of variables, constants, scope, naming conventions, and enumerations with practical step-by-step projects.
View on Amazon →
VB Programming With Code Examples
48 fully-explained VB.NET programs illustrating proper use of variables and constants in real-world applications.
View on Amazon →