UBound() returns the highest valid index in an array, while LBound() returns the lowest valid index. In Classic ASP (VBScript), array indexes start at 0. The upper bound is therefore not the same as the element count.
UBound(items) - LBound(items) + 1 gives the number of available elements. A declaration such as Dim items(3) creates four positions: 0, 1, 2 and 3.<%
Option Explicit
Dim countries
countries = Array("UK", "USA", "Canada", "UAE")
Response.Write "Highest index: " & UBound(countries) & "<br>"
Response.Write "Total elements: " & (UBound(countries) - LBound(countries) + 1)
%>
Output: Highest index: 3; Total elements: 4. The four values are stored at indexes 0 through 3.
UBound(arrayName[, dimension])
LBound(arrayName[, dimension])
The optional dimension argument identifies which dimension to inspect: 1 is the first dimension, 2 is the second, and so on. If omitted, the first dimension is used.
| Expression | Meaning |
|---|---|
UBound(arr) | Highest valid index in the first dimension |
LBound(arr) | Lowest valid index in the first dimension (0 in VBScript) |
UBound(arr) - LBound(arr) + 1 | Number of positions in a one-dimensional allocated array |
UBound(arr, 2) | Highest valid index in the second dimension |
The following example preserves the original country-array demonstration. Dim myArray(3) allocates positions 0 through 3; it does not allocate three elements.
<%
Dim myArray(3), i
myArray(0) = "UK"
myArray(1) = "USA"
myArray(2) = "Canada"
myArray(3) = "UAE"
Response.Write "Highest index = " & UBound(myArray) & "<br>"
Response.Write "Number of elements = " & (UBound(myArray) - LBound(myArray) + 1)
For i = LBound(myArray) To UBound(myArray)
Response.Write "<br>" & Server.HTMLEncode(myArray(i))
Next
%>
Output: Highest index = 3; Number of elements = 4; followed by UK, USA, Canada and UAE on separate lines. Using LBound() and UBound() avoids hard-coding loop limits.
Many Classic ASP programs create arrays from a list of values or by splitting a string. The counting formula works for both.
<%
Dim months, monthCount
months = Array("Jan", "Feb", "Mar")
monthCount = UBound(months) - LBound(months) + 1
Response.Write "Month count: " & monthCount
%>
Output: Month count: 3.
<%
Dim colours, colourCount
colours = Split("red,green,blue", ",")
colourCount = UBound(colours) - LBound(colours) + 1
Response.Write "Colours: " & colourCount
%>
Output: Colours: 3. See Split() in Classic ASP for delimiters and empty-string handling.
The original Dim arr(3, 4) example creates 4 rows and 5 columns, or 20 positions in total. Pass the dimension number to UBound() and LBound() separately.
<%
Dim arr(3, 4), rowCount, columnCount, totalElements
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
columnCount = UBound(arr, 2) - LBound(arr, 2) + 1
totalElements = rowCount * columnCount
Response.Write "Rows: " & rowCount & "<br>"
Response.Write "Columns: " & columnCount & "<br>"
Response.Write "Total elements: " & totalElements
%>
Output: Rows: 4; Columns: 5; Total elements: 20. These are available positions; some may still be unassigned (Empty).
Use an index for each dimension. The example stores and displays a compact 2-by-3 grid.
<%
Dim grid(1, 2), rowIndex, colIndex
grid(0, 0) = "A1"
grid(0, 1) = "A2"
grid(0, 2) = "A3"
grid(1, 0) = "B1"
grid(1, 1) = "B2"
grid(1, 2) = "B3"
For rowIndex = LBound(grid, 1) To UBound(grid, 1)
For colIndex = LBound(grid, 2) To UBound(grid, 2)
Response.Write grid(rowIndex, colIndex) & " "
Next
Response.Write "<br>"
Next
%>
You can put the formula in a small function for a one-dimensional allocated array. This is the same approach used in the original tutorial.
<%
Function ArraySize(values)
ArraySize = UBound(values) - LBound(values) + 1
End Function
Dim cities
cities = Array("Delhi", "Mumbai", "Hyderabad")
Response.Write "Number of cities: " & ArraySize(cities)
%>
Output: Number of cities: 3. This simple function is not intended for unallocated dynamic arrays; see the section on empty arrays below.
This version fills all six elements of Dim arr(5) and displays their positions and values.
<%
Dim arr(5), i, arraySize
For i = LBound(arr) To UBound(arr)
arr(i) = i * 10
Next
arraySize = UBound(arr) - LBound(arr) + 1
Response.Write "Size of array: " & arraySize & "<br>"
For i = LBound(arr) To UBound(arr)
Response.Write "Element " & i & " = " & arr(i) & "<br>"
Next
%>
Output: Size of array: 6, followed by Element 0 = 0 through Element 5 = 50.
Use Dim arr() when the final number of elements is not initially known. ReDim allocates the array; ReDim Preserve changes its size while retaining existing values.
<%
Dim arr()
ReDim arr(3)
arr(0) = "A"
arr(1) = "B"
arr(2) = "C"
arr(3) = "D"
Response.Write "Before resizing: " & (UBound(arr) - LBound(arr) + 1) & "<br>"
ReDim Preserve arr(5)
arr(4) = "E"
arr(5) = "F"
Response.Write "After resizing: " & (UBound(arr) - LBound(arr) + 1)
%>
Output: Before resizing: 4; After resizing: 6.
ReDim Preserve on a multidimensional VBScript array, you can change only the last dimension. For instance, an allocated ReDim grid(1, 2) can be resized using ReDim Preserve grid(1, 4), not ReDim Preserve grid(2, 2).Dim grid()
ReDim grid(1, 2) ' 2 rows, 3 columns
ReDim Preserve grid(1, 4) ' 2 rows, 5 columns; preserves values
Array() creates an empty array, for which UBound() is -1. By contrast, a dynamic array declared as Dim values() has not been allocated yet: calling UBound(values) before ReDim can cause a runtime error.
<%
Dim values
values = Array()
Response.Write "Empty array upper bound: " & UBound(values) & "<br>"
If UBound(values) < 0 Then
Response.Write "The array has no elements."
End If
%>
Output: Empty array upper bound: -1; The array has no elements.
Dim values()
ReDim values(2) ' Allocate 3 positions before calling UBound()
Response.Write UBound(values) ' Displays 2
For general-purpose input where an array might be unallocated, validate or initialize it before applying the counting formula. IsArray() alone does not guarantee that a dynamic array has been allocated.
| Issue | What to check |
|---|---|
Expecting Dim items(5) to contain 5 positions | It creates 6 positions: indexes 0 through 5. |
Subscript out of range when calling UBound() | Check that a dynamic array has been allocated and you are using an existing dimension. |
ReDim Preserve produces an error for 2D arrays | Only resize the last dimension when preserving contents. |
| Using the highest index as the element count | Use UBound(arr) - LBound(arr) + 1, not just UBound(arr). |
| Count differs from the number of meaningful values | The formula counts available positions, including unassigned elements. |
No. It returns the highest index in the requested dimension. Dim x(3) has UBound(x) = 3 but has four positions.
It makes the formula explicit: highest index minus lowest index plus one. In VBScript the lower bound of an array dimension is zero.
Yes. For example, Split("a,b,c", ",") returns three elements. For an empty input, handle the empty-array result appropriately.
The array is reallocated and previously stored values are not retained. Use ReDim Preserve if you need to keep them.
Yes, calculate each dimension separately using the second dimension argument, and multiply those sizes for the total number of positions.
Continue with array declarations and related string operations:
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.