Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
Notitie
Belangengroepen in de gemeenschap zijn nu overgestapt van Yammer naar Microsoft Viva Engage. Als u lid wilt worden van een Viva Engage-community en wilt deelnemen aan de meest recente discussies, vult u het formulier Toegang tot Finance and Operations Viva Engage-community aanvragen in en kiest u de community waarvan u lid wilt worden.
In dit artikel wordt beschreven hoe u macro's maakt en gebruikt in X++.
Precompiler-instructies, dat wil zeggen macro's, worden conceptueel verwerkt voordat de code wordt gecompileerd. De richtlijnen declareren en verwerken macro's en hun waarden. De richtlijnen worden vervangen door de inhoud die ze aanduiden, zodat de compiler ze nooit tegenkomt. De X++ compiler ziet alleen de opeenvolging van karakters die door de directives in de X++ code worden geschreven.
Waarschuwing
Macro's zijn legacy-functies en kunnen in toekomstige releases verouderd zijn. Gebruik in plaats daarvan taalconstructies: in plaats van macro's, gebruik taalconstructies zoals deze:
- Constanten
- Sysda voor query's.
Macro's definiëren
Je definieert een benoemde macro met behulp van de onderstaande syntaxis
- #define. MyMacro(Value) maakt een macro aan met een optionele waarde.
- #if. MyMacro controleert of een macro is gedefinieerd.
- #undef. MyMacro verwijdert een macro-definitie.
#define en #if richtlijnen
Alle precompiler-instructies en symbolen beginnen met het # karakter.
Definieer een macro met de volgende syntaxis:
#define.MyMacro(Value) // creates a macro with a value.
#define.AnotherMacro() // creates a macro without a value.
Je kunt overal in je code een macro definiëren. De macro kan een waarde hebben die een reeks karakters is, maar hoeft geen waarde te hebben. De #define richtlijn instrueert de precompiler om de macrovariabele te creëren, waarbij eventueel een waarde wordt toegevoegd.
De #if richtlijn controleert of de variabele gedefinieerd is en, optioneel, of deze een specifieke waarde heeft, zoals getoond in het volgende voorbeeld:
#if.MyMacro
// The MyNaacro is defined.
#endif
#ifnot.MyMacro
// The MyNaacro is not defined.
#endif
De X++ precompiler-instructies, de macronamen die ze definiëren en de #if directive-waarden tests zijn allemaal hoofdlettergevoelig. Definieer echter macronamen die beginnen met een hoofdletter.
#undef richtlijn
Gebruik de #undef richtlijn om een macro-definitie te verwijderen die bestaat uit een eerdere #define.
#undef.MyMacro
#if.MyMacro
// The macro is not defined, so this is not included
#endif
Je kunt een macronaam die je hebt verwijderd #undef herdefiniëren door een andere #definete gebruiken.
Een macrowaarde gebruiken
U kunt een macronaam definiëren die een waarde heeft.
#define.Offset(42)
...
print #Offset; // 42
Een macrowaarde heeft geen specifiek datatype - het is gewoon een reeks tekens. Ken een waarde toe aan een macro door de waarde tussen haakjes aan het einde van een #define.MyMacro richtlijn te geven. Gebruik het macrosymbool waar je wilt dat de waarde voorkomt in de X++-code. Een macrosymbool is de naam van de macro waaraan het # teken als voorvoegsel is toegevoegd. In het volgende codevoorbeeld ziet u een macrosymbool #MyMacro. Het symbool wordt vervangen door de waarde van de macro.
Een macrowaarde testen
Je kunt een macro testen om te bepalen of deze een waarde heeft. Je kunt ook bepalen of de waarde gelijk is aan een specifieke reeks tekens. Met deze tests kunt u voorwaardelijk coderegels opnemen in uw X++-programma. Er is geen manier om te testen of een gedefinieerde macro een waarde heeft. Je kunt alleen testen of de macrowaarde overeenkomt met een specifieke waarde. Als best practice definieer altijd een waarde voor elke macronaam die je definieert, of definieer nooit een waarde. Wanneer u tussen deze modi wisselt, wordt uw code moeilijk te begrijpen.
#defInc en #defDec richtlijnen
#defInc en #defDec zijn de enige richtlijnen die de waarde van een macro interpreteren. Ze gelden alleen voor macro's die een waarde hebben die de precompiler kan omzetten naar het formele int-type . Deze richtlijnen veranderen de numerieke waarde van een macro tijdens het compileren tijd. De waarde kan alleen getallen bevatten. Het enige niet-numerieke teken dat is toegestaan, is een voorloop-minteken (-). Het gehele getal wordt behandeld als een X++ int, niet als een int64. Voor macronamen die de #defInc richtlijn gebruikt, zou de #define richtlijn die de macro maakt niet in een klasse-verklaring moeten staan. Het gedrag van #defInc in deze gevallen is onvoorspelbaar. Definieer in plaats daarvan dergelijke macro's alleen in een methode. Gebruik de #defInc en-instructies #defDec alleen voor macro's met een geheel getal. De precompiler volgt speciale regels wanneer #defInc de macrowaarde geen geheel getal is, of wanneer de waarde ongewoon of extreem is. In de volgende tabel worden de waarden weergegeven die #defInc worden geconverteerd naar nul (0) en vervolgens worden verhoogd. Wanneer #defInc een waarde naar 0 wordt omgezet, kun je de oorspronkelijke waarde niet terughalen, zelfs niet door gebruik te maken #defDecvan .
| Macro waarde | defInc Waarde | Gedrag |
|---|---|---|
| (+55) | 56 | Het voorvoegsel positief (+) laat de precompiler deze waarde behandelen als een niet-numerieke string. De precompiler behandelt alle niet-numerieke tekenreeksen als 0 wanneer het een #defInc (of #defDec) instructie verwerkt. |
| ("3") | 1 | Gehele getallen tussen aanhalingstekens worden behandeld als 0. |
| ( ) | 1 | Een reeks ruimtes wordt behandeld als 0. |
| () | 1 | Een string van nul lengte wordt behandeld als 0. |
| (Willekeurige tekenreeks.) | 1 | Elke niet-numerieke tekenreeks wordt als 0 behandeld. |
| (0x12) | 1 | Hexadecimale getallen worden behandeld als niet-numerieke tekenreeksen. Daarom zet de precompiler ze om naar 0. |
| (-44) | -43 | Negatieve getallen zijn acceptabel. |
| (2147483647) | -2147483648 | De maximale positieve int-waarde loopt over naar de minimale negatieve int-waarde met #defInc. |
| (999888777666555) | 1 | Elk groot aantal, buiten de capaciteit van int en int64. |
| (5.8) | 1 | Reële getallen worden geïnterpreteerd als 0. |
| 1 | Wanneer er geen waarde en haakjes voor de richtlijn #define.MyValuelessMacro worden gegeven, is de waarde 0. |
#globaldefine richtlijn
De #globaldefine richtlijn is vergelijkbaar met de #define richtlijn. Gebruik #define in plaats van #globaldefine.
#localmacro en #macro richtlijnen
De #localmacro richtlijn is een goede keuze als je wilt dat een macro een waarde heeft die meerdere regels lang is, of wanneer je macrowaarde een afsluitende haakje bevat, waardoor ze goede kandidaten zijn om broncodefragmenten te bevatten.
#macro.RetailMatchedAggregatedSalesLine(
%1.price == %2.price
&& %1.businessDate == %2.businessDate
&& %1.itemId == %2.itemId
&& ((((%3) && (%1.qty <= 0)) || ((! %3) && (%1.qty > 0))) || (%4))
)
#endmacro
De #localmacro richtlijn kan worden geschreven als #macro. Echter, #localmacro is de aanbevolen term. Door de #if directive te gebruiken, kunt u testen of een macronaam met de #define directive wordt gedeclareerd. Je kunt echter niet testen of de macronaam met de #localmacro richtlijn wordt gedeclareerd. Alleen macro's die met behulp van de #define richtlijn worden gedeclareerd, vallen onder de #undef richtlijn. In een #define richtlijn kunt u een naam opgeven die al binnen het bereik is als een #localmacro. Het effect is om de #localmacro weg te gooien en een #define macro te maken. Dit geldt ook voor de tegenovergestelde reeks, wat betekent dat a #localmacro een #define. A #localmacro (die zowel een macronaam als een waarde heeft) overschrijft altijd een vorige #localmacro met dezelfde naam. Ditzelfde probleem doet zich voor bij #globaldefine. Het belangrijkste verschil tussen een #define macro en een #localmacro macro is de manier waarop hun syntaxis wordt beëindigd. De terminators zijn als volgt:
-
#define– wordt beëindigd door–) -
#localmacro– wordt beëindigd door–#endmacro
#localmacro is een betere keuze voor macro's met meerdere regelwaarden. Meerdere regelwaarden zijn meestal regels met X++- of SQL-code. X++ en SQL bevatten veel haakjes, en deze zouden een #define voortijdig beëindigen. Beide #define en #localmacro kunnen worden gedeclareerd en beëindigd op een enkele lijn of op volgende lijnen. In de praktijk wordt de #define op dezelfde lijn beëindigd als waarop hij is verklaard. In de praktijk wordt de #localmacro beëindigd op een volgende lijn.
Macroparameters
U kunt macrowaarden definiëren om parametersymbolen op te nemen. Het eerste parametersymbool is %1, de tweede is %2, enzovoort. U geeft waarden door voor de parameters wanneer u verwijst naar de naam van het macrosymbool voor uitbreiding. Macroparameterwaarden zijn tekenreeksen zonder formeel type, en ze zijn door komma afgebakend. Er is geen manier om een komma als onderdeel van een parameterwaarde door te geven. Het aantal doorgegeven parameters kan kleiner zijn dan, groter dan of gelijk zijn aan het aantal parameters dat de macrowaarde moet ontvangen. Het systeem tolereert mismatches in het aantal doorgegeven parameters. Als er minder parameters worden doorgegeven dan de macro verwacht, wordt elke weggelaten parameter behandeld als een reeks tekens met een lengte van nul.
Macrosymbolen nesten
U kunt precompilerdefinitierichtlijnen nesten in een externe definitierichtlijn. De belangrijkste definitierichtlijnen zijn #define en #localmacro.
Een #define richtlijn kan worden gegeven in een #localmacro richtlijn, en a #localmacro kan in een #define.
#macrolib richtlijn
In de Application Explorer onder de Macros-node onder de Code-node zijn er veel bibliotheeknodes die sets macro-directives bevatten. Beide #define komen #localmacro vaak voor in de inhoud van deze macrobibliotheken. U kunt de #macrolib gebruiken. MyAOTMacroLibrary om de inhoud van een macrobibliotheek op te nemen in je X++-code. De #if en #undef richtlijnen gelden niet voor #macrolib namen. Ze zijn echter wel van toepassing op #define richtlijnen die de inhoud van een #macrolib macro zijn. De richtlijn #macrolib. MyAOTMacroLibrary kan ook als #MyAOTMacroLibrary worden geschreven . Het #macrolib voorvoegsel wordt aanbevolen omdat het nooit dubbelzinnig is voor iemand die later de code leest.
#linenumber richtlijn
Je kunt de #linenumber directive gebruiken tijdens het ontwikkelen en debuggen van code. Het wordt vervangen door het fysieke regelnummer in het codebestand vóór elke macro-uitbreiding.
Macroscope
Het bereik waarin je een macro kunt refereren hangt af van waar je de macro definieert. In een klasse kun je macro's verwijzen die je definieert in de ouderklasse. Wanneer de precompiler een kindklasse verwerkt, volgt hij eerst de overervingsketen naar de rootklasse. De precompiler verwerkt vervolgens alle directives van de rootclass naar de te compileren klasse. Het slaat alle macro's en hun waarden op in de interne tabellen. De resultaten van de richtlijnen in elke klasse-verklaring zijn van toepassing op de interne tabellen die al zijn gevuld uit richtlijnen die eerder in de overervingskeden werden gevonden.
De precompiler behandelt echter elke methode apart. Het werkt zijn interne tabellen bij zodat het de status van de tabellen kan herstellen zoals ze waren vóór het verwerken van de huidige methode. Nadat de precompiler de eerste methode heeft verwerkt, herstelt hij de interne tabellen voordat hij de volgende methode verwerkt.
In deze context wordt een methode gedefinieerd als de inhoud van een methodeknooppunt in de Application Object Tree (AOT). In de AOT kun je de Classes-node uitbreiden, een class node uitbreiden, met de rechtermuisknop op een methode-node klikken en dan Bewerken selecteren. Dan kun je een regel toevoegen voor #define.MyMacro("abc") voor de methodedeclaratie. De precompiler behandelt deze #define directive als onderdeel van de methode, ook al gebeurt deze #define buiten het {} blok van de methode.