Validating Selections

Custom validation procedures should test the user's and computer's ship and target selections for proper location and size. Because there are several validation procedures, I have placed them in their own standard code module. This is not really necessary as all of the remaining code could have been included with the object module for the Worksheet object; however, the code in the object module was getting a bit long and more difficult to navigate, so a new module was added and named Validation in order to better organize the program's procedures.

The standard code module contains several global variable declarations previously discussed. These variables are given public scope because they must be accessed in multiple code modules.

It is worth repeating that it is best to avoid the use of global variables as they make your code harder to read and leave your data unprotected; however, at this level of programming, it is difficult to avoid the use of global variables and they are acceptable as long as their number is kept to a minimum.

Option Explicit

Public pRange As Range, cRange As Range Public numShipsPlaced As Integer Public shipSize As Variant

The two main validation procedures in the Validation code module are RangeValid() and TargetValid() which are used to validate the user's and computer's ship locations and target selections, respectively. Each of these functions calls several subordinate function procedures that validate a specific requirement of the range.

These two procedures were designed to handle validation for both the user's and computer's ships and targets; therefore, the argument msg is declared in the argument list for each function using the VBA keyword Optional. Using Optional indicates that the argument is not required in the calling statement. (Error messages are only required for the user's selections.) If Optional is used, then all subsequent arguments in the parameter list must also be optional and declared using the Optional keyword.

Public Function RangeValid(shipLocation As Range, grid As String, _

Optional msg As String) As Boolean

'Validates players selections when placing ships. Dim tempRange As Range

RangeValid = True

'Define range for tests.

If (grid = "Player") Then Set tempRange = pRange

Else

Set tempRange = cRange End If

'Call several functions testing for specific errors. 'Exit function immediately with any failed test.

RangeValid = TestLength(shipLocation, msg) If (Not RangeValid) Then Exit Function

RangeValid = TestIfInRange(shipLocation, tempRange, msg) If (Not RangeValid) Then Exit Function

RangeValid = TestForMultipleRowsOrCols(shipLocation, msg) If (Not RangeValid) Then Exit Function

RangeValid = TestForOverlap(shipLocation, msg) If (Not RangeValid) Then Exit Function End Function

The functions listed here rely heavily on the Range object and a few of its properties; but by now, you should be getting more comfortable with the Range object. The RangeValid() function procedure tests the user's and computer's ships for valid length, location within the correct grid, spanning multiple rows or columns, and overlap with a previously placed ship—using a separate function for testing each criteria (TestLength(), TestIfInRange(), TestForMultipleRowsOrCols(), and TestForOverlap()). If each criteria passes, then the function returns true to the calling procedure, otherwise it returns false.

Private Function TestLength(shipLocation As Range, msg As String) As Boolean

'Check if length of selection is correct

TestLength = True

If shipLocation.Count <> shipSize(numShipsPlaced) Then msg = "Please select " & shipSize(numShipsPlaced) & " cells" TestLength = False End If End Function

Private Function TestIfInRange(shipLocation As Range, tempRange As Range, msg As String) As Boolean

'Check if selection is in player's/computer's range and that 'either column index or row index is identical across the range.

Dim coll As Integer, col2 As Integer Dim rowl As Integer, row2 As Integer

TestIfInRange = True coll = shipLocation.Column col2 = shipLocation.Column + shipLocation.Columns.Count rowl = shipLocation.Row row2 = shipLocation.Row + shipLocation.Rows.Count

If (rowl < tempRange.Row) Or (row2 > tempRange.Row + tempRange.Rows.Count) _ Or (coll < tempRange.Column) _

Or (col2 > tempRange.Column + tempRange.Columns.Count) Then msg = "Selection out of range" TestIfInRange = False End If End Function

Private Function TestForMultipleRowsOrCols(shipLocation As Range, msg As String) As Boolean

'Check if selection spans multiple rows or columns.

TestForMultipleRowsOrCols = True

If (shipLocation.Columns.Count > 1) And (shipLocation.Rows.Count > 1) Then msg = "Selection must be within the same row or column" TestForMultipleRowsOrCols = False End If End Function

Private Function TestForOverlap(shipLocation As Range, msg As String) As Boolean

'Check to see if selection overlaps a previous selection.

Dim c As Range

TestForOverlap = True For Each c In shipLocation

If c.Interior.Color = RGB(0, 255, 255) Or c.Value = "X" Then msg = "Selection cannot overlap another ship!" TestForOverlap = False End If

Next End Function

The TargetValid() function procedure tests the user's and computer's targets for proper length (one cell) and location (within each other's grids, and not previously selected). The subordinate functions TestForOneCell() and TestLocation() handle the specific tests for validating the target.

Public Function TargetValid(shotSelection As Range, grid As String, _

Optional msg As String) As Boolean 'Tests user's/computer's selection of target. Dim tempRange As Range

'Define range for tests.

If (grid = "Player") Then Set tempRange = pRange

Else

Set tempRange = cRange End If msg = "Select one cell within the computer's grid."

'Test if only one cell is selected.

TargetValid = TestForOneCell(shotSelection, msg)

'Test if player's/computer's selection is in computer's grid or 'if player/computer already selected the target cell.

TargetValid = TestLocation(shotSelection, tempRange, msg) End Function

Private Function TestForOneCell(shotSelection As Range, msg As String) As Boolean TestForOneCell = True If shotSelection.Count > 1 Then msg = "You can only fire at one cell!" TestForOneCell = False End If End Function

Private Function TestLocation(shotSelection As Range, tempRange As Range, msg As String) As Boolean Dim c As Range

'TestLocation = True For Each c In tempRange

If c.Address = shotSelection.Address Then TestLocation = True

c.Interior.Color = RGB(255, 0, 0) Or _ c.Interior.Color = RGB(0, 255, 0) Then msg = "You have already selected that cell!" TestLocation = False Exit Function End If End If

Next End Function

Biorhythm Awareness

Biorhythm Awareness

Who else wants to take advantage of biorhythm awareness to avoid premature death, escape life threatening diseases, eliminate most of your life altering mistakes and banish catastrophic events from your life.

Get My Free Ebook


Post a comment