Die Excel4-Makrofunktion Symbolleiste.Zuordnen()
Inhalte einfügen
Namen zuweisen
Hilfe hilflos
Formatcodes für Seitenlayout
Hilfe in der Meldung
Pivottabellen
1993 kaufte ich mir das Microsoft-Office-Paket 6 und hatte schon im nächsten Jahr durch meine Arbeitslosigkeit viel Zeit, vor allem Excel, damals noch das Programm, mit dem ich am meisten arbeitete, zu testen. Ich will nicht Fehler unterstellen, die inzwischen behoben wurden und habe deshalb alles am Arbeitsplatz bei einer neueren Version (8) getestet. Alle hier genannten Fehler existieren noch.
Die Excel4-Makrofunktion Symbolleiste.Zuordnen() |
oben |
Ich entwarf ein Haushaltsbuch (download Zip-Datei) mit eigenem Menü und eigener Symbolleiste.Ich wollte aber nicht einfach Symbolleisten entfernen und die neue anzeigen lassen, sondern den bisherigen Zustand beim Verlassen der EXCEL-Arbeitsmappe wiederherstellen. Dazu experimentierte ich mit der Funktion "SYMBOLLEISTEN.ZUORDNEN(9)" und stellte fest, daß sie nicht so funktioniert, wie im Handbuch beschrieben wird.
Bei der Standard-Symbolleiste wurde korrekt "Standard" zurückgegeben. Dann testete ich aber mit mehreren gleichzeitig aktiven Symbolleisten. Stets wurde nur "Standard" zurückgegeben. Ich führte die Befehle über "Makro" "Makro ausführen" "schritt"weise aus und klickte dabei stets auf die "Auswerten"-Schaltfläche.
soll ein Array mit den Symbolleistennamen zurückgeben.
Standard ist aber nicht die einzige angezeigte Symbolleiste!
Ich baute "SYMBOLLEISTEN.ZUORDNEN(9)" auch in andere Befehle ein, nämlich in SPALTEN() und in NAMEN.ZUWEISEN(). Der zuletzt genannte Befehl wird auch als Beispiel im "Verzeichnis der Funktionen" aufgeführt
"Die folgende Makrofunktion liefert die Kennungen aller sichtbaren Symbolleisten und gibt dem Array den Namen "AlleSymLeiKenn": =NAMEN.ZUWEISEN("AlleSymLeiKenn";SYMBOLLEISTEN.ZUORDNEN(9))" (S. 581)
Trotzdem wurde nur in der Kombination "=SPALTEN(SYMBOLLEISTEN.ZUORDNEN(9))" korrekt ein Array mit drei Symbolleistenkennungen zurückgegeben. Ich habe sogar um unterschiedliche Schreibweisen zu vermeiden "SYMBOLLEISTEN.ZUORDNEN(9)" markiert, in die Zwischenablage kopiert und in den anderen Befehlen wieder eingesetzt. Das Ergebnis blieb dennoch wie geschildert.
soll ein Array mit den Symbolleistennamen zurückgeben und dann deren Anzahl.
Jetzt werden alle drei genannt.
Das ist zwar richtig, darum ging es aber nicht.
Ich schrieb einen Brief an Microsoft - "Woran liegt das und wie kann ich den Fehler beseitigen?" - und bekam nur zur Antwort, ich solle mich an die Hotline wenden.
Inhalte einfügen |
oben |
Diesen Fehler entdeckte ich Anfang 1999 beim Einsatz einer neueren Version am Arbeitsplatz. Ich entwickelte ein Tool, mit dem in regelmäßigen Abständen untereinander Inhalte eingefügt werden sollten, etwa wie beim Befehl "Inhalte einfügen" aus dem Menü "Bearbeiten".
Beim Einfügen von Inhalten kann man auswählen, z.B. alles oder Werte oder Formate (in der Symbolleiste der Pinsel). Als Makro wird dann z.B. aufgezeichnet:
Selection.PasteSpecial _
Paste:=xlAll, '
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
Die Hilfe beschreibt die PasteSpecial-Methode:
Ausdruck.PasteSpecial(Paste, Operation, SkipBlanks, Transpose)
Ausdruck Erforderlich. Ein Ausdruck, der ein Range-Objekt zurückgibt.
Paste Variant optional. Der Teil des Bereichs, der eingefügt werden soll. Zulässig ist eine der folgenden XlPasteType-Konstanten: xlPasteAll, xlPasteFormulas, xlPasteValues, xlPasteFormats, xlPasteNotes oder xlPasteAllExceptBorders. Der Standardwert ist xlPasteAll.
Operation Variant optional. Die Einfüge-Operation. Zulässig ist eine der folgenden XlPasteSpecialOperation-Konstanten: xlPasteSpecialOperationNone, xlPasteSpecialOperationAdd, xlPasteSpecialOperationSubtract, xlPasteSpecialOperationMultiply oder xlPasteSpecialOperationDivide. Der Standardwert ist xlPasteSpecialOperationNone.
SkipBlanks Variant optional. True, wenn leere Zellen im Bereich in der Zwischenablage nicht in den Zielbereich eingefügt werden. Der Standardwert ist False.
Transpose Variant optional. True, wenn Zeilen und Spalten beim Einfügen eines Bereichs vertauscht werden. Der Standardwert ist False.
Mich betreffen nur die ersten beiden Parameter: Paste und Operation
Text | Schlüsselwort | Zahl im Direktfenster | Schlüsselwort | Zahl im Direktfenster |
Alles | xlPasteAll | -4104 | xlall | -4104 |
Formeln | xlPasteFormulas | -4123 | xlformulas | -4123 |
Werte | xlPasteValues | -4163 | xlvalues | -4163 |
Formate | xlPasteFormats | -4122 | xlformats | -4122 |
Kommentare | xlPasteNotes (gibt es nicht - aber xlcomments) |
Fehlermeldung im Direktfenster geht: -4144 |
xlpastecomments | -4144 |
Gültigkeit | xlPasteAllExceptBorders | 6 | xlallexceptborders | 6 |
Alles außer Rahmen | - | 7 | - | 7 |
Zusammenfassung dazu:
Auch bei der beim Einfügen auszuführenden Operation gibt es feine Unterschiede, die aber keine Probleme bereiten.
Text | Schlüsselwort | Zahl im Direktfenster | Schlüsselwort | Zahl im Direktfenster |
keine | xlPasteSpecialOperationNone | -4142 | xlnone | -4142 |
addieren | xlPasteSpecialOperationAdd | 2 | xladd | 2 |
subtrahieren | xlPasteSpecialOperationSubtract | 3 | xlsubtract | 3 |
multiplizieren | xlPasteSpecialOperationMultiply | 4 | xlmultiply | 4 |
dividieren | xlPasteSpecialOperationDivide | 5 | xldivide | 5 |
Zusammenfassung dazu:
Namen zuweisen |
oben |
Ich habe ein VBA-Programm aufgezeichnet, das Namen anwendet, die ich vorher zugewiesen hatte. Es ging nicht ums Zuweisen, nur ums Anwenden. Meine Auswahl war dabei der aktuelle Bereich (ein Rechteck mit allen Zellen, in denen was drin stand). Aufgezeichnet hatte ich den Befehl
Selection.ApplyNames
mit einem Array von Namen (und zwar mit allen). Da ich dieses Programm in verschiedenen Zusammenhängen brauchte, störten die Namen mich sehr, aber in der Hilfe fand ich die tröstliche Erläuterung:
"Names Variant optional. Eine Matrix mit den Namen, die zugewiesen werden sollen. Wird das Argument nicht angegeben, werden dem Bereich alle Namen des Tabellenblattes zugewiesen."
Also habe ich diesen Parameter und auch alle anderen (alle optional, die Voreinstellungen reichten mir), gelöscht und nur noch dies behalten:
sub NamenAnwenden
on error resume next
Selection.ApplyNames
end sub
Jetzt kommt die Überraschung:
Die Tabelle habe ich wieder mit den alten Formeln versehen. Markierte ich eine Zelle, und rief das Programm auf, wurde nicht nur eine Formel geändert, sondern auch alle anderen Formeln! Anders ausgedrückt: Selection.ApplyNames wirkte nicht nur auf die Auswahl (Selection.)!
Das widerspricht der Definition von Selection:
"Der zurückgegebene Objekttyp richtet sich nach der aktuellen Auswahl (bei Auswahl einer Zelle gibt diese Eigenschaft beispielsweise ein Range-Objekt zurück). Die Eigenschaft Selection gibt Nothing zurück, wenn nichts markiert wurde."
in der Hilfe.
Weitere Versuche zeigten, daß man sich auch nicht darauf verlassen kann, daß der Befehl alle Namen ersetzt. Habe ich z.B. vorher über Einfügen->Namen->Anwenden wirklich nur diesen einen Namen angewandt, markiere dann eine andere Zelle, um die dortige Formel umwandeln zu lassen, rufe das Programm auf, so tut sich nichts.
Für den nächsten Versuch stellte ich die Bezüge/Adressen wieder her. Markierte ich eine Zelle, die beim letzten Anwenden von Namen nicht betroffen war, rufe das Programm auf, so wird überraschend nur die nichtmarkierte, aber zuvor schon mal geänderte erneut geändert! Warum heißt der Befehl denn Selection.ApplyNames?
Offenbar werden die Namen angewendet, die zuletzt angewendet wurden und fast beliebige auch nicht markierte Zellen geändert.
|
oben |
Um die Bildschirmaktivitäten auszuschalten, kannte ich unter EXCEL 4 die Makrofunktion =ECHO(Wahrheitswert). Mit VBA brauchte ich einen anderen Ausdruck. In der Hilfe habe ich ihn nicht gefunden. Bis mir der Befehl Application.Screenupdating = Wahrheitswert in einem Beispielprogramm begegnete, konnte ich mir allenfalls mit einem Aufruf eines in EXCEL-4-Makrosprache geschriebenen Unterprogramms helfen.
Die Hilfe enthält das Wort "Echo" überhaupt nicht. Wie soll der Umstieg klappen, wenn man bei Microsoft nicht für nötig findet, eine Liste alter und neuer Funktionen und Begriffe mitzuliefern.
Obwohl ich schon aus einem MS-Basic-Dialekt (nämlich von Access) den Befehl docmd.setwarnings Wahrheitswert für das Ein- und Ausschalten von Warnmeldungen kannte, half mir auch dabei die EXCEL-VBA-Hilfe nicht. Weder "Warnings" noch "Warnmeldungen" habe ich gefunden. Der entsprechende EXCEL- und WORD-Befehl heißt Application.DisplayAlerts.
Formatcodes für Seitenlayout |
oben |
6. Juni 2002: Wieder wird in der deutschen Hilfedatei Unsinn behauptet. Ich soll über 10 Dateien mit den gleichen Kopf- und Fußzeilen versehen. Um mir die Arbeit zu erleichtern, öffne ich alle gleichzeitig und schreibe in ein dazu eingefügtes Modul, das ich hinterher wieder löschen will:
und füge dann im With-Block noch ein paar Zuweisungen ein, für die ich mir Formatcodes aus der Hilfe hole. Das Ergebnis sieht aber anders aus als erwartet. Ich stelle dem kompletten Zitat aus der Hilfe die von mir ermittelten Formatcodes gegenüber:
wird in der Hilfedatei behauptet | Wenn das nicht stimm, gilt | ||
---|---|---|---|
stattdessen passiert | richtiger Code wäre | ||
&L | Richtet nachfolgende Zeichen links aus. | ||
&Z | Zentriert das nachfolgende Zeichen. | ||
&R | Richtet nachfolgende Zeichen rechts aus. | ||
&E | Schaltet Doppelt Unterstreichen ein oder aus. | ||
&X | Schaltet Hochstellen ein oder aus. | ||
&Y | Schaltet Tiefstellen ein oder aus. | ||
&F | Schaltet Fettdruck ein oder aus. | Dateiname | |
&K | Schaltet Kursivdruck ein oder aus. | ||
&T | Schaltet Unterstreichen ein oder aus. | Uhrzeit | &U |
&H | Schaltet Durchstreichen ein oder aus. | &S | |
&O | Schaltet Konturschrift ein oder aus (nur Macintosh). | ||
&H | Schaltet Schattieren ein oder aus (nur Macintosh). | ||
&D | Druckt das aktuelle Datum. | ||
&U | Druckt die aktuelle Zeit. | &T | |
&N | Druckt den Namen des Dokuments. | Gesamtzahl der Seiten | &F |
&B | Druckt den Namen des Registers einer Arbeitsmappe. | &A | |
&S | Druckt die Seitenzahl. | &P | |
&S+Zahl | Druckt die Seitenzahl zuzüglich der angegebenen Zahl. | &P+Zahl | |
&S+Zahl | Druckt die Seitenzahl abzüglich der angegebenen Zahl. | &P-Zahl | |
&& | Druckt ein einzelnes kaufmännisches Und-Zeichen. | ||
&"Schriftart" | Druckt die nachfolgenden Zeichen in der angegebenen Schritart. Schriftart muß von Anführungszeichen eingeschlossen sein. | &""Schriftart""test | |
&nn | Druckt die nachfolgenden Zeichen im angegebenen Schriftgrad. Geben Sie eine zweistellige Zahl an, um den Schriftgrad anzugeben. | ||
&A | Druckt die Gesamtanzahl der Seiten eines Dokumentes. | Register | &N |
Komischerweise werden in einem Beispiel der Hilfe die richtigen Codes benutzt:
In diesem Beispiel werden Datum und Seitenzahl oben auf jeder Seite gedruckt.
Worksheets("Tabelle1").PageSetup.CenterHeader = "&D Seite &P von &N"
Hilfe in der Meldung |
oben |
Ich habe mal für eine Excel-Tabelle eine Hilfedatei geschrieben, deren Inhalte natürlich da aufzurufen sein sollten, wo sie gebraucht werden konnten. Von Access kannte ich das schon:
Durch den vierten Parameter des Msgbox-Befehls oder der Msgbox-Funktion wird eine Hilfedatei festgelegt, und durch den fünften die Hilfeseite, die aus ihr aufgerufen wird.
Das soll auch in Excel so sein, wie die Hilfe behauptet:
Irrtum: Hier ist der Beweis.
Ja wo ist sie denn? Und warum erklärt mir das keiner? Jedenfalls habe ich im Internet noch keinen Text dazu gefunden, nur Texte, die wie die Hilfe das Gegenteil behaupten z.B. bei Spona und Kößling GbR, wahrscheinlich nur ungeprüft und nicht gegen besseres Wissen. Auch Microsoft scheint den Fehler nicht bemerkt zu haben:
Displaying Help Topics with the MsgBox Function
To display Help using the Visual Basic MsgBox function, you must include in its list of arguments a Help file name and topic number. This causes a Help button to be displayed in the message box, and specifies which Help topic will be displayed when the Help button is chosen. For example, in Microsoft Excel for Windows, enter:
MsgBox("Delete this item?",vbOKCancel,,"REPORTS.HLP",501)
Ein freundlicher Microsoft-Mitarbeiter hat mir inzwischen die Lösung verraten:
Bei dem Excel Problem scheint es sich um einen Bug in der Dokumentation zu handeln. Die Dokumentation passt eigentlich nur noch zu Versionen, die vor Excel 97 erschienen sind. Man muss jetzt (also ab Excel 97) die Konstante vbMsgBoxHelpButton verwenden, damit der Hilfe Button angezeigt wird. Wenn Du die Message Box wie folgt verwendest, sollte das Ergebnis so sein, wie von Dir gewünscht
Der eigentliche Fehler liegt also nicht im Excel Programm, sondern in der Dokumentation. Ich habe hierzu noch einen Knowledge Base Artikel gefunden, den Du unter folgender URL abrufen kannst:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;164500
Ich habe mir gleich den Artikel XL97: Help Argument for MsgBox Function Behaves Differently angesehen und es auch bei nächster Gelegenheit ausprobiert. Es funktioniert. Doch obwohl dort eindeutig steht:
hat Microsoft andere Hilfen nicht geändert. In diesem Zusammenhang finde ich besonders peinlich, daß Microsoft nicht nur in Artikeln zu Office 97, sondern auch in solchen zu Office XP noch behauptet, daß die Hilfeschaltfläche automatisch erzeugt wird. In der Hilfedatei zu Excel XP wird zwar die Konstante vbMsgBoxHelpButton erwähnt, aber auch der Satz zu den Host-Anwendungen wiederholt.
weitere Links ohne entscheidenden Hinweis:
weitere Links mit entscheidenden Hinweis:
Pivottabellen |
oben |
Nach den Erfahrungen mit der Hilfedatei (s.o.) dachte ich, statt etwas dort nachzulesen sollte ich vielleicht wieder öfter das Grundgerüst einer Prozedur aufzeichnen, dann hätte ich nämlich die richtigen Formatcodes schon gehabt. Aber auch das klappt nicht immer, wie ich bald erfuhr.
10. Juni 2002: Heute wurde ich um Hilfe bei einer komplexen Arbeitsmappe gefragt, die eine Pivottabelle mit mehreren Seitenfeldern enthielt, von der durch Formeln noch andere Zellen abhingen. Ich sollte für jedes Wert eines Seitenfeldes ermitteln, welcher Wert in diesen Nachfolgerzellen berechnet würde. Von Hand jeden der zahlreichen Werte auswählen fand ich zu blöd. Ich habe das deshalb erstmal aufgezeichnet:
Dann schrieb ich ein Testprogramm, das nur eine Ausgabe im Direktfenster erzeugte, immerhin erfolgreich:
Dann baute ich in die For-next-Schleife noch die Zuweisung aus dem aufgezeichneten Makro ein:
Statt nun weiter zu funktionieren, zeigte mir das Programm diese Fehlermeldung, wobei die Hilfe auch keine Erklärung brachte:
Erst nach langem Rätseln und Versuchen brachte eine ganz banale Änderung den Programmiererfolg: An die Stelle, in der auf der Tabelle der Wert des Seitenfeldes angezeigt wird (hier die Zelle B1), muß das Programm den gewünschten Wert hinschreiben:
Warum behauptet die Hilfe, die Eigenschaft "currentpage" habe Schreib-Lese-Zugriff, wenn ich nicht mit VBA schreiben kann, bzw. wenn das nur vom Makrorecorder so aufgezeichnet wird?