Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hinweis
Community-Interessensgruppen sind jetzt von Yammer zu Microsoft Viva Engage gewechselt. Um an einer Viva Engage-Community teilzunehmen und an den neuesten Diskussionen teilzunehmen, füllen Sie das Formular "Anfordern des Zugriffs auf Finance and Operations Viva Engage Community" aus , und wählen Sie die Community aus, der Sie beitreten möchten.
In diesem Artikel wird beschrieben, wie Makros in X++ erstellt und verwendet werden.
Vorkompilierungsdirektiven, d. h. Makros, werden konzeptionell verarbeitet, bevor der Code kompiliert wird. Die Direktiven deklarieren und behandeln Makros und deren Werte. Die Direktiven werden durch den von ihnen bezeichneten Inhalt ersetzt, sodass der Compiler sie nie trifft. Der X++-Compiler sieht nur die Abfolge von Zeichen, die von den Direktiven in den X++-Code geschrieben wurden.
Warnung
Makros sind Legacyfeatures und werden in zukünftigen Versionen möglicherweise nicht mehr unterstützt. Verwenden Sie stattdessen Sprachkonstrukte: Verwenden Sie anstelle von Makros Sprachkonstrukte wie die folgenden:
- -Konstanten
- Sysda für Abfragen.
Definieren von Makros
Sie definieren ein benanntes Makro mithilfe der unten gezeigten Syntax.
- #define. MyMacro(Value) erstellt ein Makro mit einem optionalen Wert.
- #if. MyMacro überprüft, ob ein Makro definiert ist.
- #undef. MyMacro entfernt eine Makrodefinition.
richtlinien für #define und #if
Alle Vorkompilierungsdirektiven und -symbole beginnen mit dem # Zeichen.
Definieren Sie ein Makro mit der folgenden Syntax:
#define.MyMacro(Value) // creates a macro with a value.
#define.AnotherMacro() // creates a macro without a value.
Sie können ein Makro an einer beliebigen Stelle im Code definieren. Das Makro kann einen Wert aufweisen, der eine Abfolge von Zeichen ist, jedoch keinen Wert aufweisen muss. Die #define Direktive weist den Vorkompiler an, die Makrovariable zu erstellen, optional einschließlich eines Werts.
Die #if Direktive überprüft, ob die Variable definiert ist und optional, ob sie einen bestimmten Wert aufweist, wie im folgenden Beispiel gezeigt:
#if.MyMacro
// The MyNaacro is defined.
#endif
#ifnot.MyMacro
// The MyNaacro is not defined.
#endif
Bei den X++-Präkompilierdirektiven, den von ihnen definierten Makronamen und den #if Direktivenwerttests wird die Groß-/Kleinschreibung nicht beachtet. Definieren Sie jedoch Makronamen, die mit einem Großbuchstaben beginnen.
#undef Richtlinie
Verwenden Sie die #undef Direktive, um eine Makrodefinition zu entfernen, die aus einem vorherigen #defineElement vorhanden ist.
#undef.MyMacro
#if.MyMacro
// The macro is not defined, so this is not included
#endif
Sie können einen Makronamen neu definieren, mit #undef dem Sie entfernt haben, indem Sie eine andere #defineverwenden.
Verwenden eines Makrowerts
Sie können einen Makronamen definieren, um einen Wert zu haben.
#define.Offset(42)
...
print #Offset; // 42
Ein Makrowert hat keinen bestimmten Datentyp – es ist nur eine Abfolge von Zeichen. Weisen Sie einem Makro einen Wert zu, indem Sie den Wert angeben, der am Ende einer #define.MyMacro Direktive in Klammern eingeschlossen ist. Verwenden Sie das Makrosymbol an der Stelle, an der der Wert im X++-Code vorkommen soll. Ein Makrosymbol ist der Name des Makros, wobei das # Zeichen als Präfix hinzugefügt wurde. Das folgende Codebeispiel zeigt ein Makrosymbol #MyMacro. Das Symbol wird durch den Wert des Makros ersetzt.
Testen eines Makrowerts
Sie können ein Makro testen, um festzustellen, ob es einen Wert aufweist. Sie können auch bestimmen, ob der Wert einer bestimmten Abfolge von Zeichen entspricht. Mit diesen Tests können Sie Codezeilen bedingt in Ihr X++-Programm einschließen. Es gibt keine Möglichkeit, zu testen, ob ein definiertes Makro einen Wert aufweist. Sie können nur testen, ob der Makrowert einem bestimmten Wert entspricht. Definieren Sie als bewährte Methode immer einen Wert für jeden von Ihnen definierten Makronamen, oder definieren Sie niemals einen Wert. Wenn Sie zwischen diesen Modi wechseln, wird Ihr Code schwer verständlich.
richtlinien für #defInc und #defDec
#defInc und #defDec sind die einzigen Direktiven, die den Wert eines Makros interpretieren. Sie gelten nur für Makros mit einem Wert, den der Vorkompiler in den formalen Int-Typ konvertieren kann. Diese Direktiven ändern den numerischen Wert eines Makros zur Kompilierungszeit. Der Wert darf nur Zahlen enthalten. Das einzige nicht numerische Zeichen, das zulässig ist, ist ein führendes negatives Zeichen (-). Der ganzzahlige Wert wird als X++- Int und nicht als int64 behandelt. Bei Makronamen, die von der #defInc Direktive verwendet werden, sollte sich die #define Direktive, die das Makro erstellt, nicht in einer Klassendeklaration befinden. Das Verhalten #defInc in diesen Fällen ist unvorhersehbar. Definieren Sie diese Makros stattdessen nur in einer Methode. Verwenden Sie die #defInc Direktiven nur #defDec für Makros, die einen ganzzahligen Wert aufweisen. Der Vorkompiler folgt speziellen Regeln, wenn #defInc der Makrowert keine ganze Zahl ist oder wenn der Wert ungewöhnlich oder extrem ist. In der folgenden Tabelle sind die Werte aufgeführt, die #defInc in Null (0) und dann inKrementierungen konvertiert werden. Wenn #defInc Sie einen Wert in 0 konvertieren, können Sie den ursprünglichen Wert nicht wiederherstellen, nicht einmal mithilfe #defDecvon .
| Makrowert | defInc-Wert | Verhalten |
|---|---|---|
| (+55) | 56 | Das Präfix (+) des positiven Zeichens behandelt diesen Wert als nicht numerische Zeichenfolge.The positive sign (+) prefix makes the precompiler makes this value as a non-numeric string. Der Vorkompiler behandelt alle nicht numerischen Zeichenfolgen als 0, wenn sie eine #defInc (oder #defDec) Direktive behandelt. |
| ("3") | 1 | Ganze Zahlen, die in Anführungszeichen eingeschlossen sind, werden als 0 behandelt. |
| ( ) | 1 | Eine Zeichenfolge von Leerzeichen wird als 0 behandelt. |
| () | 1 | Eine leere Zeichenfolge wird als 0 behandelt. |
| (Zufällige Zeichenfolge.) | 1 | Jede nicht numerische Zeichenfolge von Zeichen wird als 0 behandelt. |
| (0x12) | 1 | Hexadezimalzahlen werden als nicht numerische Zeichenfolgen behandelt. Daher konvertiert der Vorkompiler sie in 0. |
| (-44) | -43 | Negative Zahlen sind akzeptabel. |
| (2147483647) | -2147483648 | Der maximal positive Int-Wert überläuft den minimalen negativen Int-Wert um #defInc. |
| (999888777666555) | 1 | Jede große Zahl, die über die Kapazität von int und int64 hinausgeht. |
| (5.8) | 1 | Reale Zahlen werden als 0 interpretiert. |
| 1 | Wenn kein Wert und keine Klammern für die Direktive #define.MyValuelessMacro angegeben werden, lautet der Wert 0. |
#globaldefine-Direktive
Die #globaldefine Richtlinie ähnelt der #define Richtlinie. Verwenden Sie #define anstelle von #globaldefine.
richtlinien für #localmacro und #macro
Die #localmacro Direktive ist eine gute Wahl, wenn Sie möchten, dass ein Makro einen Wert aufweist, der mehrere Zeilen lang ist, oder wenn der Makrowert eine schließende Klammer enthält, sodass sie gut geeignet sind, Quellcodefragmente zu enthalten.
#macro.RetailMatchedAggregatedSalesLine(
%1.price == %2.price
&& %1.businessDate == %2.businessDate
&& %1.itemId == %2.itemId
&& ((((%3) && (%1.qty <= 0)) || ((! %3) && (%1.qty > 0))) || (%4))
)
#endmacro
Die #localmacro Richtlinie kann als #macro.
#localmacro Dies ist jedoch der empfohlene Begriff. Mithilfe der #if Direktive können Sie testen, ob ein Makroname mit der #define Direktive deklariert wird. Sie können jedoch nicht testen, ob der Makroname mit der #localmacro Direktive deklariert wird. Nur mit der #define Direktive deklarierte Makros sind von der #undef Direktive betroffen. In einer #define Direktive können Sie einen Namen angeben, der sich bereits im Bereich befindet.#localmacro Der Effekt besteht darin, das #localmacro Makro zu verwerfen und zu #define erstellen. Dies gilt auch für die entgegengesetzte Sequenz, was bedeutet, dass eine #localmacro neu definieren #definekann. Ein #localmacro (mit einem Makronamen und einem Wert) setzt immer einen vorherigen #localmacro Wert außer Kraft, der denselben Namen hat. Dieses Problem tritt auf #globaldefine. Der Hauptunterschied zwischen einem #define Makro und einem #localmacro Makro besteht darin, wie die Syntax beendet wird. Die Endzeichen sind wie folgt:
-
#define– wird beendet durch–) -
#localmacro– wird beendet durch–#endmacro
#localmacro ist eine bessere Wahl für Makros mit mehreren Zeilenwerten. Mehrere Zeilenwerte sind in der Regel X++- oder SQL-Code. X++ und SQL enthalten viele Klammern, und diese würden vorzeitig eine #define beenden. Beide und #define#localmacro können auf einer einzelnen Zeile oder in nachfolgenden Zeilen deklariert und beendet werden. In der Praxis wird die #define Einstellung in derselben Zeile beendet, für die sie deklariert ist. In der Praxis wird die #localmacro Einstellung in einer nachfolgenden Zeile beendet.
Makroparameter
Sie können Makrowerte definieren, um Parametersymbole einzuschließen. Das erste Parametersymbol ist %1, die zweite ist %2usw. Sie übergeben Werte für die Parameter, wenn Sie auf den Makrosymbolnamen für die Erweiterung verweisen. Makroparameterwerte sind Zeichensequenzen ohne formalen Typ, und sie sind durch Trennzeichen getrennt. Es gibt keine Möglichkeit, ein Komma als Teil eines Parameterwerts zu übergeben. Die Anzahl der übergebenen Parameter kann kleiner, größer oder gleich der Anzahl der Parameter sein, die der Makrowert empfangen soll. Das System toleriert Inkonsistenzen in der Anzahl der übergebenen Parameter. Wenn weniger Parameter übergeben werden, als das Makro erwartet, wird jeder ausgelassene Parameter als eine 0-Länge-Abfolge von Zeichen behandelt.
Verschachtelung von Makrosymbolen
Sie können Präkompilierungsdefinitionsdirektiven in einer äußeren Definitionsdirektive verschachteln. Die wichtigsten Definitionsrichtlinien sind #define und #localmacro.
Eine #define Direktive kann innerhalb einer #localmacro Richtlinie angegeben werden, und eine #localmacro kann sich innerhalb einer #defineRichtlinie befinden.
#macrolib-Direktive
Im Anwendungs-Explorer unter dem Knoten "Makros" unter dem Codeknoten gibt es viele Bibliotheksknoten, die Gruppen von Makrodirektiven enthalten. Sowohl als #define auch #localmacro häufig in den Inhalten dieser Makrobibliotheken. Sie können die #macrolib verwenden. MyAOTMacroLibrary , um den Inhalt einer Makrobibliothek in Ihren X++-Code einzuschließen. Die #if Richtlinien gelten #undef nicht für #macrolib Namen. Sie gelten jedoch für #define Direktiven, die der Inhalt eines #macrolib Makros sind. Die Richtlinie #macrolib. MyAOTMacroLibrary kann auch als #MyAOTMacroLibrary geschrieben werden . Das #macrolib Präfix wird empfohlen, da es für eine Person, die später den Code liest, nie mehrdeutig ist.
#linenumber Richtlinie
Sie können die Direktive während der #linenumber Entwicklung und des Debuggens von Code verwenden. Sie wird vor jeder Makroerweiterung durch die physische Zeilennummer in der Codedatei ersetzt.
Makrobereich
Der Bereich, in dem Sie auf ein Makro verweisen können, hängt davon ab, wo Sie das Makro definieren. In einer Klasse können Sie auf Makros verweisen, die Sie in der übergeordneten Klasse definieren. Wenn die Vorkompilierung eine untergeordnete Klasse verarbeitet, verfolgt sie zunächst die Vererbungskette auf die Stammklasse. Der Vorkompiler verarbeitet dann alle Direktiven von der Stammklasse in die kompilierte Klasse. Es speichert alle Makros und deren Werte in den internen Tabellen. Die Ergebnisse der Direktiven in jeder Klassendeklaration gelten für die internen Tabellen, die bereits aus Direktiven aufgefüllt wurden, die sie zuvor in der Vererbungskette gefunden haben.
Allerdings behandelt der Vorkompiler jede Methode separat. Es aktualisiert seine internen Tabellen, damit er den Status der Tabellen wie vor der Verarbeitung der aktuellen Methode wiederherstellen kann. Nachdem der Vorkompiler die erste Methode verarbeitet hat, wird die internen Tabellen wiederhergestellt, bevor die nächste Methode behandelt wird.
In diesem Kontext wird eine Methode als Inhalt eines Methodenknotens in der Application Object Tree (AOT) definiert. Im AOT können Sie den Knoten "Klassen" erweitern, einen Klassenknoten erweitern, mit der rechten Maustaste auf einen Methodenknoten klicken und dann "Bearbeiten" auswählen. Anschließend können Sie vor der Methodendeklaration eine Zeile #define.MyMacro("abc") hinzufügen. Der Vorkompiler behandelt diese #define Direktive als Teil der Methode, auch wenn dies #define außerhalb des {} Blocks der Methode erfolgt.