Direkter Zugriff auf BOs innerhalb F-Script Block

Funktionalität

  • Erzeugen von BO-Instanzen
  • Laden von BO-Instanzen
  • Lesen und Schreiben von BO-Attribut-Werten
  • Speichern von BO-Instanzen
  • Löschen von BO-Instanzen
Wichtig
Wichtig
Beachten Sie die folgenden Einschränkungen:
  • Es werden nur persistente BOs unterstützt
  • Es werden nur .NET-basierte BOs (aka migrierte BOs) unterstützt.
  • Es werden nur BOs unterstützt, die keine Spezialitäten bezüglich Datenbank-Transaktionen benötigen
  • Auf Singleton-BOs kann nur lesend zugegriffen werden

Syntax - Schlüsselwort bo

Zur Deklaration von BO-Instanz-Variablen wird das Schlüsselwort bo verwendet.
Beispiel
...
// Funktions-Argument:
function MyFunc1(bo myAddrArg := Addr) : string 
{ 
    ...
}
...
// Funktions-Rückgabe:
function MyFunc2() : Addr 
{ 
    bo myLocalAddr := Addr
    ...
    return myLocalAddr
}
...
// BO-Variable:
bo myAddr := Addr
...

Syntax - BO-Instanz: Attribut-Zugriff

Beispiele für das Setzen von Attributen:
Notiz
Notiz
Das erfolgreiche Setzen eines Attribut-Werts bedeutet noch nicht, dass sich dieser Wert auch speichern lässt. Viele Validierungen erfolgen erst beim Speichern und sind kontextabhängig.
...
// Set-String-Attribute based String-Literal:
myAddr.FirstName := 'u.'
// Set-String-Attribute based Number-Literal -> Automatic-Casting:
myAddr.FirstName := 123
// Set-String-Attribute based Number-Expression -> Automatic-Casting:
myAddr.FirstName := 100 + 23
...
// Set-Integer-Attribute based Number-Literal -> Automatic-Casting = Truncating:
myAddr.LangNo := 123.789
// Set-Integer-Attribute based INVALID String-Literal -> COMPILATION-ERROR:
myAddr.LangNo := '123abc'
// Set-Integer-Attribute based INVALID String-Expression -> RUNTIME-ERROR:
myAddr.LangNo := string(100 + 23) + 'abc'
...
// Set-Lang-Specific-Attribute for default Language according context:
myArt.Name1@@0 := 'My Value for Language 1'
// Set-Lang-Specific-Attribute with explicit Language:
myArt.Name1@@2 := 'My Value for Language 2'
...
Beispiele für das Abholen bzw. Lesen von Attributen:
Notiz
Notiz
Mithilfe des '?'-Qualifier kann auf die Attribut-Meta-Informationen zugegriffen werden.
...
// Get-Value:
return myAddr.FullName
// Get-Value with additional "Computation":
return uppercase(myAddr.FullName)
...
// Get-Lang-Specific-Attribute for default Language according context:
return myArt.Name1@@0
// Get-Lang-Specific-Attribute with explicit Language:
return myArt.Name1@@2
// Get-Lang-Specific-Attribute with explicit Language but 'Vaguely' (may include Fallback):
return myArt.Name1@2
...
// Get-Attribute with '!!'-Qualifier _and Language_ for Code-Reference-Attribute:
return myAddr.AddrTypeCd!!@53
// Get-Attribute with '!!'-Qualifier for BO-Reference-Attribute:
return myAddr.LangNo!!
...
// Get-Attribute-Info with '?'-Qualifier:
return (myArt.BarCode1?DataTypeCd + myArt.BarCode1?Format)
// Get-Attribute-Info with '?'-Qualifier and Language:
return (myArt.BarCode1?Name@53)
...

Syntax - BO-Instanz Funktionen

Beispiele für das Laden, Speichern und Löschen:
...
// Laden (ebenfalls mittels "LoadByBoKey()" und "LoadByBoKeySegments()" möglich)
if (not(myAddr.LoadByBoId(73))) 
{
    return "Fehler beim Laden (BO existiert nicht)"
}
...
// Speichern
var saveError := myAddr.Save()
if (saveError <> "")
{
    return ("Fehler beim Speichern: " + saveError)
}
...
// Löschen
var deleteError := myAddr.Delete()
if (deleteError <> "")
{
    return ("Fehler beim Löschen: " + deleteError )
}
...
BO-Funktionen
Analog zu den Instanz-Funktionen (siehe oben) gibt es zusätzlich die folgenden globalen Funktionen:
  • BO.GetAttr(boInstance, attrNameAndQualifier)
    • Attribut-Wert abholen.
    • Attribut-Namen inkl. optionalem Qualifier. (Beispiel: 'Name@@51')
    • Achtung! Nur benutzen, wenn "Late-Binding" der Argumente wirklich benötigt wird. Ansonsten mit Schlüsselwort bo (siehe oben) arbeiten. (Gründe: Performance und Fehler, wenn z.B. ein Attribut nicht existiert, treten erst zur Laufzeit auf und nicht bereits zur Kompilationszeit.)
  • BO.SetAttr(boInstance, attrNameAndQualifier, value, exceptionIfNotPossible=0)
    • Attribut-Wert setzen.
    • Attribut-Namen inkl. optionalem Qualifier. (Beispiel: 'Name@@51')
    • Der Rückgabewert signalisiert, ob der Wert gesetzt werden konnte.
    • Optional kann, mit dem entsprechendem Argument, auch eine Exception forciert werden.
    • Ein erfolgreicher Aufruf bedeutet noch nicht, dass der neue Wert auch persistent gespeichert werden kann!
    • Achtung! Nur benutzen, wenn "Late-Binding" der Argumente wirklich benötigt wird. Ansonsten mit Schlüsselwort bo (siehe oben) arbeiten. (Gründe: Performance und Fehler, wenn z.B. ein Attribut nicht existiert, treten erst zur Laufzeit auf und nicht bereits zur Kompilationszeit.)
  • BO.LoadByBoId(boInstance, boId)
    • Laden der Instanz, basierend auf der BoId.
    • Der Rückgabewert signalisiert, ob das Laden erfolgreich war oder nicht.
    • Allfällig nicht gespeicherte Änderungen oder ein vorgängig geladener Zustand gehen verloren.
  • BO.LoadByBoKey(boInstance, boIndexNo, boKey)
    • Laden der Instanz, basierend auf dem BoKey.
    • Der Rückgabewert signalisiert, ob das Laden erfolgreich war oder nicht.
    • Allfällig nicht gespeicherte Änderungen oder ein vorgängig geladener Zustand gehen verloren.
  • BO.LoadByBoKeySegments(boInstance, boIndexNo, boKeySegment, ...)
    • Laden der Instanz, basierend auf BoKey-Segmenten.
    • Der Rückgabewert signalisiert, ob das Laden erfolgreich war oder nicht.
    • Allfällig nicht gespeicherte Änderungen oder ein vorgängig geladener Zustand gehen verloren.
  • BO.Save(boInstance, withUserRedef=0, isTest=0, exceptionIfNotPossible=0, saveInfosToUiMessages=0)
    • Instanz speichern.
    • Rückgabe: Allfällige Fehlermeldung.
    • Optional kann, mit dem entsprechendem Argument, auch eine Exception forciert werden.
    • Allfällig konfigurierte F-Scripts (Vor/Nach) werden nicht ausgeführt.
  • BO.Delete(boInstance, isTest=0, exceptionIfNotPossible=0)
    • Instanz löschen.
    • Rückgabe: Allfällige Fehlermeldung.
    • Optional kann, mit dem entsprechendem Argument, auch eine Exception forciert werden.
    • Allfällig konfigurierte F-Scripts (Vor/Nach) werden nicht ausgeführt.

Syntax - Singleton-BO Attribut-Zugriff

Der (lesende) Zugriff auf ein Singleton-BO ist global (ohne Verwendung einer Instanz-Variable) möglich.
...
if (AddrCus.AddrLineSpecCd <> 0)
{
    return ("Aktuelle Einstellung: '" + AddrCus.AddrLineSpecCd!! + "'")
}
...

Syntax - Code-Value Zugriff

Der Zugriff auf Code-Values ist, über die identische Syntax wie bei Query, global möglich.
...
// Mittels DatePart.Month wird der entsprechende Code-Wert 'M' referenziert
var myDate := dateAdd(08.11.2023, 9, DatePart.Month)
...

Anwendungsbeispiele

Erstellen einer neuen Adresse.
function CreateNewAddr() : void
 {
  bo newAddr := Addr
  if(AddrCus.AddrNoIsAuto = FALSE)
  { newAddr.Number := AddrCus.NextAddrNo	}

  newAddr.SalutNo   := '1'
  newAddr.FirstName := 'Roman'
  newAddr.LastName  := 'Vonwil'
  newAddr.Street    := 'Erlen'
  newAddr.HouseNo   := '4'
  newAddr.CountrySc := 'CH'
  newAddr.Zip       := '6375'
  newAddr.City      := 'Beckenried'
  var result := newAddr.Save()

  throw newAddr.Number
 }
Erstellen einer BO-Instanz und Laden des BO.
function BoActivation() : void
 {
  XFAS.AddHeads('command','result')
  // erstellen der BO Instanz
  bo addr := Addr
  var activated := FALSE

  // Laden des B0s via ID
  activated := addr.LoadByBoId(2020)
  XFAS.AddCells("addr.LoadByBoId(2020)",addr.FullName +' > (activated: '+string(activated)+')')

  // Laden einer ungültigen ID --> activated = FALSE
  activated := addr.LoadByBoId('WRONG!')
  XFAS.AddCells("addr.LoadByBoId('WRONG!')",addr.FullName +' > (activated: '+string(activated)+')')
 }
BO laden (Late Binding).
function BO_Loading_LateBinding() : void
 {
  XFAS.AddHeads('command','result')
  bo cat := Cat

  var activated := FALSE
  activated := BO.LoadByBoId(cat, 2020)
  XFAS.AddCells("BO.LoadByBoId(cat, 2020)",activated)
  activated := BO.LoadByBoKey(cat, 2, 'ROMANS TestKatalog, 2020')
  XFAS.AddCells("BO.LoadByBoKey(cat, 2, 'ROMANS TestKatalog, 2020')",activated)
  activated := BO.LoadByBoKeySegments(cat, 2, 'ROMANS TestKatalog','2020')
  XFAS.AddCells("BO.LoadByBoKeySegments(cat, 2, 'ROMANS TestKatalog','2020')",activated)
 }
BO-Attribute (Late Binding).
function BO_Attributes_LateBinding() : void
 {
  XFAS.AddHeads('command','result')
  bo cat := Cat
  BO.LoadByBoId(cat, 2020)

  var returnValue := ''

  // Attribut-Wert abfragen
  returnValue := BO.GetAttr(cat, 'Name')
  XFAS.AddCells("BO.GetAttr(cat, 'Name')",returnValue)

  returnValue := BO.GetAttr(cat, 'Free5')
  XFAS.AddCells("BO.GetAttr(cat, 'Free5')",returnValue)

  // Einen Attribut-Wert zuweisen
  returnValue := BO.SetAttr(cat, 'Free5',timestampToStr(now(),'dd.MM.yyyy'))
  XFAS.AddCells("BO.SetAttr(cat, 'Free5',timestampToStr(now(),'dd.MM.yyyy')",returnValue)

  // Speichern der geänderten Attribute
  returnValue := BO.Save(cat, TRUE, FALSE, TRUE, TRUE)
  XFAS.AddCells("BO.Save(cat, TRUE, FALSE, TRUE, TRUE",returnValue)

  // Geänderten Attribut-Wert abfragen
  returnValue := BO.GetAttr(cat, 'Free5')
  XFAS.AddCells("BO.GetAttr(cat, 'Free5')",returnValue)

  // Abfragen von Attributen mit Qualifier
  returnValue := BO.GetAttr(cat, 'IsActiveLang@@1')
  XFAS.AddCells("BO.GetAttr(cat, 'IsActiveLang@@1')",returnValue)

  // Abfragen von MetaInfos
  returnValue := BO.GetAttr(cat,'StructLayoutType1Value?RelatedConstraint')
  XFAS.AddCells("BO.GetAttr(cat,'StructLayoutType1Value?RelatedConstraint')",returnValue)
 }
Laden einer BO-Instanz.
function BO_Loading_Instance() : void
 {
  XFAS.AddHeads('command','result')
  bo cat := Cat
  var activated := FALSE

  activated  := cat.LoadByBoId('2020')
  XFAS.AddCells("cat.LoadByBoId('2020')",activated)

  activated  := cat.LoadByBoKey(2,'ROMANS TestKatalog, 2020')
  XFAS.AddCells("cat.LoadByBoKey(2,'ROMANS TestKatalog, 2020')",activated)

  activated  := cat.LoadByBoKeySegments(2,'ROMANS TestKatalog','2020')
  XFAS.AddCells("cat.LoadByBoKeySegments(2,'ROMANS TestKatalog','2020')",activated)
 }
Abfragen, Zuweisen, Speichern und erneut Abfragen von Attribut-Werten.
function BO_Attributes_Instance() : void
 {
  XFAS.AddHeads('command','result')
  bo cat := Cat
  cat.LoadByBoId(2020)

  var returnValue := ''

  // Attribut-Wert abfragen
  returnValue := cat.Name
  XFAS.AddCells('cat.Name',returnValue)

  returnValue := cat.Free5
  XFAS.AddCells("cat.Free5",returnValue)

  // Einen Attribut-Wert zuweisen
  cat.Free5 := dateAdd(timestampToStr(now(),'dd.MM.yyyy'),1,'D')
  XFAS.AddCells("cat.Free5 := dateAdd(timestampToStr(now(),'dd.MM.yyyy'),1,'D')",cat.Free5)

  // Speichern der geänderten Attribute
  returnValue := cat.Save()
  XFAS.AddCells("cat.Save()",returnValue)

  // Geänderten Attribut-Wert abfragen
  returnValue := cat.Free5
  XFAS.AddCells("cat.Free5",returnValue)

  // Abfragen von Attributen mit Qualifier
  returnValue := cat.IsActiveLang@@1
  XFAS.AddCells("cat.IsActiveLang@@1",returnValue)

  // Abfragen von MetaInfos
  returnValue := cat.StructLayoutType1Value?RelatedConstraint
  XFAS.AddCells("cat.StructLayoutType1Value?RelatedConstraint",returnValue)
 }
BO Kontext.
function Bo_Context() : void
 {
  bo boInstance := Art
  boInstance.LoadByBoKey(1, '2020')
  XFAS.AddHeads('Number','Free6?Format','Free6?DataType','Free6?Name@51')
  XFAS.AddCells(boInstance.Number,boInstance.Free6?Format,boInstance.Free6?DataTypeCd,boInstance.Free6?Name@51)
  
  boInstance.LoadByBoKey(1, '2020.LEISTUNG')
  XFAS.AddCells(boInstance.Number,boInstance.Free6?Format,boInstance.Free6?DataTypeCd,boInstance.Free6?Name@51)
 }