Home Forum Nuclos Konfiguration Vorgänge und Objekte Berechnende Referenzfelder

Ansicht von 9 Beiträgen - 1 bis 9 (von insgesamt 9)
  • Autor
    Beiträge
  • #5593
    Markus Glitzner
    Teilnehmer

    Hallo!

    Ist es möglich ein Referensfeld zu berechnen?

    Im Detail:
    – Ein Auftrag hat eine Referenz zum Projekt
    – Eine Bestellung hat eine Referenz zum Auftrag
    – Die Bestellung soll nun eine Referenz zum Projekt, des referenzierten Auftrages haben.

    Hintergrund:
    Das Projekt soll direkt aus einer Bestellung geöffnet werden können ohne erst den Auftrag öffnen zu müssen.

    Datenbanktechnisch ist es kein Problem, aber wie bekomme ich auf der Bestellung ein LOV zum Projekt.

    Gruß
    Hugo

    #5597
    Matthias Haake
    Teilnehmer

    Hallo Hugo,

    als Feature-Request-Ticket existiert das bereits: NUCLOS-183

    Ansonsten würde ich das ungefähr so machen (Regel beim Speichern einer Bestellung):

    // ID des selektierten Auftrags lesen
    Integer auftragsId = (Integer)server.getAttribute("auftrag").getValueId();

    // ID des Projektes aus Auftragsobjekt lesen
    Integer projektId = (Integer)server.getMasterData("auftragsentität", auftragsId).getField("projektId")

    // Projekt-ID in Bestellung speichern
    server.setField("bestellungsentität", "projekt", projektId, null);

    Das setzt natürlich eine Referenz von Bestellung zu Projekt voraus (kein Pflichtfeld). Auf der GUI würde ich das schreibgeschützt machen und durch obige Regel automatisch befüllen.

    Ggf. könntest Du beim Speichern eines Auftrages prüfen, ob das referenzierte Projekt gewechselt wurde. In diesem Fall sollte man alle abhängigen Bestellungen suchen und dort die Projekt-ID ebenfalls ändern.

    Viele Grüße,
    Matthias

    #5598
    Markus Glitzner
    Teilnehmer

    Hallo Mathias!

    So in der Art hab ich es bis jetzt immer gelöst (z.B. mittels Arbeitsschritt, Regel, etc.), allerdings besteht die Gefahr, dass durch Änderungen die Referenzen der beiden Entitäten inkonsistent werden (ohne hierauf jetzt näher darauf einzugehen).

    Dein Ticket ist in der Tat genau das, was ich bräuchte. Vielleicht lässt sich nuclos austricksen, indem das INTID_STR… Feld ebenfalls berechnet wird, werds mal probieren.

    Gruß
    Hugo

    #5599
    Matthias Haake
    Teilnehmer

    Achso, Du meinst einfach die entsprechende VIEW ändern. Keine schlechte Idee… Aber mittelfristig sollen die Views abgeschafft werden – dann hätte man wieder das gleiche Problem.

    #5611
    Ramin Goettlich
    Teilnehmer

    Hallo,

    aktuell ist das leider noch nicht erreichbar (zumindest fällt uns keine Lösung sein), da ein Referenzfeld „unter der Motorhaube“ aus zwei internen Felder besteht: Aus dem Feld, das die eigentliche Referenz (bzw. den Fremdschlüssel) enthält und aus dem Feld, dass den Anzeigeausdruck (also z.B. die Projektnummer) enthält.

    Selbst wenn man nun zwei berechnete Attribute definieren würde, die diese beiden Werte liefern, würde Nuclos den gewünschten Zusammenhang nicht kennen. Die Umsetzung von NUCLOS-183 ist also Voraussetzung. Bis dahin dient nur der Workaround, das Referenzfeld tatsächlich (redundant) in der Entität als solches anzulegen – und z.B. über eine Regel zu befüllen. Diese redundanten Felder (und die Regeln) könnte man dann ja zu einem späteren Zeitpunkt (nach NUCLOS-183) durch ein entsprechendes berechnetes Attribute ersezen.

    Grüsse,
    nuclosian

    #5614
    Matthias Haake
    Teilnehmer

    Ich habe eben auf einem Testsystem mal was probiert – es funktioniert 🙂 Dabei habe ich die Idee von hugo aufgegriffen und die entsprechende VIEW der Entität manuell angepasst.

    Die Berechnungslogik ist in einer Procedure ausgelagert, die eine ID (INTID) als Eingangsparameter bekommt und auf Basis der hinterlegten Logik eine entsprechende ID zurückgibt.

    Diese Procedure habe ich dann zweimal in der VIEW eingebaut: im SELECT und im JOIN. Es funktioniert gut. Die Werte des LOVs werden nun berechnet. Speichern lassen sich die Datensätze auch. Stellt man im LOV einen anderen Wert ein, wird dieser auch an die Entitätstabelle weitergereicht – ist aber nie sichtbar, da bei der Anzeige immer der berechnete Wert aus der VIEW verwendet wird.

    Als kurzfristiger Work-a-round vielleicht einsetzbar. Bei jeder Änderung an der Entität müsste die VIEW wieder angepasst werden aber dank der Auslagerung in die Procedure ist das kein wirklicher Aufwand.

    Viele Grüße,
    Matthias

    #5623
    Frank Pavlic
    Teilnehmer

    Hallo Matthias,
    wäre es möglich, wenn Du deine Lösung posten könntest? Das würde mir und sicher einigen menr sehr weiter helfen…

    Vielen Dank im Voraus.

    Gruß

    Frank

    #5624
    Matthias Haake
    Teilnehmer

    Hallo Frank,

    die Lösung kann man aber nicht 1:1 übernehmen, da sie ja von der eigenen Datenstruktur abhängt.

    Aber vielleicht hilft der folgende symbolische Code einer geänderten VIEW weiter:


    ALTER VIEW [dbo].[V_EO_BESTELLUNG](
    INTID,
    INTID_STRPROJEKT,
    INTID_STRAUFTRAG
    STRVALUE_STRPROJEKT,
    STRVALUE_STRAUFTRAG
    ) AS SELECT
    t.INTID,
    dbo.GetProjectIdByOrder(t.INTID),
    t.INTID_STRAUFTRAG,
    fk1.STRPROJEKTNAME,
    fk2.AUFTRAGSNUMMER
    FROM
    T_EO_BESTELLUNG t
    LEFT OUTER JOIN T_EO_PROJEKT fk1 ON (dbo.GetProjectIdByOrder(t.INTID) = fk1.INTID
    LEFT OUTER JOIN T_EO_AUFTRAG fk2 ON (t.INTID_STRAUFTRAG = fk2.INTID)

    Im Beispiel (von Hugos ersten Post) würde die obige VIEW zur Entität „Bestellung“ gehören. Diese Bestellung hätte zwei Referenzen: Einmal die Referenz zum Auftrag und zum anderen die Referenz zum Projekt. Letztere soll berechnet werden, daher würde man als erstes den JOIN zum Projekt anpassen: Den ID-Wert der Spalte t.INTID_STRPROJEKT einfach ignorieren und statt dessen eine skalare DB-Funktion aufrufen. Deren Rückgabewert (eine Projekt-ID) wird dann für den JOIN mit der Projektentität verwendet.

    Wie nuclosian schrieb, gehören 2 Werte dazu. Daher muss die oben genannte DB-Funktion auch den Wert INTID_STRPROJEKT im SELECT ersetzen.

    Die DB-Funktion selbst ist irgendwas wie dies hier:


    ALTER FUNCTION [dbo].[GetProjectIdByOrder]
    (
    @OrderId NUMERIC(20,0)
    )
    RETURNS NUMERIC(20,0)
    AS
    BEGIN
    DECLARE @result NUMERIC(20,0);

    SELECT TOP 1 @result = INTID_STRPROJEKT
    FROM T_EO_AUFTRAG a INNER JOIN T_EO_BESTELLUNG b ON b.INTID_STRAUFTRAG = a.INTID
    WHERE b.INTID = @OrderId;

    RETURN @result;
    END

    Wie gesagt – der Code ist jetzt so runtergetippt und nicht getestet. Daher bitte Vorsicht walten lassen, Backup machen usw. Ich vermute mal, spätestens hier endet die Gewährleistung von Novabit 😉

    Viele Grüße,
    Matthias

    #5629
    Frank Pavlic
    Teilnehmer

    Hallo Matthias,
    super Dir eine riesen Danke schön.

    Gruß

    Frank

Ansicht von 9 Beiträgen - 1 bis 9 (von insgesamt 9)