Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7640305
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T08:38:13+00:00 2026-05-31T08:38:13+00:00

I have a C# program that opens several Microsoft Access files, and executes functions

  • 0

I have a C# program that opens several Microsoft Access files, and executes functions from within each one.

Essentially, the code looks something like this:

Microsoft.Office.Interop.Access.Application app =
    new Microsoft.Office.Interop.Access.Application();

app.Visible = true;
app.OpenCurrentDatabase(accessFileFullPath, false, "");

//Call the function
app.Eval(function);

However, when a debug error occurs in the VBA code, I would like to trap it in my C# program.

Please don’t answer: “trap the error in your VBA program”. For reasons that I will not get into, this is not possible.

A method that I have used in the past is to have a thread intermittently monitor for a handle to any Visual Basic Debug window (the FindWindowEx Win32 function returns a nonzero value). I do not like this method, and don’t want to continue to using it.

I found this thread, which applies to Microsoft Excel. In essence, it uses the Microsoft.VisualBasic.CallByName() function, which apparently can be trapped in a try/catch block, without user interaction. However, I have not been able to get this to work with Microsoft Access– primarily because I cannot figure out how to call the function/sub using this command.

Any suggestions would be sincerely appreciated!

Edit: As I mentioned in one of the answers below, I have tried wrapping the Eval() in a try/catch block and my C# program seems to ignore it, until a user hits the “End” button on the “Microsoft Visual Basic” error dialog. I do not want any user interaction, but rather want to trap the VBA error for handling in my C# program.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T08:38:15+00:00Added an answer on May 31, 2026 at 8:38 am

    Update: For some reason, the previous code I had posted had only worked when the Access file format was 2000. I have confirmed that this new code also works with Access 2002 and 2010 files.

    The code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using VBA = Microsoft.Vbe.Interop;
    
    namespace CaptureVBAErrorsTest
    {
        class CaptureVBAErrors
        {
            public void runApp(string databaseName, string function)
            {
                VBA.VBComponent f = null;
                VBA.VBComponent f2 = null;
                Microsoft.Office.Interop.Access.Application app = null;
                object Missing = System.Reflection.Missing.Value;
                Object tempObject = null;
    
                try
                {
                    app = new Microsoft.Office.Interop.Access.Application();
                    app.Visible = true;
                    app.OpenCurrentDatabase(databaseName, false, "");
    
                    //Step 1: Programatically create a new temporary class module in the target Access file, with which to call the target function in the Access database
    
                    //Create a Guid to append to the object name, so that in case the temporary class and module somehow get "stuck",
                    //the temp objects won't interfere with other objects each other (if there are multiples).
                    string tempGuid = Guid.NewGuid().ToString("N");
    
                    f = app.VBE.ActiveVBProject.VBComponents.Add(VBA.vbext_ComponentType.vbext_ct_ClassModule);
    
                    //We must set the Instancing to 2-PublicNotCreatable
                    f.Properties.Item("Instancing").Value = 2;
                    f.Name = "TEMP_CLASS_" + tempGuid;
                    f.CodeModule.AddFromString(
                        "Public Sub TempClassCall()\r\n" +
                        "   Call " + function + "\r\n" +
                        "End Sub\r\n");
    
                    //Step 2: Append a new standard module to the target Access file, and create a public function to instantiate the class and return it.
                    f2 = app.VBE.ActiveVBProject.VBComponents.Add(VBA.vbext_ComponentType.vbext_ct_StdModule);
                    f2.Name = "TEMP_MODULE_" + tempGuid
                    f2.CodeModule.AddFromString(string.Format(
                        "Public Function instantiateTempClass_{0}() As Object\r\n" +
                        "    Set instantiateTempClass_{0} = New TEMP_CLASS_{0}\r\n" +
                        "End Function"
                        ,tempGuid));
    
                    //Step 3: Get a reference to a new TEMP_CLASS_* object
                    tempObject = app.Run("instantiateTempClass_" + tempGuid, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing);
    
                    //Step 4: Call the method on the TEMP_CLASS_* object.
                    Microsoft.VisualBasic.Interaction.CallByName(tempObject, "TempClassCall", Microsoft.VisualBasic.CallType.Method);
                }
                catch (COMException e)
                {
                    MessageBox.Show("A VBA Exception occurred in file:" + e.Message);
                }
                catch (Exception e)
                {
                    MessageBox.Show("A general exception has occurred: " + e.StackTrace.ToString());
                }
                finally
                {
                    //Clean up
                    if (f != null)
                    {
                        app.VBE.ActiveVBProject.VBComponents.Remove(f);
                        Marshal.FinalReleaseComObject(f);
                    }
    
                    if (f2 != null)
                    {
                        app.VBE.ActiveVBProject.VBComponents.Remove(f2);
                        Marshal.FinalReleaseComObject(f2);
                    }
    
                    if (tempObject != null) Marshal.FinalReleaseComObject(tempObject);
    
                    if (app != null)
                    {
                        //Step 5: When you close the database, you call Application.Quit() with acQuitSaveNone, so none of the VBA code you just created gets saved.
                        app.Quit(Microsoft.Office.Interop.Access.AcQuitOption.acQuitSaveNone);
                        Marshal.FinalReleaseComObject(app);
                    }
    
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
            }
        }
    }
    

    The Details:

    According to the thread I had linked to by Mike Rosenblum, CallByName() can execute Office code in C#, and can trap VBA exceptions (Application.Run() and Application.Eval() seem to only get caught after the user interacts with the debug window). The problem is that CallByName() requires an [instantiated] object to call a method on. By default, Excel has the ThisWorkbook object, which is instantiated upon opening a workbook. Access does not have a similar object that is accessible, as far as I know.

    A subsequent post on the same thread suggests adding code dynamically to the Excel workbook to allow calling of methods in standard modules. Doing so on ThisWorkbook is relatively trivial, because ThisWorkbook has a code-behind and is automatically instantiated. But how can we do this in Access?

    The solution combines the two techniques above in the following way:

    1. Programatically create a new temporary class module in the target Access file, with which to call the target function in the Access database. Keep in mind that the Instancing property of the class must be set to 2 - PublicNotCreatable. This means that the class is not creatable outside of that project, but it is accessible publicly.
    2. Append a new standard module to the target Access file, and create a public function to instantiate the class and return it.
    3. Get a reference to the object in your C# code, by calling the VBA code in step (2). This can be done using Access interop’s Application.Run().
    4. Call the method on the object from (3) using CallByName– which calls the method in the standard module, and is trappable.
    5. When you close the database, you call Application.Quit() with acQuitSaveNone, so none of the VBA code you just created gets saved.

    To get the VBA error description, use “e.Message”, where “e” is the COMException object.

    Make sure you add the following .NET references to your C# project:

    Microsoft.Office.Interop.Access
    Microsoft.Vbe.Interop
    Microsoft.VisualBasic
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a python program that opens several urls in seperate tabs in a
I'm building a program that has several functions that need to read data from
I have a Java program that opens a file using the RandomAccessFile class. I'd
I have a simple Tray icon program that opens a site using System.Diagnostics.Process.Start(URL) And
I have a program that when it starts, opens a winform (it is the
I have a program that uses the mt19937 random number generator from boost::random. I
My application have several modules, each in one tab on the mainform. When using
I have several large text text files that all have the same structure and
The Situation I have a WPF program that I want to print several documents
So I have several summary files that I want to read and get the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.