0

I have this dynamic Object to get the system.__comobject from Access:

   dynamic app = Marshal.GetActiveObject("Access.Application");

And now I open a form like this:

    app.Run("gbOpenDataEditPart", "ediQuali.170013662.Wawi");

and that is working. It opens the right form from Access. Now what I want is to loop if this exactly already open. I thought maybe there is a method like if(IsOpen), but it isn't open. Is there another way to loop if this is open?

And I tried it with Powershell script with that but there is the Window not there too:

$accessApp = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Access.Application")

$forms = $accessApp.CurrentProject.AllForms

foreach ($form in $forms) {
    Write-Host "Form name: $($form.Name)"
}

Example1

I can see my Application which I want to look if it is already open or not but when I look through AllForms with that:

CurrentProject.AllForms("HPGebote").IsLoaded

or

CurrentProject.AllForms("ediQuali.170013662.Wawi").IsLoaded

then there is no form which has the name I am searching for.

And no matter which Formular I will open in my Access:

Access

He will always detect frmSysAuskunft and thats It no matter how many Forms I will have Open he will always just detect one with always the same name

  • You may check the collection `app.CurrentProject.AllForms` for `.Name` equals "gbOpenDataEditPart"... – Vojtěch Dohnal Apr 17 '23 at 10:45
  • not working, it gave me a lot of Form names but none of them was that what Ive been opening in run – BeginnerWPF Apr 17 '23 at 11:18
  • See this, it's in VBA but you shouldn't have any issues: https://learn.microsoft.com/en-us/office/vba/api/access.accessobject.isloaded – Kostas K. Apr 17 '23 at 15:07
  • I must be missing something here. Using all forms .isloaded against form frmSysAuskunft should work just fine. Are you dealing with VBA or code that opens possbile multiple instnaces of the one form called frmSysAuskunft? Or are you dealing with possible multiple instances of access running? .IsLoaded will work, and ONLY returns true if the form is open in Access. There are exceptions to this rule. (does VBA code have or allow multiple instances of the form, and that form was not opened using docmd.OpenForm in the Access application. (however, you not shared these details). – Albert D. Kallal Apr 18 '23 at 14:33
  • You don't need to using windows api, and the forms handle for this checking. Your screen shot does not look like Access, so it not clear here what you are attempting. Do look again at the sample code I posted. It shows .isLoaded of the allforms collection does return true, or false based on using form name - we don't care nor use "caption" or the windows api handle here - and we don't have to unless you have some reason for doing so? – Albert D. Kallal Apr 18 '23 at 14:36
  • Are you looking to check if Access is open, or is a form open? You don't use forms colleciton to determine if access is open. You can use GetOjbect, and if it fails, then you can use createobject to launch access if you wish. So, check if access is running is VAST different issue than checking if a form is open. you don't try to check for a form open if access is not yet determined to be running. They are 100% separate concepts and not to be intermixed and confused here. If Access is not open, then there is no valid forms collection to test. – Albert D. Kallal Apr 18 '23 at 15:03
  • And forms collection is of little use, since that is a collection of forms, and that includes all forms, and even ones that are not open. As noted, you can use the .IsLoaded method of allforms if you looking to test if the form is actually open. But forms collection ALWAYS returns all forms - regardless if that form is open or not. but of course the forms collection is not valid until such time we determined that Access is running and has a valid open database. So 1st determine if Access is running. We then probably should determine if Access has a open database. Then we use forms collection. – Albert D. Kallal Apr 18 '23 at 15:05

1 Answers1

0

Ok, I just add this:

using Microsoft.VisualBasic;

And now in my code I can do this:

button to open form, button to close the form, and button to test/check if form is open.

    private void button1_Click(object sender, EventArgs e)
    {
        dynamic app = Interaction.GetObject(Class: "Access.Application");
        app.DoCmd.Openform("tblHotelsA");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        dynamic app = Interaction.GetObject(Class: "Access.Application");

        bool IsOpen = app.CurrentProject.AllForms("tblHotelsA").IsLoaded;
        MessageBox.Show($"Status of form tblHotelsA \n Open:{IsOpen.ToString()}");
    }

    private void button3_Click(object sender, EventArgs e)
    {
        dynamic app = Interaction.GetObject(Class: "Access.Application");
        app.DoCmd.Close(2,"tblHotelsA");

    }

So, the result is this:

enter image description here

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • I edited my Question with some explanation, because It dosent find an Window name in the Form part – BeginnerWPF Apr 18 '23 at 08:35
  • Well, you can use the windows api, and search by window name, but it sure is boatloads less work and effort to check + use form name and the AllForms.isloaded. However are you looking to open a form for the Access user, or are you looking to check if the form is open (has been opened by the user? You can clearly see my example code from c# is able to open the form, close the form, and also check if the form is open. So, the posted code is not only simple, but also as the screen cap gif shows works. So, using form name as opposed to window name (caption) is a FAR more reliable and easy road. – Albert D. Kallal Apr 18 '23 at 14:28