Überprüfen, ob eine gewisse Excel-Mappe offen ist
Romero
- javascript
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
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:
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
Hallo Jörg,
Für vbs hab eich was gefunden:
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
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
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
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
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.
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
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.
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
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.
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
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
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.
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
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:
- über mein Script starten lasse,
- ü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?
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
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
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.
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
In VBA gibt es da eine Möglichkeit mit Application.EnableEvents = False (Makros ausschalten).
Dann geht das genau si auch in JS.
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
Weiß du auch, wie man z.B. 2 Objekte gleichzeitig übergibt?
Als Objekt?
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?
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.
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