Gestaltungselement Ansicht - individuelle Berechnung in Ansichtsspalte und Sichtbarkeit von Zeilen

J

Guten Abend zusammen!

Ich habe eine Tabelle Projekte und eine Tabelle Kunden. Bei den Projekten würde ich nun gerne das Gestaltungselemet Ansicht einsetzen und darin die Kunden anzeiegn. Das funktioniert  mit der Funktion

select Kunden

das kann ich mit dem zusatz where auch spezifizieren und nur bestimmte Kunden anzeigen. Das funktioniert bisher auch mit  Ja/Nein Feldern oder Zahlen etc.

Ich würde nun gerne die Kunden anzeigen die zum Projekt maximal 100 km (Luftlinie) entfernt sind. Dazu gibt es natürlich jeweils in der Kundentabelle als auch in der Projekttabelle ein Adressfeld. Die Formel für die Berechnung der Luftlinie ist auch bekannt. Für die Berechnung der Entfernung eines Kunden oder Projekts zu einer festgelegten Adresse lautet die Formel:

let SA := location("Adresse1", 49.0, 8.5);
let SB := this.kundenadresse;
let PI := 3.141592653589793;
let dL := longitude(SA) - longitude(SB);
let dB := latitude(SA) - latitude(SB);
let BL := sqrt(sqr(dL) + sqr(dB));
PI * 6371 * BL / 180

Ab hier stehe ich auf dem Schlauch. Die Funktion für das Gestaltungselement Ansicht im Projekt-Formular müsste in etwa so aussehen:

let SA := projektadresse;
let PI := 3.141592653589793;
select kunden where (PI * 6371 * sqrt(sqr(longitude(SA) - longitude(kundenadresse)) + sqr(latitude(SA) - latitude(kundenadresse))) / 180) <= 100

Allerdings bleibt die Ansicht damit leer. Kann mir hier jemand helfen?

Des weiteren würde ich dann natürlich gerne wissen, wieviel Kilometer der jeweilige Kunde entfernt ist. Da ich mich durch den select Befehl in der Kundentabelle befinde kann ich nichtmehr auf das Feld Projektadresse zugreifen. Daher funktioniert folgendes nicht:

let mynr := this.Nr;
let A1 := first((select projekte where Nr = mynr).projektadresse);
let A2 := this.kundenadresse;
let PI := 3.141592653589793;
let dL := longitude(A1) - longitude(A2);
let dB := latitude(A1) - latitude(A2);
let BL := sqrt(sqr(dL) + sqr(dB));
PI * 6371 * BL / 180

Damit erhalte ich zwar Zahlen, aber die sind offensichtlich nicht korrekt. Kann mir auch hier jemand helfen?

Besten Dank vorab! Bin jedes mal begeistert welch ein Know-How hier aufeinandertrifft.

 

LG
Johannes

A

Hallo Johannes,

in deiner Select anweisung fehlt dem Programm meines erachtens das Feld nach dem es Filtern soll. also eher sowas:

select kunden where kundenadresse <= Bedingung

hier wirst du das Problem haben, dass du Berechnest und eine 2. Bedingungen brauchst.

vielleicht geht es ja auch, dass du in der Ansicht einfache ein Berechnungsfeld erzeugst, was auf dir die Entfernung berechnet und dann setzt du einen filter der nur werte anzeigt, die kleiner als 100 sind. Damit hast du beide Fragen erschlagen.

LG Alex

Ninox Profile

Hallo, versuch doch mal, die select-Berechnung für die Ansicht ein wenig zu entlasten und den Längen- und Breitengrad der Projekt-Location in Variablen zu speichern:


let PLo := longitude(projektadresse);
let PLa := latitude(projektadresse);
let PI := 3.141592653589793;
select Kunden where PI * 6371 * sqrt(sqr(PLo - longitude(kundenadresse)) + sqr(PLa - latitude(kundenadresse))) / 180 <= 100

 

Ninox Profile

PS: Zur Berechnung und Anzeige der Entfernung zum Projekt innerhalb der Ansicht fiele mir jetzt nur ein, in der Tabelle Projekte ein Ja/Nein-Feld namens "Bezugspunkt" oder so zu erstellen und bei der Berechnung darauf Bezug zu nehmen. Man müsste natürlich sicherstellen, dass immer nur ein Datensatz augewählt sein kann, also bei diesem Feld "Bezugspunkt" als Trigger "Nach Änderung" bspw. folgenden Code einsetzen:


let myNr := this.Nr;
if Bezugspunkt = true then
    (select Projekte where Bezugspunkt = true and Nr != myNr).(Bezugspunkt := false)
end


Innerhalb der Ansicht könnte man dann als neue Spalte eine Funktion hinzufügen, welche die Entfernung zu dem Projekt-Standort berechnet, der als "Bezugspunkt" gekennzeichnet ist (in der Regel der, in dem sich auch die Ansicht befindet):


let myProject := first(select Projekte where Bezugspunkt);
let PLo := longitude(myProject.projektadresse);
let PLa := latitude(myProject.projektadresse);
let PI := 3.141592653589793;
PI * 6371 * sqrt(sqr(PLo - longitude(kundenadresse)) + sqr(PLa - latitude(kundenadresse))) / 180


Das ist zugegebenermaßen nicht sehr elegant, und vielleicht hat da jemand noch eine bessere Idee, es könnte aber immerhin funktionieren. Man müsste halt im Projektformular das Feld "Bezugspunkt" auf "Ja" setzen.

J

@Alex: die "Luftlinien"-Formel stellt ja die Bedingung für das Feld kundenadresse dar. Ist leider sehr verschachtelt.

Über den Filter in einem Berechnungsfeld wollte ich es erst machen, darauf ziehlt ja die zweite Frage ab. Das scheint aber derzeit unmöglich zu sein, da ich aus der Ansicht nicht auf Felder im jeweiligen Projektformular zugreifen kann.

 

@der copytexter: besten Dank, mit der Entlastung hat es geklappt. Gibt es hier einen Anhaltswert, wieviel Berechnung ein Filter verträgt?

Bei der Berechnung der jeweiligen Entfernung von Kunde zu Projekt klappt deine Lösung leider nur bedingt. Ich bekomm hier immer unterschiedliche Werte heraus, irgendwie scheint hier der Bezugspunkt zu "springen". (Je nachdem welches Projekt vorher berechnet wurde.)

Ich schätze, dass hier das Problem besteht, dass die beiden Tabellen ansich nicht miteinander verbunden sind und ich somit nicht auf die Felder in der Projekttabelle zugreifen kann, wenn ich mich über den select-Befehl in der Kundentabelle befinde.

Warten wir mal noch ab ob es weitere Ideen gibt :-)

J

@Alex: die "Luftlinien"-Formel stellt ja die Bedingung für das Feld kundenadresse dar. Ist leider sehr verschachtelt.

Über den Filter in einem Berechnungsfeld wollte ich es erst machen, darauf ziehlt ja die zweite Frage ab. Das scheint aber derzeit unmöglich zu sein, da ich aus der Ansicht nicht auf Felder im jeweiligen Projektformular zugreifen kann.

 

@der copytexter: besten Dank, mit der Entlastung hat es geklappt. Gibt es hier einen Anhaltswert, wieviel Berechnung ein Filter verträgt?

Bei der Berechnung der jeweiligen Entfernung von Kunde zu Projekt klappt deine Lösung leider nur bedingt. Ich bekomm hier immer unterschiedliche Werte heraus, irgendwie scheint hier der Bezugspunkt zu "springen". (Je nachdem welches Projekt vorher berechnet wurde.)

Ich schätze, dass hier das Problem besteht, dass die beiden Tabellen ansich nicht miteinander verbunden sind und ich somit nicht auf die Felder in der Projekttabelle zugreifen kann, wenn ich mich über den select-Befehl in der Kundentabelle befinde.

Warten wir mal noch ab ob es weitere Ideen gibt :-)

Ninox Profile

Ich würde hier doch lieber eine Beziehung aufbauen. Da wir hier mehrere Projekte haben, wo auch mehrere Aderssen passen würden, ist es sinnvoll eine Tabelle "Entfernung" o.ä. aufzubauen. Dort eine Verknüpfung  zu Projekte, eine Verknüpfung zu Kunden und ein Zahlenfeld für Entfernung. Dann entweder einen Trigger bei Änderung der Projektadresse oder einen Button:

---

let my:=this;
delete select Entfernung where Projekte=my;
let PI := 3.141592653589793;
for i in select Kunden do
let myEntf:=PI * 6371 * sqrt(sqr(longitude(my.projektadresse) - longitude(i.kundenadresse)) + sqr(latitude(my.Projektadresse - latitude(i.kundenadresse))) / 180;
if myEntf<=100 then
let new:=create Entfernung;
new.Projekte:=my;
new.Kinden:=i;
new.Entfernung:=myEntf
end
end

---

Wenn man jetzt die Tabellenspalten richtig formatiert, kann man alle adressen mit entfernung sehen. Allerdings landet man bei dem Klick erst in der Tabele Entfernung und dann nach zweitem Klick beim Kunden.

Leo

A

Vielleicht reicht es ja, wenn man sich eine Hilfstabelle mit dem aktuellen Standort einrichtet, und dann direkt auf diese zugreift. Vielleicht gibt es ja auch eine Möglichkeit, beim öffnen des Datensatzes diese Wert direkt zu aktualisieren? Sonst eben per Button.

let nEnt := this;
delete (select Xentfernung);
let xEnt := (create Xentfernung);
xEnt.(Standort := nEnt.Projektadresse)

und über die Ansicht kannst du dann im Filter direkt mit 

@Leo 

kann man das filtern evtl. mit do as server beschleunigen?

Ninox Profile

@Johannes: Theoretisch gibt es meines Wissens für die Anzahl der Funktionen bzw. Berechnungen innerhalb einer select-Anweisung keinen Grenzwert, der sich konkret quantifizieren ließe. Praktisch kann man aber offenbar doch an Grenzen stoßen (war mir bisher nicht gelungen). Ich bin auch nur darauf gekommen, weil der Code logisch und syntaktisch korrekt zu sein schien. Grundsätzlich würde ich aber sowieso immer empfehlen, innerhalb einer select-Anweisung möglichst wenige Funktionen auszuführen, und alle Berechnungen, bei denen das möglich ist, vorher durchzuführen und die Ergebnisse als Variaben in die select-Anweisung zu übernehmen.


Bei meinem Vorschlag zur Berechnung und Anzeige der Entfernungen in der Ansicht wird der Wert übrigens immer in dem Moment aktualisiert, in dem man 'Bezugspunkt' auf "Ja" setzt (siehe Screenshot). Vorher wird in der Tat ein "falscher" Wert angezeigt, weil der Bezugspunkt ja noch ein anderes Projekt ist. Das sollte technisch eigentlich funktionieren, war aber wie gesagt nur ein Workaround.

 

2020-01-19_Entfernung1


Insofern wäre Leos Vorschlag einer Entfernungstabelle wahrscheinlich der bessere Ansatz. Wobei man m. E. dafür sorgen müsste, dass die Tabelle bspw. auch beim Anlegen eines neuen Kunden aktualisiert wird.

Antworten