Uso delle istruzioni condizionali

Completato

Le istruzioni condizionali sono ampiamente usate in qualsiasi linguaggio di programmazione, incluso il linguaggio delle applicazioni (AL). Un'istruzione condizionale viene usata per verificare una condizione. In base alla valutazione di tale condizione, possono essere eseguite una o più istruzioni.

Istruzioni If

L'istruzione condizionale più comunemente usata è If.

var 
    a: Integer;
    b: Integer;
    c: Integer;
begin
    a := 10;
    b := 5;

    if a > b then
        c := a - b;
end;

Nell'esempio precedente, alle variabili a e b viene assegnato un valore. Con l'istruzione If, viene verificata la condizione che a sia più grande di b. Se questa condizione è true, allora alla variabile c viene assegnato il valore di a meno b.

Notare la posizione del punto e virgola. Un punto e virgola indica l'inizio di una nuova istruzione. Poiché if .. then è considerata un'istruzione, il punto e virgola viene messo dopo l'ultima istruzione, non dopo la parola chiave then.

Si può mettere solo un'istruzione dopo la parola chiave then. Se si desidera eseguire più istruzioni quando la condizione è true, è necessario usare un'istruzione composta, come mostrato nell'esempio seguente.

var
    a: Integer;
    b: Integer;
    c: Integer;
begin
    a := 10;
    b := 5;

    if a > b then begin
        c := a - b;
        Message('%1', c);
    end;
end;

È importante notare le posizioni dei diversi punti e virgola dopo ogni istruzione all'interno e anche alla fine dell'istruzione composta.

Istruzione If-then-else

L'istruzione if è spesso combinata con un'istruzione else. Se la condizione non si valuta come true, si eseguono le istruzioni nel blocco else.

var
    a: Integer;
    b: Integer;
    c: Integer;
begin
    a := 10;
    b := 5;

    if a > b then
        c := a - b
    else
        c := a + b;
end;

Nessun punto e virgola è posto alla fine dell'istruzione nel blocco then, solo uno è posizionato alla fine dell'istruzione if-then-else completa.

Si possono anche usare istruzioni composte in una struttura if-then-else.

var
    a: Integer;
    b: Integer;
    c: Integer;
begin
    a := 10;
    b := 5;

    if a > b then begin
        c := a - b;
        Message('%1', c);
    end
    else begin
        c := a + b;
        Message('%1', c);
    end;
end;

Poiché un'istruzione if-then-else è anche un'istruzione regolare, è possibile inserire le istruzioni if in altre istruzioni if, creando così istruzioni nested if.

begin
    if Amount <> 0 then
        if Amount > 0 then
            Sales := Sales + Amount
        else
            if Reason = Reason::Return then
                if ReasonForReturn = ReasonForReturn::Defective then
                    Refund := Refund + Amount
                else
                    Credits := Credits + Amount
            else
                Sales := Sales - Amount;
end;

Prestare attenzione alle istruzioni nested if perché spesso sono difficili da leggere e possono risultare complesse. Guardare le posizioni dei punti e virgola può semplificarne la lettura e la comprensione.

Uso dell'operatore ternario

L'operatore ternario (? :), comunemente usato in altri linguaggi di programmazione, semplifica le operazioni condizionali nel codice, migliora la leggibilità e riduce la verbosità. È utile per condizioni semplici, promuovendo la chiarezza del codice e la programmazione incentrata sull'intento. Consentendo l'inizializzazione delle variabili all'interno della stessa riga, garantisce una corretta assegnazione e limita la lunghezza del codice. Con questa versione, AL supporta l'operatore ternario.

È possibile usare l'operatore ternario per assegnare uno dei due valori a una variabile, a seconda delle condizioni di un'espressione. Di seguito è riportato un esempio di utilizzo di if-then-else con un operatore ternario.

Convenzioni di programmazione

Per implementazioni di successo, attenersi ai principi indicati di seguito:

  • If e then devono trovarsi sulla stessa riga, else deve essere su una riga separata.

  • Se ci sono molte espressioni o espressioni particolarmente lunghe, then deve trovarsi su una nuova riga ed essere allineato con if.

  • Quando si scrivono espressioni if con parti then ed else, scriverle in modo che il risultato then sia più probabile di quello else.

  • Se l'ultima istruzione nella parte then di un'istruzione if-then-else è exit o un errore, non continuare con un'istruzione else.

Istruzione case

Un'altra istruzione condizionale che è possibile usare è case. A seconda del valore di un'istruzione, case esegue altre istruzioni.

Il prossimo esempio mostra che, a seconda del valore del campo Document Type (che è un campo di opzione in una tabella), l'istruzione case eseguirà alcune istruzioni. L'istruzione case può usare un blocco else che viene eseguito quando non si eseguono altri blocchi. Poiché si può eseguire un'unica istruzione per ogni blocco con l'istruzione case, per eseguire più istruzioni contemporaneamente occorre usare istruzioni composte.

var
    a: Integer;
begin
    case "Document Type" of
        "Document Type"::Quote:
            a := 1 + 1;
        "Document Type"::Order:
            a := 2 + 1;
        "Document Type"::Invoice:
            begin
                // Some statement 1;
                // Some statement 2;
                // Some statement 3;
                a := 3 + 1;
            end;
        "Document Type"::"Return Order":
            if Reason = Reason::Return then begin
                // Some statement 1;
                // Some statement 2;
                // Some statement 3;
                a := 4 + 1;                
            end;
        else
            a := 5 + 1;
    end;

end;

Le istruzioni case sono anche chiamate istruzioni con opzioni multiple e vengono generalmente usate quando è necessario scegliere tra più di due azioni diverse. Il metodo dell'istruzione case è il seguente:

  • L'Espressione viene valutata e il primo set di valori corrispondente esegue l'istruzione associata, se presente.

  • Se nessun set di valori corrisponde al valore dell'espressione e la parte facoltativa else è stata omessa, non viene intrapresa alcuna azione. Se viene usata la parte facoltativa else, viene eseguita l'istruzione associata.

Il tipo di dati dei set di valori deve essere uguale al tipo di dati di Espressione o almeno essere convertibile nello stesso tipo di dati.

Nella maggior parte dei casi, il tipo di dati dei set di valori viene convertito nel tipo di dati dell'espressione valutata. L'unica eccezione è se l'espressione valutata è una variabile Code. Se l'espressione valutata è una variabile Code, i set di valori non vengono convertiti nel tipo di dati Code.

Convenzioni di programmazione: istruzioni Case

Quando si usa un'istruzione case, impostare il rientro dei set di valori di quattro caratteri. Se sono presenti due o più set di valori sulla stessa riga, separarli con virgole senza spazi. L'ultimo set di valori su una riga è immediatamente seguito da due punti non preceduti da uno spazio. L'azione inizia sulla riga dopo il set di valori e presenta un ulteriore rientro di quattro caratteri. Se è presente un'istruzione begin, deve trovarsi su una riga separata a meno che non segua else. Se un begin segue un else, deve trovarsi sulla stessa riga di else.

Se ci sono più di due alternative, usare un'istruzione case. In caso contrario, usare un'istruzione if-then-else.

Direttive dei preprocessori in AL

In AL, come in altri linguaggi di programmazione, le direttive dei preprocessori possono essere usate per rendere condizionale il codice, per non visualizzare gli avvisi o per abilitare l'espansione e la compressione del codice.

Le direttive del preprocessore possono essere suddivise nei seguenti gruppi.

  • Direttive condizionali
  • Aree
  • Pragma

Qualsiasi codice può essere reso condizionale, inclusi i campi della tabella, e verificato usando una direttiva condizionale. Per controllare il codice usando una direttiva condizionale, è necessario definire un simbolo da controllare. Un simbolo restituisce un valore booleano: true o false.

I simboli possono essere definiti all'inizio di un file di origine e l'ambito del simbolo specifico è il file in cui è definito. È anche possibile definire i simboli nel file app.json e allora l'ambito per l'estensione è globale.

Le seguenti direttive condizionali per il preprocessore sono supportate in AL.

  • #if: specifica l'inizio di una clausola condizionale. La clausola #endif chiude. Compila il codice tra le direttive se il simbolo specificato da controllare è definito.

  • #else: specifica una clausola condizionale composta. Se nessuna delle clausole precedenti restituisce true, il compilatore valuterà il codice tra #else e #endif.

  • #elif: combina le istruzioni else e if. Se #elif è true il compilatore valuta tutto il codice tra #elif e la direttiva condizionale successiva.

  • #endif: specifica la fine di una clausola condizionale che inizia con #if.

  • #define: definisce un simbolo che può essere usato per specificare le condizioni di una compilazione. Ad esempio, #define DEBUG. L'ambito del simbolo è il file in cui è stato definito.

  • #undef: rimuove la definizione di un simbolo.

I simboli possono essere definiti globalmente nel file app.json. Un simbolo può anche essere definito usando la direttiva #define nel codice. Se definiti nel file app.json, i simboli possono tuttavia essere usati globalmente.

Il seguente esempio definisce DEBUG come simbolo globale. Questo simbolo può quindi essere usato dal codice come illustrato nell'esempio di codice condizionale qui di seguito. Un simbolo ha un valore booleano, dunque restituisce true o false.

File app.json

"preprocessorSymbols": [ "DEBUG" ]

al-code che usa il simbolo DEBUG

#if DEBUG
    trigger OnOpenPage()
    begin
        Message('Only in debug versions');
    end;
#endif

Non visualizzare gli avvisi AL

In alcuni casi, gli avvisi del compilatore o dell'analizzatore sono dovuti all'uso previsto del codice. Per ridurre il disordine in modo che gli sviluppatori possano concentrarsi sugli avvisi da risolvere, è stato aggiunto il supporto per non visualizzare esplicitamente gli avvisi, per un'intera estensione o localmente in un contenitore di codice.

Sono disponibili due modi per supportare gli avvisi:

  • Globale (per un'estensione)

  • Locale

È importante ricordare che la maggior parte degli avvisi è presente per un motivo e la loro eliminazione potrebbe avere un impatto non previsto, se gli avvisi sono modificati in errori (ad esempio, gli obsoleti).

Globale

È presente una proprietà suppressWarnings nel manifesto app.json per eliminare un elenco separato da virgole di ID di avvisi al momento della compilazione dell'estensione:

"suppressWarnings": [Warning ID,Warning ID2,...]

Locale

Direttive è un nuovo costrutto nel linguaggio AL che specifica come il compilatore AL tratta una sezione di codice chiusa. Lo stesso concetto è noto in altri linguaggi. Le istruzioni specifiche della direttiva devono essere supportate dal compilatore. Non è possibile creare istruzioni di pre-elaborazione personalizzate.

Una delle nuove direttive è pragma avvisi, che si può impostare per una sezione di codice per eliminare un elenco di avvisi separati da virgole solo nel contenitore interessato.

Se non si fornisce una chiusura di fine pragma, allora sarà il resto del file. Il ripristino lo riporta allo stato di eliminazione globale presente, come descritto sopra. Quando non si specificano numeri di avviso, Disabilita disabilita tutti gli avvisi e Ripristina abilita tutti gli avvisi.

#pragma warning disable warning-list
#pragma warning restore warning-list