Romero: Überprüfen, ob eine gewisse Excel-Mappe offen ist

Hallöchen an euch da draußen,

ich möchte gern wissen, wie ich überprüfen kann, ob eine diverse EXCEL-Mappe offen ist oder nicht. Um sie dann, wenn sie offen ist, zu speichern.

Der Hintergrund ist der, dass ich erst von Javascript (Hauptcode) in VBScript übergehe, da eine gewisse EXCEL-Mappe öffnen lasse, da diverse Tabellenblätter dynamisch erstellen lasse und dann ein Makro aufrufe. Danach geht das Script von VBScript zurück in Javascript, und da möchte ich halt abfragen, ob der User die Mappe, welches die neuen Tabellenblätter mittels VBScript enthält, speichern möchte.

Die Mappe öffnet sich im Hintergrund und wartet auf die Eingabe des Users.
Wenn der User also auf Speichern drückt, dann soll die Mappe gespeichert und die EXCEL-Applikation geschlossen werden.

Und da weiß ich nicht, wie ich überprüfen kann, ob eine bestimmte Mappe offen ist oder nicht.

LG Romero

  1. Hallöchen an euch da draußen,

    ich möchte gern wissen, wie ich überprüfen kann, ob eine diverse EXCEL-Mappe offen ist oder nicht. Um sie dann, wenn sie offen ist, zu speichern.

    Für vbs hab eich was gefunden:

    http://www.vb-paradise.de/programmieren/visual-basic-script-vbs-active-server-pages-asp/91128-vbs-prozess-exe-abfrage/

    In JS - zumindest dem klassischen "Webseiten-JS" - halte ich es für ein Unding. Machst in node.js?

    Der Hintergrund ist der, dass ich erst von Javascript (Hauptcode) in VBScript übergehe, da eine gewisse EXCEL-Mappe öffnen lasse, da diverse Tabellenblätter dynamisch erstellen lasse und dann ein Makro aufrufe. Danach geht das Script von VBScript zurück in Javascript, und da möchte ich halt abfragen, ob der User die Mappe, welches die neuen Tabellenblätter mittels VBScript enthält, speichern möchte.

    Klingt in meinen Ohren ziemlich verkorkst. Aber ich weiß ja auch nicht, woran Du arbeitest und warum genau Du solche Bockstürze machst.

    Jörg Reinholz

    1. Hallo Jörg,

      Für vbs hab eich was gefunden:

      http://www.vb-paradise.de/programmieren/visual-basic-script-vbs-active-server-pages-asp/91128-vbs-prozess-exe-abfrage/

      In VBS hab ich auch was gefunden aber ich brauche das in Javascript, weil ich diese Buttons mit dem speichern gern einbinden will.
      Übrigend meine Datei ist eine *.HTA-Datei.

      In JS - zumindest dem klassischen "Webseiten-JS" - halte ich es für ein Unding. Machst in node.js?
      Klingt in meinen Ohren ziemlich verkorkst. Aber ich weiß ja auch nicht, woran Du arbeitest und warum genau Du solche Bockstürze machst.

      Ich könnte auch so eine Meldung auch mittels MsgBox ausgeben lassen, sieht für mich aber nich gut aus.

      Warum ich VBScript mit eingebunden habe, ist der Grund, dass ich mit VBScript auf eine Personal Communications von IBM zugreife und ich auf dieser Seite die Befehle für den Zugriff habe, habe ich da also weiter in VBS geschrieben und mittels diesem VBS eine vorhandene EXCEL-Mappe geöffnet und da neue Tabellenblätter erstellt.

      Und da ich, wie gesagt, des Aussehens zu Folge, einen Speicherungs-Button mittels Javascript erstellen möchte, welches dann diese Mappe speichert, wollte ich wissen, wie man überprüfen kann, ob diese jeweiligen Mappen schon offen sind oder nicht.

      Sollte das Ganze so nicht funktionieren, muss ich halt die Erstellung neuer Tabellenblätter mittels Javascript machen.

      LG Romero

      1. Hi,

        Für vbs hab eich was gefunden:

        Wo ist dann das Problem? Du rufst doch jetzt auch schon vbs aus Javascript auf.
        Warum dann nicht auch für die Kontrolle, ob die Datei offen ist?

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        O o ostern ...
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
        1. Hi,

          Für vbs hab eich was gefunden:

          Wo ist dann das Problem? Du rufst doch jetzt auch schon vbs aus Javascript auf.
          Warum dann nicht auch für die Kontrolle, ob die Datei offen ist?

          cu,
          Andreas

          Du meinst, Abruf in VBS starten, wenn er war ist, return-Anweisung von VBS-Funktion zurück an Javascript und wenn er z.B. true ist, dann weitere Dinge starten?

          LG Romero

          1. Hi nochmal,

            Wo ist dann das Problem? Du rufst doch jetzt auch schon vbs aus Javascript auf.
            Warum dann nicht auch für die Kontrolle, ob die Datei offen ist?

            cu,
            Andreas

            Wenn ich also aus Javascript diese VBScript-Funktion(en) starte, starte ich ebenso eine Excel-Applikation und eine dazugehörige Mappe:

            Function EXCEL_Tabelle_erstellen()  
              
            	Set OpenExcel = CreateObject("Excel.Application")  
            	Set OpenWorkbook = OpenExcel.Workbooks.Open( C:\test.xls" )  
              
            End Function
            

            Damit bleibt ja die Mappe so lange offen bis ich sie entweder händisch oder über das Script schließe.
            Aber woher weiß das Script, welche Mappe offen ist? Wenn ich in VBScript bleibe, kann ich ja die Mappe mittels ...

            OpenExcel.Workbooks.Close  
            OpenExcel.Quit
            

            ... schließen.

            Auch wenn ich in VBScript eine passende Abfrage starte, wo ich das Öffnen dieser Mappe erfrage, so weiß doch Javascript nicht, welche Mappe offen ist. Oder kann ich einfach aus VBScript zurück in Javascript gehen und dann einfach mit ...

            workbook.Close();  
            excelApp.Quit();
            

            ... schließen? Schließt bzw. Speichert er mir auch die richtige Mappe ab?

            Wenn jemand eine kurze Anleitung hätte, wäre ich euch dankbar.

            LG Romero

      2. In VBS hab ich auch was gefunden aber ich brauche das in Javascript, weil ich diese Buttons mit dem speichern gern einbinden will.

        Dann geht das so auch in JS gehen. VBS benutzt nur die COM-Interfaces von Excel über ActiveX.
        Diese kannst du dann natürlich auch mit JS nutzen. Du musst nur die Syntax anpassen.

        1. Hy,

          Dann geht das so auch in JS gehen. VBS benutzt nur die COM-Interfaces von Excel über ActiveX.
          Diese kannst du dann natürlich auch mit JS nutzen. Du musst nur die Syntax anpassen.

          Ich habe grad einiges ausprobiert, getestet und durchgelesen aber was passendes war nicht dabei.

          Mein Versuch sah da wie folgt aus:

          VBScript:

          Dim i, dudu  
          For i = 1 To OpenExcel.Workbooks.Count  
          	If OpenExcel.Workbooks(i).FullName = OpenWorkbook.FullName Then  
          		dudu = OpenExcel.Workbooks(i).FullName  
          	End If  
          Next  
          			  
          EXCEL_Tabelle_erstellen = dudu
          

          Da werden alle Mappen, welche offen sind, durchlaufen und geprüft, ob diese mit meiner Datei übereinstimmen. Nicht das ausversehen andere gelöscht, gespeichert, usw. werden.

          Wenn ich das ermittelt habe, gehts zurück an Javascript und da versuche ich mittels ...

          var abc = new VBArray( EXCEL_Speicherung );  
          var eee = abc.getItem(0);  
          eee.Close();
          

          ... die eine Mappe zu schließen. Und da bringt er mir die Fehlermeldung, dass das "Objekt diese Eigenschaft oder Methode nicht unterstützt".

          Ich komm da echt nicht weiter. Klar sind die Befehle oder die Anweisungen wie ich z.B. eine Excel-App bzw. eine Excel-Mappe in Javascript und VBScript erstelle oder öffne, aber wie kann ich beides verbinden?

          In VBScript öffnen, und dann in Javascript speichern und schließen.

          LG Romero

          1. Mein Versuch sah da wie folgt aus:

            Das musst du dann nur auf JS anpassen

              
            var OpenExcel = new new ActiveXObject("Excel.Application");  
            var i, dudu;  
            for (i = 1; i <= OpenExcel.Workbooks.Count; ++i)  
            {  
              alert(OpenExcel.Workbooks(i).FullName);  
            }  
              
            
            > Da werden alle Mappen, welche offen sind, durchlaufen und geprüft, ob diese mit meiner Datei übereinstimmen. Nicht das ausversehen andere gelöscht, gespeichert, usw. werden.  
            
            den Dateinamen musst du dir noch besorgen  
              
            
            > Wenn ich das ermittelt habe, gehts zurück an Javascript und da versuche ich mittels ...  
            >   
            > [code lang=javascript]var abc = new VBArray( EXCEL_Speicherung );  
            > var eee = abc.getItem(0);  
            > eee.Close();
            
            

            was ist VBArray? ein Objekt von dir?
            Per Interface Marshaling solltest du auch dein Objekt aus VBS nach JS einfach zurückgeben können.

            1. Hy,

              Das musst du dann nur auf JS anpassen

              var OpenExcel = new new ActiveXObject("Excel.Application");
              var i, dudu;
              for (i = 1; i <= OpenExcel.Workbooks.Count; ++i)
              {
                alert(OpenExcel.Workbooks(i).FullName);
              }

              Und das zeigt mir dann die bisher geöffnete Mappe an?
              Und anhand dieser Infos kann ich dann auch mittels *.Close() die Mappe schließen?

              [code lang=javascript]var abc = new VBArray( EXCEL_Speicherung );
              var eee = abc.getItem(0);
              eee.Close();

              
              > was ist VBArray? ein Objekt von dir?  
              > Per Interface Marshaling solltest du auch dein Objekt aus VBS nach JS einfach zurückgeben können.  
                
              Das VBArray kommt von dieser [Seite](http://msdn.microsoft.com/de-de/library/ie/y39d47w8%28v=vs.94%29.aspx), da wo ich Arrays von VBScript in Javascript umwandeln kann.  
                
              LG Romero
              
              1. Und das zeigt mir dann die bisher geöffnete Mappe an?

                Wenn OpenExcel.Workbooks alle offenen Mappen anzeigt dann ja. Macht es aber glaube ich nicht, sondern nur die von dieser Instanz geöffneten. Dann musst du aber auch nicht prüfen, ob ausversehen andere gelöscht, gespeichert, usw. werden, weil es sich nur um deine handeln kann.
                Dann müsstest du dein OpenExcel-Objekt noch nach JS übertragen.

                Und anhand dieser Infos kann ich dann auch mittels *.Close() die Mappe schließen?

                Das:
                <script type="text/vbscript">
                Function EXCEL_Tabelle_erstellen()
                  Set OpenExcel = CreateObject("Excel.Application")
                  Set OpenWorkbook = OpenExcel.Workbooks.Open( "C:\test.xls" )
                  Set EXCEL_Tabelle_erstellen = OpenWorkbook
                End Function
                </script>
                <script type="text/javascript">
                var OpenWorkbook = EXCEL_Tabelle_erstellen();
                alert(OpenWorkbook.Fullname);
                OpenWorkbook.Close();
                </script>
                sollte funktionieren.

                1. Und das zeigt mir dann die bisher geöffnete Mappe an?
                  Wenn OpenExcel.Workbooks alle offenen Mappen anzeigt dann ja. Macht es aber glaube ich nicht, sondern nur die von dieser Instanz geöffneten. Dann musst du aber auch nicht prüfen, ob ausversehen andere gelöscht, gespeichert, usw. werden, weil es sich nur um deine handeln kann.
                  Dann müsstest du dein OpenExcel-Objekt noch nach JS übertragen.

                  Und anhand dieser Infos kann ich dann auch mittels *.Close() die Mappe schließen?
                  Das:
                  <script type="text/vbscript">
                  Function EXCEL_Tabelle_erstellen()
                    Set OpenExcel = CreateObject("Excel.Application")
                    Set OpenWorkbook = OpenExcel.Workbooks.Open( "C:\test.xls" )
                    Set EXCEL_Tabelle_erstellen = OpenWorkbook
                  End Function
                  </script>
                  <script type="text/javascript">
                  var OpenWorkbook = EXCEL_Tabelle_erstellen();
                  alert(OpenWorkbook.Fullname);
                  OpenWorkbook.Close();
                  </script>
                  sollte funktionieren.

                  Ok danke dir erstmal.

                  Werde das demnächst ausprobieren und ein Feedback geben.

                  LG Romero

                2. Hy unknown,

                  habe es so gemacht, wie du es beschrieben hast:

                  VBScript:

                  Function EXCEL_Tabelle_erstellen()  
                  	Dim OpenExcel, OpenWorkbook  
                  	Set OpenExcel = CreateObject("Excel.Application")  
                  	Set OpenWorkbook = OpenExcel.Workbooks.Open( "C:\\blablub.xls" )  
                    
                  	'Internes Makro starten und ausführen'  
                  	OpenExcel.Run "Script_Buttonklick_A320.Script_Buttons_erstellen"  
                    
                  	Set EXCEL_Tabelle_erstellen = OpenWorkbook  
                  End Function
                  

                  Javascript:

                  VBSCode_EXCEL_Start( EXCEL_Tabelle_erstellen() );  
                  function VBSCode_EXCEL_Start( EXCEL_Speicherung )  
                  {  
                  	alert( EXCEL_Speicherung.FullName )  
                  	EXCEL_Speicherung.Save();  
                  	EXCEL_Speicherung.Close();  
                  };
                  

                  Wenn ich das SO mache, wie oben beschrieben, läuft er zwar das interne Makro durch (wird ausgeführt), aber wenn ich das mittels .Save() speichern möchte, bleibt die Datei offen, wartet und es kommt eine Meldung hoch, ob ich die Mappe speichern möchte.
                  Wenn ich auf JA klicke, kommt da dieses Speicherfenster hoch mit folgender "Datei": -> :.xls (unter C:\Dokumente und Einstellungen\Eigene Dateien...)
                  Das ist aber weder der richtige Name noch der richtige Pfad.

                  Wenn ich auf NEIN klicke, dann kommt folgende Fehlermeldung:
                  Out of memory at line: 4257
                  Wo meine .Save()-Anweisung drin steht.

                  Wenn ich aber vorher dieses Mappen-interne Makro nicht automatisch starten lasse, bringt er mir spätestens beim Schießen der Mappe eine Debug-Meldung, wo ich den VBA-Script sehe und mir die "besagte fehlerhafte Zeile" anzeigt.

                  VBA-Code der besagten Stelle:
                  Set varButton = .Buttons.Add(Anfangsspalte(Application.Match(wsTarget.Name, arrSheets, 0) - 1), arrCounter(Application.Match(wsTarget.Name, arrSheets, 0) - 1), Buttonbreite, 15)
                  Und da verweist er auf "Buttons" hin (Fehlermeldung: Die Add-Eigenschaft des Buttons-Objektes kann nicht zugeordnet werden).

                  Dieses Makro startet, wenn die Mappe geschlossen wird und bewirkt, dass zu jedem Tabellenblatt auf einer Übersichtsseite Buttons gebildet werden um schneller auf das (über 400 Blätter) jeweilige Blatt zuzugreifen.

                  1. Händisch die Mappe öffnen -> Blatt einfügen -> Schließen -> Makro für die Buttons ausführen -> Speichern => klappt
                  2. automatisch Mappe öffnen -> Blatt einfügen -> internes Makro aufrufen -> Speichern => klappt nicht
                  3. automatisch Mappe öffnen -> Blatt einfügen -> automatisch Schließen -> Speichern (wird nicht ausgeführt obwohl es vor dem Schließen kommt) => klappt nicht

                  Und da bin grad echt überfragt.

                  LG Romero

                  1. Ich hab es gerade mal getestet,
                     * eine leere Excel-Datei angelegt
                     * folgenden Code einfügt

                      
                    Sub Button_klick()  
                      MsgBox ("Test")  
                    End Sub  
                      
                    Function Buttons_erstellen()  
                      Dim Target  
                      Set Target = Range("A" & 1)  
                      Set Button = ActiveSheet.Buttons.Add(Left:=Target.Left, Top:=Target.Top, Width:=Target.Width, Height:=Target.Height)  
                      Button.PrintObject = False  
                      Button.Name = "Test"  
                      Button.Caption = "Test"  
                      Button.OnAction = "DieseArbeitsmappe.Button_klick"  
                    End Function  
                    
                    

                    * im HTML folgenden Code global eingefügt

                      
                    <script type="text/vbscript">  
                    Function EXCEL_Tabelle_erstellen()  
                      Dim OpenExcel, OpenWorkbook  
                      Set OpenExcel = CreateObject("Excel.Application")  
                      Set OpenWorkbook = OpenExcel.Workbooks.Open( "C:\\test.xls" )  
                      
                      'Internes Makro starten und ausführen'  
                      OpenExcel.Run "DieseArbeitsmappe.Buttons_erstellen"  
                      
                      Set EXCEL_Tabelle_erstellen = OpenWorkbook  
                    End Function  
                    </script>  
                    <script type="text/javascript">  
                    VBSCode_EXCEL_Start( EXCEL_Tabelle_erstellen() );  
                    function VBSCode_EXCEL_Start( EXCEL_Speicherung )  
                    {  
                      alert( EXCEL_Speicherung.FullName )  
                      EXCEL_Speicherung.Save();  
                      EXCEL_Speicherung.Close();  
                    };  
                    </script>  
                    
                    

                    wenn ich das HTML-File im öffne und danach meine Excel-Datei, habe ich in dieser nun einen Button.
                    ich vermute irgendwas stimmt nicht mit den Argumenten, die du Add übergobst.

                    1. Hy unknown,

                      wenn ich das HTML-File im öffne und danach meine Excel-Datei, habe ich in dieser nun einen Button.
                      ich vermute irgendwas stimmt nicht mit den Argumenten, die du Add übergobst.

                      Wie ist es bei dir, wenn du mehrere Blätter neu erstellst. Wird der "alte" Button mit der Info des neuen Buttons überschrieben? Oder hast du je nachdem wieviele Blätter du hast auch entsprechende Buttons?

                      Aber warum klappt das Ganze wenn ich das Makro:

                      1. über mein Script starten lasse,
                      2. über das händische Öffnen und beim "Sub Worksheet_BeforeClose()" über Call ausführen lasse,

                      damit beim Verlassen der Mappe alle Buttons passend zu den Blättern neu erstellt wird.

                      Das ist ja was ich nicht verstehe?

                      Beim Starten des Makro über das Script heraus, sehe ich ja, wie alle Buttons neu erstellt werden und an der richtigen Stelle sind. Aber leider da ohne "OnAction", sprich ohne Anklick-Funktion um die anderen Blätter anzusteuern.

                      Gibt es eine Möglichkeit, Makros zu deaktivieren? Hab dazu mittels Google leider nix gefunden.
                      Weil dann würde ich, sofern es unter VBScript andere Befehle gibt, da mir ein Makro basteln.
                      Oder wenn du möchtest, geb ich hier mal das besagte komplette Makro preis.

                      Ich möchte, dass der Nutzer halt mind. 2 Möglichkeiten hat:
                      1.: ein Tabellenblatt händisch einfügen. Und dann sollen die Buttons jeweils für jedes Blatt dazu kommen.
                      2.: ein Tabellenblatt mittels einem Script (automatisch) erstellen, wo dann ebenfalls die Buttons für jedes Blatt erstellt werden.

                      Bisher aber von dir dir, vielen vielen lieben Dank. Hast mir bis hier her sehr sehr weiter geholfen.

                      LG Romero

                      1. Wie ist es bei dir, wenn du mehrere Blätter neu erstellst. Wird der "alte" Button mit der Info des neuen Buttons überschrieben? Oder hast du je nachdem wieviele Blätter du hast auch entsprechende Buttons?

                        Ich habe nur einen Button in einer vorhandenen Tabelle erstellt, um zu prüfen, ob es prinzipiell geht.

                        Aber warum klappt das Ganze wenn ich das Makro:

                        1. über mein Script starten lasse,
                        2. über das händische Öffnen und beim "Sub Worksheet_BeforeClose()" über Call ausführen lasse,

                        Keine Ahnung, da stimmen vielleicht irgendwelche Randbedingungen, die im automatischem Fall nicht gegeben sind.

                        Das ist ja was ich nicht verstehe?

                        Bau doch ein paar Debugausgaben ein um zu prüfen welche Werte an Add übergeben werden.

                        Beim Starten des Makro über das Script heraus, sehe ich ja, wie alle Buttons neu erstellt werden und an der richtigen Stelle sind. Aber leider da ohne "OnAction", sprich ohne Anklick-Funktion um die anderen Blätter anzusteuern.

                        Also läuft irgendwas anders als im automatischem Fall, warum auch immer.

                        Gibt es eine Möglichkeit, Makros zu deaktivieren? Hab dazu mittels Google leider nix gefunden.

                        Keine Ahnung, das MSDN wird aber auch von Jahr zu Jahr besch...
                        Kannst ja mal hier versuchen was zu finden.

                        Weil dann würde ich, sofern es unter VBScript andere Befehle gibt, da mir ein Makro basteln.

                        Verstehe ich nicht, aber nochmal, Excel bietet Interfaces an. Die kannst du überall verwenden, wo du ActiveX-Objekte anlegen kannst. Diese Interfaces sind immer die selben, ob in VBS, JS oder Perl, oder C++ oder oder oder.

                        Ich möchte, dass der Nutzer halt mind. 2 Möglichkeiten hat:
                        1.: ein Tabellenblatt händisch einfügen. Und dann sollen die Buttons jeweils für jedes Blatt dazu kommen.
                        2.: ein Tabellenblatt mittels einem Script (automatisch) erstellen, wo dann ebenfalls die Buttons für jedes Blatt erstellt werden.

                        Kann es sein, dass der Button im 2. Fall im Makro für den 1. Fall nich angelegt werden kann, weil er einmal vom Script und einmal vom Makro erstellt werden soll?

                        1. Hy unknown,

                          Das ist ja was ich nicht verstehe?
                          Bau doch ein paar Debugausgaben ein um zu prüfen welche Werte an Add übergeben werden.

                          Ich habe folgendes getestet:

                          Ich habe mir vor dem .Button.Add(Anfangsspalte(Application.Match(wsTarget.Name, arrSheets, 0) - 1), arrCounter(Application.Match(wsTarget.Name, arrSheets, 0) - 1), Buttonbreite, 15) die Parameter vorher ausgegeben und das sind Zahlen, welches die Position des Buttons wiederspiegeln.

                          Weiterhin habe ich mir, ohne das Makro über das Script aufzurufen (nur .Close() in JS), diese Werte ausgegeben und da wurde nur der Wert für den 1. Button angezeigt, dann die Fehlermeldung, dass die Add-Methode für das Button-Objekt nicht verwendet werden kann. Also das was bisher auch immer kam.

                          Nun habe ich danach diesen Makro-Ausführ-Befehl mittels Call unterbunden und das Makro aus meinem Script gestartet. Und siehe da, alle Buttons mit der dazugehörigen OnAction-Funktion klappt wunderbar.

                          Hat es was mit meinem Sub in der EXCEL-Mappe zu tun?
                          Es sieht da so aus:

                          Private Sub Workbook_BeforeClose(Cancel As Boolean)  
                            
                              Blattzähler_Ende = ThisWorkbook.Sheets.Count  
                            
                              'Array() bilden für die Blätter als Vergleich, ob sich Tab.-Namen verändert hat'  
                              ReDim Blattanzahl_Ende(ThisWorkbook.Sheets.Count)  
                              Dim ws As Worksheet, Blattnamen_Veränderung As String  
                              Dim i As Integer, j As Integer  
                              i = 0  
                            
                              For Each ws In ThisWorkbook.Worksheets  
                                  Blattanzahl_Ende(i) = ws.Name  
                                  i = i + 1  
                              Next  
                            
                              'Vergleich der Blattnamen beim Öffnen und beim Schließen'  
                              If Blattzähler_Start = Blattzähler_Ende Then  
                                  For j = LBound(Blattanzahl_Ende) To UBound(Blattanzahl_Ende)  
                                      If Blattanzahl_Start(j) <> Blattanzahl_Ende(j) Then  
                                          Blattnamen_Veränderung = "zutrefflich"  
                                      End If  
                                  Next  
                              End If  
                            
                              If Blattzähler_Start <> Blattzähler_Ende Or Blattnamen_Veränderung = "zutrefflich" Then  
                                  'Call Buttonklick_A320.Buttons_erstellen'  
                              End If  
                            
                          End Sub
                          

                          Je nachdem Veränderungen sind, egal ob veränderter Name oder Anzahl der Blätter sollen neue Buttons erstellt werden.

                          Aber nachdem der letzte Test erfolgreich war, kommt beim .Close() in JS, wieder die Meldung hoch mit dem Speichern.
                          Drücke ich das 1. mal auf JA passiert nix, dann diese Meldung wieder. Drücke da wieder auf JA und da kommt der Pfad zu meinen Eigenen Dateien und der Speichername der Datei lautet wie folgt: ":.xls".

                          Ich möchte, dass der Nutzer halt mind. 2 Möglichkeiten hat:
                          1.: ein Tabellenblatt händisch einfügen. Und dann sollen die Buttons jeweils für jedes Blatt dazu kommen.
                          2.: ein Tabellenblatt mittels einem Script (automatisch) erstellen, wo dann ebenfalls die Buttons für jedes Blatt erstellt werden.
                          Kann es sein, dass der Button im 2. Fall im Makro für den 1. Fall nich angelegt werden kann, weil er einmal vom Script und einmal vom Makro erstellt werden soll?

                          Die Buttons werden vorher alle gelöscht mit dem Aufruf des Makros.
                          Also egal, welchen Weg man da geht, es kommt zu keiner Überlappung oder Zuweisung gleicher OnAction für ein und denselben Button.

                          LG Romero

                          1. NACHTRAG:

                            Ich habe nun, nach weiteren Tests, folgendes rausbekommen:

                            Für das Speichern:
                            Ich hatte ja angeführt, dass das Speichern auch nicht funktioniert. Da ich in meiner Mappe eine Sub namens Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) habe, vermute ich, dass es daran liegt. Genauer gesagt an den Parametern. Denn wenn ich diese ganze Sub weglasse und dann über das Script speichern lasse (*.Save()), funktioniert es ebenfalls.

                            Ich muss diese Parameter aber übergeben, weil sonst gibt er mir in VBA diese Fehlermeldung aus:
                            Fehler beim Kompilieren:
                            Deklaration der Prozedur entspricht nicht der Beschreibung eines Ereignisses oder einer Prozedur mit demselben Namen.

                            Für das Schließen: (und Buttons erstellen)
                            Bei der besagten Sub Workbook_BeforeClose(Cancel As Boolean) dasselbe Problem und da denke ich, daran liegt es: An diesem Cancel As Boolean.

                            Wie kann ich das umgehen? Oder was muss ich anders schreiben, dass es funktioniert?

                            LG Romero

                            1. Für das Speichern:
                              Ich hatte ja angeführt, dass das Speichern auch nicht funktioniert. Da ich in meiner Mappe eine Sub namens Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) habe, vermute ich, dass es daran liegt. Genauer gesagt an den Parametern. Denn wenn ich diese ganze Sub weglasse und dann über das Script speichern lasse (*.Save()), funktioniert es ebenfalls.

                              Workbook_BeforeSave speichert ja nicht, sondern wird von Excel aufgerufen vor dem Speichern.
                              Ich glaube nicht, daß es an dieser Funktion liegt, diese hat ja keinen Einfluss auf die Buttonklick_A320.Buttons_erstellen-Funktion welche den Fehler erzeugt. Sie ruft sie nur auf, ohne Parameter und soweit ich das sehe werden auch keine globalen Variablen verändert, die von Buttonklick_A320.Buttons_erstellen verwendet werden könnten/sollten.

                              Ich muss diese Parameter aber übergeben, weil sonst gibt er mir in VBA diese Fehlermeldung aus:
                              Fehler beim Kompilieren:
                              Deklaration der Prozedur entspricht nicht der Beschreibung eines Ereignisses oder einer Prozedur mit demselben Namen.

                              Du übergibst die Parameter ja nicht, das macht Excel, du deklarierst sie nur.

                              Wie kann ich das umgehen? Oder was muss ich anders schreiben, dass es funktioniert?

                              Diese Funktionen werden doch von Excel generiert, soweit ich das gesehen habe. Die Parameter sind dann so auch richtig.

                              Mehr kann ich dazu auch nicht sagen, keine Ahnung, wo das Problem liegt. Meine Vermutung war ja, daß die Parameter für Add nicht stimmen. Das hast du ja ausgeschlossen.

                              1. Hy unknown,

                                Workbook_BeforeSave speichert ja nicht, sondern wird von Excel aufgerufen vor dem Speichern.
                                Ich glaube nicht, daß es an dieser Funktion liegt, diese hat ja keinen Einfluss auf die Buttonklick_A320.Buttons_erstellen-Funktion welche den Fehler erzeugt. Sie ruft sie nur auf, ohne Parameter und soweit ich das sehe werden auch keine globalen Variablen verändert, die von Buttonklick_A320.Buttons_erstellen verwendet werden könnten/sollten.

                                Wie gesagt, ich denke, dass es nicht direkt an meinem Makro liegt. Weil mit explizitem Aufruf OpenExcel.Run "Buttonklick_A320.Buttons_erstellen" im VBScript, kann ich ja dieses Makro starten.

                                Der Fehler tritt erst auf, wenn ich die Mappe mittels JS schließen möchte. Und da ich aber in EXCEL in der Mappe, diverse Sub's habe (Workbook_BeforeSave() & Workbook_BeforeClose()), vermute ich, dass es an den beiden Sub's Workbook_BeforeSave() & Workbook_BeforeClose() liegt (nach ausgiebigen Tests herausgefunden).

                                Gehe ich also den einfachen Schritt:
                                Javascript starten -> Dateneingabe -> Daten an VBScript übergeben -> in VBScript Tabellenblatt mit den Daten erstellen (Mappe ist offen und enthält verschiedene Sub's) -> zurück an Javascript -> Button mit Speichern & Beenden -> Speicher-Button drücken und Mappe Speichern und schließen.

                                Lasse ich z.B. Workbook_BeforeSave() & Workbook_BeforeClose() weg, und gehe, wie oben beschrieben, den einfach Weg, dann bekomm ich weder eine Fehlermeldung noch irgendwas anderes. Die Mappe wird gespeichert und geschlossen.

                                Wenn ich also die Mappe in JS schließen möchte, wird in der Mappe ja das Sub Workbook_BeforeClose() gestartet. Und da "beißt" sich halt irgendwas miteiander. Das selbe ist bei Workbook_BeforeSave() der Fall, wenn ich aus JS speichern möchte.

                                Leider würde ich die beiden Sub's aber weiterhin nutzen wollen. Aber das geht halt leider nicht. Oder gibt es die Möglichkeit, aus JS zu EXCEL, explizite Sub's auszuklammern bzw. an der Ausführung zu hindern?
                                In VBA gibt es da eine Möglichkeit mit Application.EnableEvents = False (Makros ausschalten).

                                LG Romero

                                1. In VBA gibt es da eine Möglichkeit mit Application.EnableEvents = False (Makros ausschalten).

                                  Dann geht das genau si auch in JS.

                                  1. Ich habe die Lösung:

                                    Ich baue in meiner Mappe ein weiteres Modul ein.

                                    In diesem Modul deklariere ich eine globale (Public) Variable:

                                      
                                    Option Explicit  
                                      
                                    Public Status As Boolean   ' False = Aufruf nich vom VB-Script'  
                                                               ' True = Aufruf vom VB-Script'  
                                      
                                    Private Sub setStatus()  
                                        Status = True  
                                    End Sub
                                    

                                    Dann baue ich eine Abfrage in BeforeClose() bzw. BeforeSave() ein:

                                      
                                    Private Sub Workbook_BeforeClose(Cancel As Boolean)  
                                        If Status Then Exit Sub  
                                    End Sub  
                                      
                                    Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  
                                        If Status Then Exit Sub  
                                    End Sub
                                    

                                    Und diese ganze Sache starte ich aus meinem VBScript heraus:

                                    Dim ExcelApp, ExcelWB  
                                    Set ExcelApp= createobject("Excel.Application")  
                                    Set ExcelWB = ExcelApp.Workbooks.Open("C:\Mappe.xls")  
                                    ExcelApp.Run "Mappe.xls!modul1.setStatus"
                                    

                                    Das Ganze bewirkt, dass die Variable "Status" als FALSE gesetzt wurde.
                                    Öffne ich nun die Mappe händisch, so bleibt Status = FALSE. Öffne ich aber aus meinem Script heraus, so wird die Funktion setStatus ausgeführt, wo Status nun auf TRUE gesetzt wird.
                                    Und wenn das ist, dann werden die beiden Sub's (Workbook_BeforeClose & Workbook_BeforeSave) verlassen, noch bevor sie ausgeführt werden.

                                    Ich danke dir trotzdem unknown für die vielen zahlreichen Tipps, gerade das übergeben eines Objektes an JS zurück.

                                    Weiß du auch, wie man z.B. 2 Objekte gleichzeitig übergibt?

                                    LG Romero

                                    1. Weiß du auch, wie man z.B. 2 Objekte gleichzeitig übergibt?

                                      Als Objekt?

                                      1. Weiß du auch, wie man z.B. 2 Objekte gleichzeitig übergibt?
                                        Als Objekt?

                                        Wie jetzt? Sorry das ich das frage, aber kannst du mal n kurzes Bsp. zeigen?

                                        1. Wie jetzt? Sorry das ich das frage, aber kannst du mal n kurzes Bsp. zeigen?

                                          Ich hab auch keine Ahnung von VB, aber wie man dort Objekte anlegt ist eigentlich schnell gegoogelt:

                                          <script type="text/vbscript">
                                          class myExcelObj
                                            public Application
                                            public Workbook
                                          end class
                                          Function EXCEL_Tabelle_erstellen()
                                            Dim OpenExcel, OpenWorkbook
                                            Set OpenExcel = CreateObject("Excel.Application")
                                            Set OpenWorkbook = OpenExcel.Workbooks.Open( "C:\test.xls" )

                                          set e = new myExcelObj
                                            set e.Application = OpenExcel
                                            set e.Workbook = OpenWorkbook

                                          Set EXCEL_Tabelle_erstellen = e
                                          End Function
                                          </script>

                                          <script type="text/javascript">
                                          VBSCode_EXCEL_Start( EXCEL_Tabelle_erstellen() );
                                          function VBSCode_EXCEL_Start( EXCEL )
                                          {

                                          EXCEL.Workbook.Worksheets.Add();
                                            EXCEL.Workbook.ActiveSheet.Name = "Test_" + EXCEL.Workbook.Worksheets.Count;

                                          'Internes Makro starten und ausführen'
                                            EXCEL.Workbook.Parent.Run("'DieseArbeitsmappe.Buttons_erstellen " + 1 + ", "js"'");

                                          EXCEL.Workbook.Save();
                                            EXCEL.Application.Quit();

                                          };
                                          </script>

                                          Es liegt mit großer Wahrscheinlichkeit doch am Before_Close-Handler, bzw. am Close.
                                          Wenn man Workbook.Close() aufruft läuft irgendwas anders, als wenn man das Document im Excel manuell schließt. Dann sind im Before_Close-Handler nicht mehr alle Aktionen möglich, die im Normalfall möglich sind. Auf jeden Fall in Bezug auf das Worksheet.Buttons Objekt.
                                          Vielleicht ist das der Grund, warum es als hidden gekennzeichnet ist.

                                          1. Hy unknown,

                                            Du hast mir sehr sehr geholfen. Vielen vielen lieben Dank an dich.
                                            Jetzt kann ich meine Mappe schließen und auch die Excel-Applikation beenden.

                                            Nochmals: 1000 Dank.

                                            LG Romero