Home > Excel, VBA Macro > Excel data validation with VBA macros

Excel data validation with VBA macros

February 4, 2011 Leave a comment Go to comments

You have an important lead set or any other orders/financial recordset in excel and have to import the data in SQL Server. This is not a one time effort but ongoing and in future you have to deals with lot such records/data files. To import valid data in your SQL tables you want to ensure and validate at the frst step instead of correcting the data by firing SQL queries. Also to avoid this manual work to identify the incorrect/invalid data out of thousands of records automated approach would be quite helpful.

Excel not only store data but also have a power to run VBA macro code against and manipulate the data. Lets take a simple example to validate a set of Customer numbers & their insert date, shown below:

-- Test Data which is correct and expected to import in SQL table.
InsertDate	CustomerNo
11/16/2009	91878552
11/16/2009	101899768
11/16/2009	101768884
11/16/2009	123456789123
11/16/2009	101768800

Columns InsertDate should be a valid date & CustomerNo should be numeric & less than 12 characters or max length equal to 12.

-- Lets tweak the test data put some invalid values under both the columns, shown below:
InsertDate	CustomerNo
11/16/2009	91878552
51/96/2009	101899768
11/16/2009	1017abc84
11/16/2009	123456789123
11/16/2009	101768800

If you are on MS Office 2007 create a Macro enabled excel file with extension *.xlsm, OR if you are on 2003 and lower version *.xls file would be fine. Copy the above data in Sheet1 with incorrect values. Now press open up the VBA macro editor or press ALT+F11 keys. Now double click on Sheet1 under “Project -VBAProjects” explorer.
I wish to run the validation while someone tries to save the macro enabled excel file. So the event selected is “BeforeSave”. And the VBA macro code goes below:

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

	Dim errorCode As Integer
	Dim errorMsg As String

	Dim numOfRecs As Integer
	Dim counter As Integer

	'---------------------
	'Start - Validate Date
	'---------------------
	Sheet1.Activate
	Range("A2").Select

	errorCode = 0
	numOfRecs = 0

	Do Until ActiveCell.Value = vbNullString

		' Validate Date
		If IsDate(ActiveCell.Value) <> True Then
			errorCode = 1
			ActiveCell.Interior.ColorIndex = 3 'Red
		Else
			ActiveCell.Interior.ColorIndex = 2 'White
		End If

		numOfRecs = numOfRecs + 1

		ActiveCell.Offset(1, 0).Select

	Loop

	If errorCode = 1 Then
		errorMsg = errorMsg + vbCrLf & "- Invalid Insert Date"
	End If
	'-------------------
	'End - Validate Date
	'-------------------

	'--------------------------
	'Start - Validate Customer#
	'--------------------------
	Sheet1.Activate
	Range("B2").Select

	errorCode = 0

	Do Until ActiveCell.Value = vbNullString

		' Check for a valid Customer Number
		If IsNumeric(ActiveCell.Value) <> True Or Len(ActiveCell.Value) > 12 Then
			errorCode = 1
			ActiveCell.Interior.ColorIndex = 3 'Red
		Else
			ActiveCell.Interior.ColorIndex = 2 'White
		End If

		ActiveCell.Offset(1, 0).Select

	Loop

	If errorCode = 1 Then
		errorMsg = errorMsg + vbCrLf & "- Invalid Customer #"
	End If
	'------------------------
	'End - Validate Customer#
	'------------------------

	' Go to first cell.
	Range("A1").Select

	'If errors then display the error msg and do not save the file otherwise save the excel file.
	If errorCode = 1 Then
		MsgBox "Workbook not saved. Following are the fields that contain invalid values." _
			& vbCrLf & errorMsg & vbCrLf & vbCrLf & _
			"Please correct the values highlighted in RED color.", vbCritical, "Data Validation ERROR"

		Cancel = True

	End If

End Sub

Invalid values highlighted RED

Now save the macro code and close the editor. Now try to Save the Excel file, you will get the cells with invalid values highlighted in RED, as shown in the image. The excel file not be saved and when closing you will get the dialog box to save it again & again.

In order to save it correctly you need to correct the invalid values, i.e. InsertDate & CustomerNo, and then save it. The RED highlighted cells will become WHITE for the correct values.

This excel file is now very much validated and clean to import in SQL Server or any other database.

 

Try this code and tweak it as per your needs.

I’ve also discussed this logic in MSDN’s TSQL forum at following link: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/09299d7d-9306-4ea4-bb29-87207572aa04

Suggestions & comments are welcome!!!

Advertisement
  1. Steven White
    August 1, 2011 at 6:29 pm

    Good code except for the fact that if there is an error in column “A” but no error in column “B”, error code gets reset to 0, and no error message is displayed. You could set a Boolean to True if errorcode = 1 after checking each field, and then check the Boolean at the end to decide whether to display the error message.

  2. August 2, 2011 at 5:54 am

    Thanks Steven for pointing it out.
    Appreciate your comments 🙂

  3. rose
    August 14, 2017 at 9:23 am

    looking at this code, whats the best way to condense this code so its not so long?

    Option Compare Database

    ‘Step 1 Setting up connection for access to vba

    Dim connection As New ADODB.connection
    Dim magazines As New ADODB.Recordset
    Private recordBookmark As Integer

    ‘Step 2 Create your function for populating the form

    Private Sub PopulateForm()

    Me.txtMagazineID = magazines.Fields(“magazineId”)
    Me.txtName = magazines.Fields(“name”)
    Me.txtDate = magazines.Fields(“firstPublished”)
    Me.txtFee = magazines.Fields(“subscriptionFee”)
    Me.txtCategory.Value = magazines.Fields(“categoryId”)

    End Sub

    ‘Step 2.1 Creat your lock form

    Private Sub LockForm()

    Me.btnAdd.Enabled = True
    Me.btnEdit.Enabled = True
    Me.btnSave.Enabled = False
    Me.btnCancel.Enabled = False
    Me.btnExit.Enabled = True
    Me.btnDelete.Enabled = True

    Me.txtCategory.Locked = True
    Me.txtMagazineID.Locked = True
    Me.txtName.Locked = True
    Me.txtDate.Locked = True
    Me.txtFee.Locked = True

    End Sub

    ‘Step 2.2 Creat your edit unlock form

    Private Sub EnableLockForm()

    Me.btnAdd.Enabled = False
    Me.btnEdit.Enabled = False
    Me.btnSave.Enabled = True
    Me.btnCancel.Enabled = True
    Me.btnExit.Enabled = True
    Me.btnDelete.Enabled = False

    Me.txtCategory.Locked = False
    Me.txtMagazineID.Locked = False
    Me.txtName.Locked = False
    Me.txtDate.Locked = False
    Me.txtFee.Locked = False

    End Sub

    ‘Step 3 load form

    Private Sub Form_load()

    Set connection = CurrentProject.connection
    magazines.Open “SELECT * FROM magazine ORDER BY magazineId”, connection, adOpenKeyset, adLockOptimistic
    magazines.MoveFirst

    Call PopulateForm
    Call LockForm
    End Sub

    ‘Step 4 Create list before creating search and so it can link properly

    Private Sub txtList_Click()
    magazines.Requery
    magazines.Find “magazineId = ” & Me.txtList.Value
    Call PopulateForm

    End Sub

    ‘Step 4.2 This part comes last when your list is done, its because its the same code(optional)

    Private Sub btnSearch_Click()

    magazines.Requery
    magazines.Find “name LIKE ‘” & Me.txtSearch & “%'”
    Call PopulateForm

    End Sub

    ‘Step 5 making your add button working

    Private Sub btnAdd_Click()

    Call EnableLockForm

    magazines.AddNew
    magazines(“name”) = “”
    Call PopulateForm

    End Sub

    ‘Step 5.1 Making edit button

    Private Sub btnEdit_Click()

    Call EnableLockForm
    magazines.Requery

    End Sub

    ‘Step 5.1.5 making the save update form

    Private Sub UpdateForm()

    magazines(“categoryId”) = Me.txtCategory
    magazines(“name”) = Me.txtName
    magazines(“firstPublished”) = Me.txtDate
    magazines(“subscriptionFee”) = Me.txtFee

    End Sub

    ‘getting the validation to work
    Private Sub validation()

    Dim errors As String
    errors = “”
    Dim savedCustomer As String

    If Len(Me.txtName) = 0 Then
    If errors = “” Then
    Me.txtName.SetFocus
    End If
    errors = errors & vbCrLf & “Please enter name”
    End If

    If IsNull(txtFee) > 9 Or Not IsNumeric(txtFee) Then
    If errors = “” Then
    Me.txtFee.SetFocus
    End If
    errors = errors & vbCrLf & “Number must be greater then 9”
    End If

    If IsNull(txtDate) Or Not IsDate(txtDate) Then
    If errors = “” Then
    Me.txtDate.SetFocus
    End If
    errors = errors & vbCrLf & “ou must enter a correct date e.g 1/1/2017”
    End If

    If errors = “” Then
    recordBookmark = Me.txtMagazineID
    Call UpdateForm

    magazines.Update
    magazines.Requery

    magazines.Find ” magazineId = ” & recordBookmark

    Call LockForm
    Else
    ‘if there are errors, shows error msg and prompts a cancel
    MsgBox (errors)

    End If
    

    End Sub

    ‘Step 5.2 Making the save button

    Private Sub btnSave_Click()
    Call validation

    End Sub

    ‘Step 5.2 Making the cancel button

    Private Sub btnCancel_Click()

    magazines.CancelUpdate
    Call PopulateForm
    Call LockForm

    End Sub

    ‘Step 5.2 Making the delete button

    Private Sub btnDelete_Click()

    Dim confirm As Boolean
    confirm = MsgBox(“Confirm Delete of Magazine: ” & Me.txtName, vbYesNo)
    If confirm = True Then
    magazines.Delete
    magazines.MovePrevious
    Call PopulateForm
    End If

    End Sub

    Private Sub btnFirst_Click()
    magazines.MoveFirst
    Call PopulateForm

    End Sub

    Private Sub btnLast_Click()

    magazines.MoveLast
    Call PopulateForm

    End Sub

    Private Sub btnNext_Click()

    On Error GoTo btnNext_Click_Err

    If magazines.EOF Then
        magazines.MoveLast
    Else
        magazines.MoveNext
        Call PopulateForm
    End If
    

    btnNext_Click_Exit:
    Exit Sub

    btnNext_Click_Err:
    MsgBox “This is the last customer on record.”
    Resume btnNext_Click_Exit

    End Sub

    Private Sub btnPrevious_Click()

    On Error GoTo btnNext_Click_Err

    If magazines.BOF Then
        magazines.MoveFirst
    Else
        magazines.MovePrevious
        Call PopulateForm
    End If
    

    btnNext_Click_Exit:
    Exit Sub

    btnNext_Click_Err:
    MsgBox “This is the last customer on record.”
    Resume btnNext_Click_Exit

    End Sub

    Private Sub btnExit_Click()

    DoCmd.Close
    ‘SELECT category.categoryId, category.description FROM category ORDER BY categoryId;
    End Sub

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: