Archiv des Intrexx Live! Forums

Hier sehen Sie die Foreneinträge aus dem Intrexx Live! Forum. Bis November 2016 war es das Forum für alle Fragen rund um die Software Intrexx von United Planet.
Seit November 2016 gibt es ein neues moderiertes Forum, das Intrexx Community Forum. Nutzen Sie bitte unbedingt dieses für aktuelle Fragen, Antworten und Informationen.

Wichtig: Dieses Forum dient als Archiv. Die Einträge beziehen sich oft auf ältere Versionen von Intrexx und entsprechen nicht mehr den aktuellen technischen Gegebenheiten.
Daher sollten alle Inhalte ausschließlich von Experten genutzt werden. Bei unsachgemäßer Anwendung kann es zu zeitaufwändigen Problemen oder Datenverlust kommen.
Übersicht > Intrexx Professional: Programming > [Gelöst] Datensatzänderung nachverfolgen

[Gelöst] Datensatzänderung nachverfolgen

Hallo,

ich würde gerne bei einer Datengruppe nachverfolgen welche Daten bei einer Änderung an einem Datensatz tatsächlich geändert wurden und diese Änderungen in eine, am Besten Unterdatengruppe, wegschreiben.
Also quasi mit loggen welche Feelder denn nun tatsächlich geändert wurden und zwar nur die.

Habt Ihr eine Idee wie ich das am bestent anstellen kann?

mir würde jetzt nur einfallen jedes Feld beim laden der Seite mit JavaScript einzulesen und beim Speichern gegen die eingelesenen Werte zu vergleichen und dann wegschreiben, das ist doch aber sehr umständlich, jedes Feld einzeln erstmal zu lesen.
03.03.2016 15:03 von falkh
So ein ähnliches Thema hatten wir hier schonmal, ich finde es aber gerade auch nicht.

Prinzipiell würde ich das in den Prozess oder einen Actionhandler auslagern, denn man braucht das ja nur wenn tatsächlich was geändert wird und nicht bei jedem Aufruf.

Die Besonderheit im Prozess: In Groovy hat man über g_record Zugriff auf die neuen Werte, da sich das ganze in einer Transaktion befindet wurden diese aber noch nciht auf die Datenbank geschrieben. Setzt man in Groovy also ein SQL-Statement ab um den aktuellen Datensatz zu lesen, erhält man die alten Daten und kann dann reativ bequem vergleichen welche Felder sich geändert haben.
03.03.2016 15:24 von MartinW
also irgendwie klappt das nicht,

ich habe jetzt einen Pozess angelegt, der bei Datensatzänderung reagiert und dort dann einen Groovy-Aktion eingebunden in der ich den Vergleeich zwischen g_record und Select auf die DB machen, doch leider steht in beidem also auch im Select schon der neue Wert drin.
Oder wo liegt mein Fehler?
04.03.2016 09:07 von falkh
Hallo,

wenn es nicht zu viele Felder und nicht zu lange Felder (keine Textfelder!) sind, kann man auf der Eingabeseite sowohl die Ansichtsfelder (alte Daten) als auch Eingabefelder (neue Daten) platzieren und die Werte der alten Daten per Request in den Prozess übergeben und dort auslesen.

Gruß
Snixx
04.03.2016 09:31 von Snixx
Das wäre dann die Notlösung aber an der anderen wäre ich eher interessiert.
04.03.2016 11:56 von falkh
Mir fällt die ActionHandler von Version 7.0 ein. Die Ausführungszeitpunkt kann man da genau definieren. processBefore, processAfter, processBeforeWorkflow.
04.03.2016 12:21 von lisaL
OK dann brauch ich nur den Hinweis wie und wo ich den Actionhandler einstellen/setzten/aufrufen kann, da ich mit sowas noch nie zu tun hatte
04.03.2016 12:27 von falkh
eine Definition von Actionhandler kann auf dem Reiter "Handler" in den Eigenschaften der Applikation, einer Datengruppe oder einer Seite erfolgen.

Ich habe selbst noch nicht damit angefangen. Bis jetzt noch nicht gebraucht.
04.03.2016 12:42 von lisaL
Na super ich sehe gerade, dass der Action Handler nicht funktioniert, weil ich auf der Eingabeseite auch Referenzfelder habe und man mit g_record beim Action Handler auf diese nicht zugreifen kann.

Vielleicht doch irgendwie nur über den Prozess?
04.03.2016 12:50 von falkh
hat nicht zufällig noch jemand eine Idee wie ich den Prozess starte bzw. wie ich an die Daten ran komm bevor sie geändert wurden.

ansonsten würde mir jetzt noch einfallen, dass ich die Daten beim Erzeugen in eine Unterdatengruppe kopieren und beim Ändern auch und so die Historie quasie habe
08.03.2016 15:03 von falkh
Ich habe mir das jetzt nochmal angeschaut.
Es ist tatsäöchlich so, dass man im Prozess per SQL nicht mehr an die alten Daten kommt. Da habe ich mich getäuscht.

Bei einem ActionHandler im processBefore kommt man über diese Methode jedoch dran.
Dort kommt man per g_record auch an die Daten der Referenzen, diese werden lediglich nicht bei der Auswahl über das Kontextmenü angeboten.

Ich habe jetzt mal eine Beispiel-Applikation mit PageActionHandler und Prozess angehängt.

Der Action-Handler ist auf der Eingabeseite zu finden.
09.03.2016 08:14 von MartinW
ah ok Super, hätte ich auch selber ausprobieren können, dachte nur wenns nicht in der Auswahl ist, dann kann ichs auch nicht ansteuern.

Ich denke damit kann ich arbeiten.

Vielen Dank!
10.03.2016 07:52 von falkh
Für alle die es interessiert hier meine Lösung:

Ich mache den Vergleich wie schon von Martin vorgeschlagen im ActionHandler der Eingabeseite und weil ich in der Unterdatengruppe nicht alle Einträge kopiert haben möchte, bastel ich mir hier auch gleich en Logeintrag zusammen, welchen ich dann an einen Prozess übergebe. Dieser Prozess schaut dann ob das Flag gesetzt ist, dass überhaupt eine Änderung stattgefunden hat und wenn ja, dann schreibt er mir in die Unterdatengruppe den Logeinrag. Im Logeintrag sind übrigens nur die Felder die sich dann auch tatsächlich geändert haben, bzw. die ich automatisch protokollieren will.
Da ich mit Referenzfeldern arbeite und ich da natürlich nicht nur die ID sondern einen sprechenden Wert protokollieren will habe ich einmal den Wert zum Vergleichen drin (das ist die Ref. ID) und den Wert den ich Wegschreibe, das ist sprchender Wert aus der entsprechenden Referenz, welchen ich per SQL SELECT entsprechen dazulesen muss. Ich kann ja nur mit der ID vergleichen, da nur die ID in der DG vorhanden ist, wenn ich mit dem Wert vergleichen will müsste ich entweder nen komplexen JOIN bauen oder aber für jede Referenz einen JOIN, das wollte ich mir sparen.
Hinweis: Man sollte noch beachten, dass man an die sprechenden Werte der Referenzen nur in Groovy ran kommt, wenn die Felder auf der Eingabeseite vorhanden sind, also einfach zusätzlich in den versteckten Bereich machen.

Beim Vergleich der Werte hatte ich noch ein Problem wenn der Wert in der Datenbank NULL war, denn auf der Eingabeseite ist ein leeres Feld nicht NULL sondern "" und somit hat ermir die Felder immer als geändert erkannt obwohl ich nichts daran gemacht hatte, hier musste ich einfach vor dem Vergleich die leeren Felder der Eingabeseite auf NULL setzten (geht natürlich auch anderes herum)
der Rest sollte im Code ersichtlich sein.
Action Handler (processBefore)

def bWriteHistory = false

//Feldnamen für die Logausgabe
def fieldNames = ["Firma","Status","Verwendung","Benutzer","Kostenstelle Asset","IP Adresse","Standort","kein LDAP Abgleich"]
//GRUIDs der Werte der Vergleichsfelder, bei Referenzen nur mit den IDs verglichen aber ein sprechender Wert protokollieren
def fieldCompareGUIDS = ["ED5D2080443A8260E3EA064DD99A4887A26A9DC9","4D18F3F2B8A3D4277FD3CAE522C3783DBA1CAC5C","126F406B68BCFD22F7128B8538858FA22E3ED525","C452C2BF03C66A6DF025497717402C06A9D8B093","706C487ABD6B9303E53E99484792F342C5E6C99C","C11730E0911B03C6651C0137217B5237F9B92D55","D17974857B7249D4537FDD44B5B15573C376E7F4","6DB9ABE5C8CDBBA3E75E56CF395AA1D4B68E80D9"]
def selectRefQuerys = []
selectRefQuerys.add(/SELECT STR_Firma FROM DATAGROUP('DDB54B51DFA7B5410D7ADB5C7E98E6794D19C197') /)
selectRefQuerys.add(/SELECT STR_STATUS FROM DATAGROUP('0FB11263CA83CBEBF9F8108BDBBF8D3D5B6BA222') /)
selectRefQuerys.add(/SELECT STR_VERWENDUNG FROM DATAGROUP('88C2F7CBE9B3594305EE250DB26A9F5DC637C635') /)
selectRefQuerys.add(/SELECT STRFULLNAME FROM DATAGROUP('DAF7CECF66481FCABE50E529828116EAFE906962') /)

def logText="Alte Daten:"
def oldValue = null

import de.uplanet.scripting.groovy.util.Safely

def conn = g_dbConnections.systemConnection
def stmt = null
def rs = null

try
{
//Hole die Altdaten aus der DB
stmt = g_dbQuery.prepare(conn, "SELECT REF_63F16AE3, REF_4C81D1FC, REF_B92F0CCD, REF_190DCC8F, STR_KONSTENSTELLE, STR_IPADRESSE, STR_STANDORT, B_KEINLDAPABGLEICH FROM DATAGROUP('2D9876D3E5E9F3A7437C8C4D1EA09640E28955FC') WHERE LID = ?")

stmt.setInt(1, Integer.parseInt(g_record.getRecId()))

rs = stmt.executeQuery()

while (rs.next())
{
for (i = 0; i <= fieldCompareGUIDS.size-1; i++) {
def newValue = g_record[fieldCompareGUIDS[i]].value
// für Integer Felder (Ref.IDs)
if(i<4)
{
oldValue = rs.getIntValue(i+1)
}
// für String Felder
else if(i > 3 && i < 7)
{
oldValue = rs.getStringValue(i+1)
}
// für Boolean Felder
else
{
oldValue = rs.getBooleanValue(i+1)
}
//setze leere Felder der Eingabeseite für den Vergleich auf NULL, da in der DB leer = NULL
if(newValue == "")
newValue = null

//Vergleich was sich geändert hat
if(oldValue != newValue)
{
bWriteHistory = true
//Wenn Ref Feld muss der zu protokollierene Wert nachgelesen werden
if(i<4)
{
oldValue = g_dbQuery.executeAndGetScalarValue(conn, selectRefQuerys[i] + "WHERE LID = ?", "NULL") {
setInt(1, rs.getIntValue(i+1))
}
}
//baue den Logeintrag zusammen
logText += "\n" + fieldNames[i] + ": " + oldValue
}
}
}

rs = Safely.close(rs)
stmt = Safely.close(stmt)
}
finally
{
rs = Safely.close(rs)
stmt = Safely.close(stmt)
}

//schreibe die Werte in die Shared Variablen um sie mit dem Prozess abzugreifen
g_sharedState.writeHistory = bWriteHistory
g_sharedState.infoHistory = logText




Prozess:

DG-Ereignisbehandler: bei Änderung
Groovy-Bedingung:
if(g_sharedState.writeHistory == true){
return writeHistory
}else{
return null
}
Datengruppen-Aktion: Datensatz hinzufügen
Feldzuordnung: FKLID = PK ID
PK ID = Autoamtisch
Logeintrag = infoHistory (Verarbeitungskontext)

11.03.2016 13:35 von falkh
Zurück | Alles über Intrexx | Impressum | Datenschutzerklärung

Über United Planet
© 2019 United Planet GmbH
Schnewlinstraße 2
79098 Freiburg