ConditionalCode
Eine leistungsstarke Visual Studio Code-Erweiterung zur Verwaltung und Kontrolle von bedingtem Code in Business Central-Anwendungen. Ermöglicht die einfache Verwaltung verschiedener Code-Versionen und Plattform-spezifischer Implementierungen.
Hauptfunktionen
1. Versions-Management
- Multi-Version Support: Verwalten Sie mehrere Versionen Ihrer Business Central-Anwendung in einem einzigen Projekt
- Version-Switching: Nahtloses Umschalten zwischen verschiedenen BC-Versionen (z.B. 26.0.0.0, 25.0.0.0)
- Plattform-spezifische Anpassungen: Separate Verwaltung von Cloud- und On-Premise-Versionen
2. Bedingter Code
- Intelligente Code-Markierung: Nutzen Sie
//CondiCodeStart und //CondiCodeEnd zur Kennzeichnung versionsspezifischen Codes
- Automatische Code-Aktivierung: Code wird basierend auf der gewählten Version automatisch aktiviert/deaktiviert
- Syntax-Highlighting: Spezielle Hervorhebung der bedingten Code-Bereiche
3. App-Paket-Management
- Automatische App-Signierung: Integrierte Azure Key Vault-Unterstützung für App-Signierung
- Paket-Konvertierung: Tools zum Konvertieren zwischen .app und .zip Formaten
- Symbol-Extraktion: Automatische Extraktion von Symbolen und Dokumentation aus Apps
Detaillierte Einrichtung
Voraussetzungen
- Visual Studio Code
- Business Central AL Language Extension
- Azure Key Vault (für App-Signierung) Dokumentation
Installation
Marketplace Installation
- Öffnen Sie Visual Studio Code
- Drücken Sie
Ctrl+Shift+X um den Extensions Marketplace zu öffnen
- Geben Sie "ConditionalCode" in die Suchleiste ein
- Klicken Sie auf die Extension von "profor software GmbH"
- Klicken Sie auf den blauen "Install" Button
- Neu starten Sie VS Code nach der Installation
Manuelle Installation
- Laden Sie die neueste .vsix-Datei aus den Releases herunter
- Öffnen Sie VS Code
- Drücken Sie
Ctrl+Shift+X für die Extensions-Ansicht
- Klicken Sie auf das "..." Menü (Weitere Aktionen)
- Wählen Sie "Install from VSIX..."
- Navigieren Sie zur heruntergeladenen .vsix-Datei und wählen Sie diese aus
- Bestätigen Sie die Installation und starten Sie VS Code neu
Erste Schritte
Projekt-Konfiguration
a. Version erstellen:
- Öffnen Sie die Command Palette mit
Ctrl+Shift+P
- Geben Sie "Version hinzufügen" ein (oder
ConditionalCode.createversion )
- Drücken Sie Enter
b. Versions-Details eingeben:
- Name der Version: Eindeutiger Name (z.B. "BC26")
- BC Platform: Business Central Platform Version (z.B. "26.0.0.0")
- BC Application: Application Version, meist identisch mit Platform
- BC Target: Wählen Sie zwischen "Cloud" oder "OnPrem"
- BC Runtime: .NET Runtime Version (z.B. "14.0")
c. Workspace vorbereiten:
Die Erweiterung erstellt und konfiguriert automatisch:
.vscode/ConditionalCode.json für Versionskonfigurationen
.allalpackages Ordner für gemeinsam genutzte Dependencies
d. AL Objekt-Analyse:
Die Erweiterung analysiert automatisch:
- Tabellen und Tabellenbeziehungen
- Seiten und Seitenerweiterungen
- Codeunits und deren Abhängigkeiten
- Reports und XMLPorts
- Enumerationen und Schnittstellen
Code-Versionierung einrichten
a. Code-Blöcke markieren:
//CondiCodeStart VersionCompare(config.app.platform,'>=', '26.0.0.0') && TargetCompare('Cloud')
procedure ModernCloudFeature()
begin
// Nur für BC 26.0 oder höher in der Cloud
end;
//CondiCodeEnd
//CondiCodeStart VersionCompare(config.app.platform,'==', '25.0.0.0')
procedure LegacyFeature()
begin
// Nur für BC 25.0
end;
//CondiCodeEnd
//CondiCodeStart TargetCompare('OnPrem')
procedure OnPremiseIntegration()
begin
// Nur für On-Premise-Installationen
end;
//CondiCodeEnd
b. Bedingungs-Syntax und Operatoren:
- Versions-Vergleiche:
VersionCompare(config.app.platform,'>=', '26.0.0.0') (exakte Version)
VersionCompare(config.app.platform,'>=', '26.0.0.0') (mindestens Version)
VersionCompare(config.app.platform,'<=', '26.0.0.0') (höchstens Version)
- Target-Checks:
TargetCompare('Cloud')
TargetCompare('OnPrem')
- Logische Operatoren:
&& für UND-Verknüpfung
|| für ODER-Verknüpfung
! für NICHT
c. Automatische Verwaltung:
- Dynamische Aktivierung/Deaktivierung beim Versionswechsel
- Automatische Kommentierung inaktiver Blöcke
- Intelligentes Folding der Code-Bereiche
- Integration mit AL-Objektverwaltung
App-Signing konfigurieren (optional)
a. Umgebungsvariablen setzen:
# Permanent für den Benutzer setzen
[Environment]::SetEnvironmentVariable("KeyVault_clientId", "Ihre-Client-ID", "User")
[Environment]::SetEnvironmentVariable("KeyVault_Secret", "Ihr-Client-Secret", "User")
[Environment]::SetEnvironmentVariable("KeyVault_tenant", "Ihre-Tenant-ID", "User")
# Optional: Test der Konfiguration
$Env:KeyVault_clientId
$Env:KeyVault_Secret
$Env:KeyVault_tenant
Fortgeschrittene Funktionen
Automatisierte Build-Prozesse
App-Pakete erstellen
- Versionsspezifische Builds mit
ConditionalCode.buildversion
- Automatische .app-Datei Generierung
- Parallele Builds für mehrere Versions-Targets
AL-Kompilierung
- Native AL-Compiler Integration
- Intelligentes Dependency Management
- Version-spezifische Compiler-Einstellungen
- Build-Output-Verwaltung nach Version
Package-Management
.alpackages Synchronisation pro Version
.allalpackages für geteilte Dependencies
- Automatisches Cleanup und Versionierung
- App-zu-Zip Konvertierung für Analysen
Build-Konfiguration
{
"AllConfig": {
"app": {
"id": "com.yourcompany.app",
"name": "Your App Name",
"publisher": "Your Company",
"brief": "App Description",
"privacyStatement": "https://privacy.url",
"EULA": "https://eula.url",
"help": "https://help.url",
"url": "https://company.url",
"supportedLocales": ["de-DE", "en-US"],
"dependencies": [],
"idRanges": [{"from": 50000, "to": 50999}],
"features": ["TranslationFile"]
}
},
"Versions": {
"BC26": {
"app": {
"version": "26.0.0.0",
"platform": "Microsoft Dynamics 365 Business Central",
"application": "26.0.0.0",
"target": "Cloud",
"runtime": "14.0"
}
}
}
}
Symbol-Management
- Automatische Generierung von Symbol-Referenzen
- Extraktion von Dokumentationskommentaren
- Verwaltung von Objekt-Beziehungen
Workspace-Organisation
- Automatische .gitignore-Konfiguration
- Verwaltung von versionsspezifischen Abhängigkeiten
- Strukturierte Arbeitsbereich-Organisation
Troubleshooting
Häufige Probleme und Lösungen
App-Signierung schlägt fehl
a. Symptome:
- Fehlermeldung beim Build-Prozess
- Signatur wird nicht erstellt
- Azure-Authentifizierungsfehler
b. Lösungsschritte:
# Überprüfen der Umgebungsvariablen
$env:KeyVault_clientId
$env:KeyVault_Secret
$env:KeyVault_tenant
Versions-Konflikte
a. Symptome:
- Inkonsistente Code-Aktivierung
- Unerwartetes Verhalten beim Version-Switching
- Build-Fehler mit verschiedenen Versionen
b. Diagnose:
- Überprüfen Sie die ConditionalCode.json:
{
"Versions": {
"BC26-Cloud": {
"app": {
"version": "26.0.0.0",
"target": "Cloud"
}
}
}
}
- Validieren Sie die bedingten Code-Blöcke:
//CondiCodeStart VersionCompare(config.app.platform,'>=', '26.0.0.0')'
// Dieser Code sollte eindeutig einer Version zugeordnet sein
//CondiCodeEnd
Build-System-Probleme
a. Compiler-Fehler:
- Überprüfen Sie die AL Language Extension Version
- Validieren Sie die Compiler-Einstellungen in launch.json
- Stellen Sie sicher, dass alle Dependencies verfügbar sind
b. Performance-Probleme:
Entwicklung und Beitrag
Setup für Entwickler
- Repository klonen:
git clone https://github.com/yourusername/ConditionalCode.git
cd ConditionalCode
- Abhängigkeiten installieren:
npm install
- Entwicklungs-Watch starten:
npm run watch
Testing
- Nutzen Sie die integrierten Test-Tools
- Führen Sie Tests mit unterschiedlichen BC-Versionen durch
- Testen Sie Cloud- und On-Premise-Szenarien
Lizenz
MIT
Support
Bei Fragen oder Problemen:
Hinweise
Standard .gitignore Einträge:
.vscode/.alcache/*.*
.vscode/.altemplates/*.*
.alpackages
/*.app
Translations/*.xlf
.vscode/launch.json
.vscode/rad.json
🧾 Cheat Sheet / Schnellreferenz
📌 Befehle (Command Palette)
Command ID |
Titel |
Kurzbeschreibung |
ConditionalCode.switchtoversion |
Version wechseln |
Baut app.json & kopiert passende .alpackages für gewählte Version. |
ConditionalCode.createversion |
Version hinzufügen |
Interaktive Anlage eines neuen Eintrags in ConditionalCode.json . |
ConditionalCode.buildversion |
Erstelle mehrere Versionen |
Baut mehrere ausgewählte Versionen sequenziell (inkl. Packaging/Signierung). |
ConditionalCode.overridegitignore |
Überschreibe gitignore |
Schreibt empfohlene .gitignore . |
ConditionalCode.createAppSymbolJson |
Erstelle AppSymbol.json |
Scan von src/ – erzeugt .vscode/alsymbols.json (Objekte & Relationen). |
ConditionalCode.createjsonfromapps |
Erstelle JSON aus AL Apps |
Extrahiert SymbolReference.json & DocComments.xml aus .app (+ optional .alpackages ). |
ConditionalCode.extractappfiles |
Extrahiere AL App Dateien |
Entpackt komplette .app (→ *_Extracted). |
ConditionalCode.signfile |
Signiere Datei |
Signiert .app via Azure Key Vault. |
ConditionalCode.runAlLinter |
AL Linter ausführen |
Manuelles Auslösen aller aktiven Regeln. |
ConditionalCode.applyAllLinterFixes |
AL Linter: Alle Quick Fixes eines Typs anwenden |
Massen-Fix (derzeit PageFieldCaption). |
ConditionalCode.nextObjectId |
AL: Nächste freie Objekt-ID |
Ermittelt nächste freie ID (idRanges + Ignorierliste). |
ConditionalCode.listObjectIds |
AL: Vergebene Objekt-IDs je Typ anzeigen |
Ausgabe aller IDs inkl. Name in Output-Channel. |
Explorer Kontext (.app): JSON generieren, Dateien extrahieren, signieren (Submenü "Conditional Code").
⚙️ Einstellungen (Auszug)
Setting |
Default |
Beschreibung |
conditionalCode.AppSigning |
false |
App-Signierung beim Packen aktivieren. |
conditionalCode.objectId.ignoreIdsOrRanges |
[] |
IDs / Bereiche überspringen (z.B. 50100-50120 , table:60000 ). |
conditionalCode.objectId.completion.enable |
true |
Nächste freie Objekt-ID vorschlagen. |
conditionalCode.objectId.completion.showIdList |
true |
Liste vorhandener IDs im Tooltip. |
conditionalCode.dynamicPageFieldCompletion.enable |
true |
Var.Field.PageField → Snippets. |
conditionalCode.expression.showVariableValues |
true |
Inline Ausdrückevaluierung anzeigen. |
conditionalCode.linter.enable |
true |
Linter Hauptschalter. |
conditionalCode.linter.runOnSave |
true |
Lint bei Speichern. |
conditionalCode.linter.runOnOpen |
true |
Lint beim Öffnen. |
conditionalCode.linter.ignoreInlineDirective |
al-linter-disable-next-line |
Directive zum Deaktivieren der nächsten Zeile. |
Linter Regeln (wichtige Keys)
Regel |
Kern-Settings |
Zweck |
objectNamePrefix |
prefix, objectTypes, severity |
Präfix-Prüfung für Objekt-Namen. |
fileNameMatchesObject |
allowShorter, showDetailedReasons |
Dateiname spiegelt Objekt-Namen (ohne _ ). |
customRegex |
Array von {id, pattern, message} |
Eigene Regex Verstöße. |
namespace |
allowApp, allowCustomization, customizingCustomerName |
Namespace-Pattern PSG.App.* / PSG.Customization.*. |
tableFieldNaming |
requirePrefix |
Tabellenfeld Benennung (PSG_ + PascalCase). |
tableFieldIds |
enforceFirstIdOne, checkExtensionIdRanges, reservedCustomerFrom/To |
Feld-ID Regeln & Reservierungen. |
pageFieldCaption |
enable |
Caption konsistent zu Feldquelle. |
versioning |
enforceDevPattern, enforceProdStartPattern, mode |
Versionsformat (Dev/Prod Pattern). |
Inline deaktivieren (nächste Zeile): // al-linter-disable-next-line ObjectNamePrefix oder mehrere durch Leerzeichen / Komma. Global: // al-linter-disable-next-line all .
🧪 Linter Issue Codes
ObjectNamePrefix · FileNameMismatch · FileNameCaseMismatch · FileNameTooShort · FileNameHasTrailing · NamespacePattern · TableFieldNaming · TableFieldIds · PageFieldCaption · Versioning ·
Ausführliche Beschreibung aller Codes (Bedeutung, Beispiele, Behebung): siehe docu.md. Klickbare Codes im Problems-Panel öffnen – sofern vorhanden – die passende Wiki-Seite ALCC(####) .
🧩 CondiCode Syntax
Markers: //CondiCodeStart <Expr> ... //CondiCodeEnd – inaktive Zeilen werden als //CondiCode| markiert. Mehrzeilig mit //CondiCodeContinue .
Verfügbare Variablen/Funktionen innerhalb des Ausdrucks:
platform , runtime , features , tenant , debug , config , VersionCompare(a,op,b) , isVersionInRange(v,min,max) , TargetCompare(target) , now .
Beispiele:
//CondiCodeStart platform >= 26 && TargetCompare("Cloud")
//CondiCodeStart isVersionInRange("26.0.0.0","25.0.0.0","27.0.0.0")
//CondiCodeStart features.includes("A") && !debug
✨ Completions
Feature |
Trigger |
Ergebnis |
Objekt-ID |
Zeile beginnt mit Typ (z.B. table ) |
Vorschlag nächste freie ID + Liste. |
Page Feld Snippet |
Var.Feld.PageField |
Feld-Control oder komplette Page. |
Ausdruck Completion |
Innerhalb CondiCode Ausdruck |
Variablen, Funktionen, Operatoren. |
🔧 Quick Fix / Bulk Fix
Regel |
Quick Fix |
Bulk |
PageFieldCaption |
Korrigiertes Caption (Quotes, Worttrennung) |
ConditionalCode.applyAllLinterFixes → Auswahl PageFieldCaption |
🔐 Signierung
Erfordert Umgebungsvariablen: KeyVault_clientId , KeyVault_Secret , KeyVault_tenant (Namen identisch zum Skript). Aktivierung via Setting conditionalCode.AppSigning .
🆔 Objekt-ID Logik
Berücksichtigt app.json idRanges ; ignoriert definierte Ausschlüsse; Cache invalidiert bei Save.
🧯 Troubleshooting Kurz
Problem |
Hinweis |
Keine ID Vorschläge |
Prüfen: completion.enable & Zeilenkontext vor Objektname. |
Namespace Warnung |
customizingCustomerName / Schreibweise prüfen. |
PageFieldCaption Meldungen |
Regel aktivieren oder Bulk Fix ausführen. |
Ausdruck toggelt nicht |
Ausdruck Syntax / Mehrzeilen mit Continue prüfen. |
Signierung fehlgeschlagen |
Umgebungsvariablen vorhanden & Terminal-Ausgabe kontrollieren. |
✅ Best Practices
Kurz halten: CondiCode Blöcke dokumentieren • CustomRegex sparsam einsetzen • PageFieldCaption erst nach Naming-Disziplin aktivieren • Eigene ID-Ranges früh definieren.
Dieser Cheat Sheet Abschnitt kann bei Erweiterung der Funktionen aktualisiert werden.
| |