Full Version: Connecting to already open DB using VB.Net
UtterAccess Discussion Forums > Microsoft® Access > Access Automation
Pyth007
I have an Access DB that we have been using for a while, and so have several forms with underlying code ensuring data integrity that are used for data entry. I have recently been asked to create a program that can grab data from a help-desk application and semi-automatically enter in that data into our DB (semi-automatic in that a human user would validate the data before it gets stored into the DB). Because we are also looking to expand / upgrade our DB to a DB2 backend, I was wanting to create this new app. in VB.Net (which we'll probably, eventually use for the new front-end) and then incorporate it into the current DB. I have been able to do much of what I'm wanting to do: query the DB using ADO.Net, fill in data on an Access form, and run public methods from those forms:
CODE

Dim strForm As String = "frmEntry"
Dim oForm As Access.Form
Dim oAccess As New Access.Application()
oAccess.OpenCurrentDatabase("c:\database\mydb.mdb", false) ' Opens database
If Not oAccess.Visible then oAccess.Visible = True ' Ensure that it is visible

' Make a connection to the form in the DB
oAccess.DoCmd.SelectObject(Access.AcObjectType.acForm, strForm, True)
oAccess.DoCmd.OpenForm(strForm, Access.AcFormView.acNormal)
oForm = oAccess.Forms(strForm)
oForm.Controls.Item("txtTicketNumber").Text = Me.txtTicket.Text ' Perform data-entry into the DB form
' [... continue for all other data fields. When done call ProcessTicket to update DB]
oForm.ProcessTicket()  ' ProcessTicket is a Public sub

However the problem with this is that the way that I am automating the data-entry into the Access form opens a new instance of the Access DB. What I would like to do is be able to use an instance of the DB that is already open (or perhaps check to see if there is an instance open, and to use it if so). Eventually I'd like to be able to have a button on this form in Access that when pushed will run the VB.Net app. and automate the data-entry back into that form.

I was thinking of using GetObject method, but according to the MS site, that method will not allow one to control the Access application, and so they recommend using the OpenCurrentDatabase function instead. Is this the problem; is there a different function I can use to gain control of the already running Access instance? Or is my problem with initializing oAccess with a New Access.Application? Or am I going about this automation completely wrong?
Pyth007
I think I've solved it...
I actually did end up using GetObject instead of OpenCurrentDatabase. I'm not sure why the MS site says that you can't "control" the app. if you use GetObject; perhaps they meant that you're program would have *exclusive* control, whereas with OpenCurrentDatabase, you can specify whether you want to open the DB under exclusive or shared mode. Anyways, I was able to use GetObject and perform the data entry as I had hoped to do.

One more cursious thing that I noted, which I'd be interested to learn if anyone has ideas about it: After I am finished with the data entry, etc., if I try to close the DB, I get an error saying that the old DB cannot be deleted and that the compressed DB will be saved as db1.mdb (I have the DB set to Compact on Close). I've found, however, that I can get around this problem if I were to close the VB.net app. after the data entry has been completed. I'm therefore thinking that it may have to do with the app. having some pointer still accessing the DB while the app. is running. I thought I was being good about setting all object variables to Nothing as well as using ystem.Runtime.InteropServices.Marshal.ReleaseComObject since it sounds like this is also needed to release all access to the DB, but perhaps I'm still missing something. Here is the rest of my code, to see if anyone can spot where my problem lies:
CODE
' ... Previous code from above post, except that I'm using GetObject() instead.
        ' Release Application object and allow Access to be closed by user:
        If Not oAccess.UserControl Then oAccess.UserControl = True
        System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtrl)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtrls)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
        oAccess = Nothing
        oCtrls = Nothing
        oCtrl = Nothing
        Me.Close()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.