I am working on a spreadsheet tool that queries a SQL Server database and populates various sheets with the results. I provide the user with a simple GUI (formatted cells) to enter their database credentials and an Excel form button which tests the connection. When the button is pressed and the connection string is formed correctly, I identify this by changing the color of a status indicator from red to green. I have added a check to the range of cells that hold the credentials using the Worksheet_Change function, which will switch the status from green back to red if any of the cells are altered.
The problem is users are entering some aspect of their connection string, maybe the last field, and then pressing the ‘Test Connection’ button without first pressing enter or navigating away. and actually writing the value to the cell. My ‘Test Connection’ macro (linked to the button) is called first, switching the status indicator to green (assuming correct credentials), but the Worksheet_Change method does not get called until after the button macro has run through. The result is that the status indicator blinks from green and then back to red despite a establishing a database connection successfully.
I have tried things like manually switching the focus away from the current cell. Before calling my ‘TestConnection’ function from the form button. But so far nothing has worked.
Edit: Some Code…
Private Sub Worksheet_Change(ByVal Target As Range)
Call SetGlobals
'Check if database criteria has changed
If Not Intersect(Target, Target.Worksheet.Range(DB_CELL_RANGE)) Is Nothing Then
Call UpdateDBStatus(1)
End If
End Sub
'Connect to database using Main sheet credentials
Function TestConnection()
'Connection vars
Set cnn = New ADODB.Connection
'Open the connection.
On Error GoTo ConnectError
cnn.Open GetConnectionString()
'Update dependencies
'On Error GoTo FilterError
Call UpdateFilter("select ********", "F", "F")
Call UpdateFilter("select *******", "E", "E")
Call UpdateDBStatus(2)
MsgBox "Connected successfully to '" & DBASE & "' on machine '" & SERVER & "'"
'Cleanup
cnn.Close
Set cnn = Nothing
Exit Function
ConnectError:
Call UpdateDBStatus(1)
MsgBox "Could not establish a connection."
Exit Function
FilterError:
MsgBox "Filter Update Failure."
Exit Function
End Function
'Set the status of the database connection and mark the result
Public Function UpdateDBStatus(Status As Integer)
If Status = 1 Then
Sheets("Main").Range(DB_STATUS_CELL).Value = "Not Connected"
Sheets("Main").Range(DB_STATUS_CELL).Interior.ColorIndex = 3
DB_STATUS = False
Else
Sheets("Main").Range(DB_STATUS_CELL).Value = "Connected"
Sheets("Main").Range(DB_STATUS_CELL).Interior.ColorIndex = 4
DB_STATUS = True
End If
End Function
Basically if someone is currently editing a cell inside of DB_CELL_RANGE and they presses the ‘Test Connection’ button I would like to have Worksheet_Change complete before calling ‘TestConnection’.
Answer turned out to be a fairly simple boolean flag which I set to True when a successful database connection is established, then false after the next run of
Worksheet_Changefinishes. From then only check the DB connection when the flag is false. Code is as follows: