问题
I am writing an add-in for XL 2010 / 2013 that makes use of a database connection via an ADODB.Connection object. I tried to declare the object in various ways in order for it to remain between uses of the add-in but so far to no avail.
The goal is to initialise the connection at startup and maintain this for the duration. When the add-in workbook's Open event is triggered the initialisation code runs fine, makes the connection and I have an ADODB.Connection object. When the sequence finishes control returns to XL as you would expect. Stepping through the code shows that it all works as expected. The ADODB.Connection object would then be disposed of in the Workbook_BeforeClose event handler.
When a user then attempts to use a feature of the add-in (after startup / initialisation) that utilises the database connection we find that the connection object has dropped out of scope and no longer exists, even when set as a global in a standard module. I have also tried setting this as a public variable / object in the workbook's code module but to no avail.
Is there a way to persist the connection object (or any object for that matter) between successive uses of the add-in?
Cheers
The Frog
PS: For DB afficionados out there who will (usually rightly) point out that maintaining a connection is not the best way: In this scenario it is required whether I like it or not. The back end (BE) uses a lot of temp tables that need to remain between using the different features of the add-in.
ANSWER
Well Tony you had it right, I just hadn't put it in the right place.
The answer to the problem is as follows:
1/ You need to declare a function that will return for you the connection object:
Function cn() As ADODB.Connection
Static mCon As ADODB.Connection
On Error Resume Next 'Better way to handle?
If mCon Is Nothing _
Or mCon.State = adStateClosed Then 'exists? connected?
Set mCon = New ADODB.Connection 'create anew
mCon.Open getConnectionString 'open the connection
Debug.Print "Connection attempted"
If mCon.State = adStateOpen Then Connected = True
End If
Set cn = mCon
End Function
2/ Declare the 'working' connection object as Static as in the code above
3/ Use the name of the function in place of the connection object. In this case the function is called 'cn'. You can use 'cn' just as you would if you declared the object directly and called it directly. Using the function you will get intellisense and all other normal object properties and methods available to you (including using it with stored procedures if you have them).
eg/ Debug.Print cn.ConnectionString will call the function and return the connection string of the underlying ADODB.Connection object's property.
4/ I have used a function to generate the connection string called 'getConnectionString' - you can hard code it or make your own function. All it does is provide the correct connection string for the ADODB.Connection objects Open method call.
5/ I have a variable called 'Connected' which I believe will be better served as a function rather than a global. ie/ Write a function that checks the 'State' property of the connection object and returns a boolean.
Thanks for the help Tony. Nice pointer.
Enjoy the solution
Cheers
The Frog
来源:https://stackoverflow.com/questions/23234086/xl-add-in-vba-and-persistent-objects