Automatische Kilometerberechnung über Google
Für alle, die auf der Suche nach einer automatischen Berechnung der Kilometer sind, hier mein Lösungsansatz:
Start-Adresse (Text-Feld)
Ziel-Adresse (Text-Feld)
Google (Berechnungs-Feld)
Km (Berechnungs-Feld)
Code Google-Feld
text(http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Ziel-Adresse' + "&key=API_KEY"))
Den API-Key von Google kann man sich hier erstellen lassen und bei API_KEY einsetzen.
Code Km-Feld
let at := text(extractx(Google, "(text...)\d*.\d*"));
text(extractx(at, "\d+.\d+"))
Als Übergangslösung bis Ninox mit Arrays arbeiten kann, funktioniert es super.
Sobald man nun in das Start- und Zielfeld eine Adresse eingibt, berechnet er die Kilometer der schnellsten Route.
Man kann das ganze auch noch mit einem Button vervollständigen, der die Route in Google-Maps oder Apple-Maps öffnet.
Für Google:
openURL("http://maps.google.com/maps?saddr=" + text('Start-Adresse') + "&daddr=" + text('Ziel-Adresse') + "&hl=de")
Für Apple-Karten:
openURL("http://maps.apple.com/maps?daddr=" + text('Straße' + " " + 'Hausnr.' + " " + PLZ + " " + Ort))
84 Antworten
-
Hallo,
in der PDF-Ausgabe habeb ich ein Funktionsfeld mit folgendem Code
let myGrund := 'Grund der Reise'.Grund;
let myBeginn := Dienstreisen.'Beginn der Reise';
let mykm := first((select Dienstreisen)['Grund der Reise'.Grund = myGrund and 'Beginn der Reise' = myBeginn].'km Fahrt');
if mykm != null then mykm endAls Ausgabe erhalte ich "0 km", obwohl im Feld "km Fahrt" ein durch Google-Abfrage erhaltener Wert enthalten ist. Soll heißen: das Feld "km Fahrt" in der Tabelle "Dienstreise" ist ein Funktionsfeld, das den in diesem Thread kommunizierten Google-Abfrage-Code einschl. Key enthält. Obwohl dort z. B. 31 km ausgegeben wird, bekomme ich die 31 km nicht in die PDF-Ausgabe.
Woran kann es liegen?
Grüße
Maurice
-
Hallo Maurice,
wenn deine Formel mit let myBeginn... stimmt, dann ist die Tabelle Dienstreisen fest mit der Ausgabetabelle verknüpft. In diesem Fall brauchst du keine select Anweisung um Dienstreisen anzusprechen, also einfach
—-
Dienstreisen.'km Fahrt
'—-
eingeben
Leo
-
Hallo Leo,
da ist richtig. Ich habe mykm eingeführt, um die Bedingungen einzubringen. Aber das ginge ja dann auch mit einer if-Schleife. Problemweiterhin: Auch nur
Dienstreisen.'km Fahrt'
bringt die Ausgabe "0" (mit meinem obigen Code erhalte ich "0 km".
Die Null ist das Problem. In der Formularansicht von Dienstreisen steht "91 km".
Grüße
Maurice
-
Dann brauche ich mehr Info. Datenmodell und Datenstruktur der Printausgabetabelle
-
Versuch bitte das Berechnungsfeld mit der Formel (Dienstreisen.'km Fahrt') in der Tabelle Anträge zu erstellen und im Layout direkt ansprechen
-
Habe ich getan. Im (neuen) Berechnungsfeld der Tabelle Anträge wird die korrekte Kilometeranzahl angezeigt. Das Feld im PDF-Layout bringt wieder nur eine 0. Habe auch mal number(Dienstreisen.'km Fahrt') in das Berechnungsfeld gesetzt. Gleiches Ergebnis. Ist das ein Bug?
-
Ich glaube, dass die REST Abfrage einfach viel langsammer abläuft, als für layout-Berechnung notwendig ist. Ich würde die km Start-DG und km Ende-DG als ZahlenEinfügen und die Werte per skript fest rein schreiben (z.B. per Button). Dann sollte es klappen.
Leo
-
Versuch mal das Feld in ein Textfeld oder Zahlenfeld zu schreiben. Am besten ein Button mit dem ganzen code von oben und dann nur bei der stelle round(number(km.value) / 1000, 0) machst du Textfeld := round(number(km.value) / 1000, 0)
-
Hallo Leo und Bastian,
echt klasse, dass ihr mir helft. Das Forum hier ist spitze.
Leos Vorschlag verstehe ich nicht ganz. Wo soll ich die km Angaben von Start-DG und Ende-DG als Zahlen einfügen? Und wo die Werte per Script reinschreiben?
Das Merkwürdige ist ja, dass im Feld "km-Fahrt" mit den Ergebnissen aus Start-DG und Ende-DG richtig gerechnet wird.
Bastain, deinen Vorschlag habe umgesetzt: einen Button mit dem Google-Code und am Ende Ergebnis := round ...; Ergebnis ist ein Textfeld, das ich neu angelegt habe. Das Feld bleibt leer, ebenso, wenn ich das Feld als Zahlfeld anlege.
Grüße
Maurice
-
In dem Response gibt er ja auch km mit aus und ninox erkennt dies dann als text. Text kannst du aber nicht in ein Zahlenfeld wandeln darum musst du die km mit replace(text(km), "km", null) wegbekommen. Leider ist es damit noch nicht getan, du musst aus dem komma ein punkt machen also wenn bei dir 5,5 km entfernung kommen musst dieses komma wegbekommen und erst dann kann der wert als number gewandelt werden und auch erst dann in ein Zahlenfeld geschrieben werden. Vielleicht hat leo da eine einfache Lösung.
-
Aber warum addiert Ninox die beiden Response-Felder Start-DG und Ende-DG im Feld "km-Fahrt" korrekt? Wenn das nur als Text aufgefasst würde, ginge das doch nicht, oder? Aber dachte, wenn schon richtig addiert, sollte Ninox das auch leicht weiterverweten können (im PDF).
-
Noch eine Merkwürdigkeit: füge ich in mein PDF-Layout eine Tabelle ein, so wird die Spalte 'km Fahrt' korrekt ausgegeben.
So werde ich das vielleicht lösen als workaround. Ich brauche aber nur einen Datensatz - mal schauen.
-
Hallo zusammen,
nach den ganzen Diskussionen hier und auch auf Telegramm habe ich mir den Code nochmals angeschaut. Es werden immernoch die Texte vor Responce analysier obwohl Ninox schon lange in der Lage ist Json zu lesen. In der Cloud funktioniert die Google-Abfrage auch. man muss nur do as Server verwenden. Also Angenommen es gibt zwei Textfelder:
'Start-Adresse'
'Ziel-Adresse'
Dann noch das Feld Zeitdauer (von Typ Zeitdauer)
und ein Zahlenfeld Entfernung.
Dann wäre die Formel für einen Button:
---
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Ziel-Adresse' + "&key=*********************")
end;
Zeitdauer := number(last(first(gcode.result.rows).elements).duration.value) * 1000;
Entfernung := number(first(first(gcode.result.rows).elements).distance.value) / 1000
---
man sollte selbstverständlich den eigenen Key einsetzen. Ich habe hier auf Prüfungen, ob die Adressfelder nicht leer sind, verzichtet. Es geht mir erstmal um json-Auswertung.
Die Zeitdauer kommt hier in Millisekunden und die Entfernung in km.
Leo
-
Hallo Leo,
vielen Dank. Das Feld Entfernung lässt sich im PDF-Formular ansprechen.
Jetzt habe ich noch ein Problem: der von dir gepostete Code funktioniert bei einem Button. In einem Berechnungsfeld erscheint die Meldung, dass diese Funktion keine Datenveränderungenn vornehmen kann. Über response ging das.
Ich hätte (natürlich) gerne in meiner Tabelle, dass ich etwas in das Start und/oder Ziel Feld tippe und sofort die Abfrage erfolgt, ohne auf einen Button klicken zu müssen. Dazu muss ich den Button triggern über die Änderung der Felder Start bzw. Ziel (die bei mir selbst ein Funktionsfeld sind, da sie aus mehreren Feldinhalten zusammen gesetzt werden, aber das Triggern erfolgt dann über die ursprünglichen Felder).
Ich finde den Namen der Befehlsschlatfläche (Button) aber nicht in der Übersicht der Feldnamen, so dass ich irgendwie als Trigger-Funktion "Button = true" eingeben könnte. Wie trigger ich den Button bei einer Änderung?
Grüße
Maurice
-
Hallo Maurice,
Die Formel für ein Berechnngsfeld soll anders aussehen. Für Zeitdauer:
---
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Ziel-Adresse' + "&key=*********************")
end;
number(last(first(gcode.result.rows).elements).duration.value) * 1000
---
Für Entfernung:
---
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Ziel-Adresse' + "&key=*********************")
end;
number(first(first(gcode.result.rows).elements).distance.value) / 1000
---
Ich bin kein Freund von Berechnungsfelder mit REST-Abfragen. Stell dir for, du hast 1000 Datensätze und in einer Tabellenansicht die Spalten Entfernung und Zeitdauer. Auch wenn die Abfrage nur 1 Sekunde dauern würde, braucht Ninox zum Aufbauen der Tabellenansicht 1000 *1*2:=2000s=33 min. Viel besser wäre es, wenn die Felder eben als Zahl bzw. Zeitinterval angelegt sind und bei beiden Textfelder Start- und Ziel-Adresse einen Trigger nach Änderung angelegt ist:
---
if 'Start-Adresse' and 'Ziel-Adresse' then
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Ziel-Adresse' + "&key=*********************")
end;
Zeitdauer := number(last(first(gcode.result.rows).elements).duration.value) * 1000;
Entfernung := number(first(first(gcode.result.rows).elements).distance.value) / 1000
end
---
so prüft Ninox bei Änderung eines Adressfeldes ob beide Adressfelder gefüllt sind und falls JA fragt bei Google die Entfernung und die Zeit an.
Leo
-
Hallo Leo,
deine Überlegungen zur Zurückhaltung bei der Google-Abfrage überzeugen, aber das klappt nicht bei mir.
Bei mir werden die Start-Adresse und Ziel-Adresse, aus dem für Google Start und Ziel gelesen werden, wie folgt generiert:
let myStart := Start;
let Maurice := first(select 'Persönliche Daten' where Vorname = "Maurice");
switch myStart do
case 1:
Maurice.'Straße' + ", " + Maurice.PLZ + " " + Maurice.Wohnort
case 2:
Maurice.'Straße Stammdienststelle' + ", " + Maurice.'PLZ Stammdienststelle' + " " + Maurice.'Ort Stammdienststelle'
default:
'Schlagwörter, Startadresse' + " " + 'PLZ, Start' + " " + 'Ort, Start'
end
sprich: ich habe ein Mehrfachauswahlfeld 'Start' mit 3 Optionen. Bei den ersten beiden Optionen wird das Feld 'Start-Adresse' automatisch vorbelegt mit meiner Daten aus einer anderen Tabelle, bei der dritten Option (default) erscheinen drei Eingabefelder, die dann übernommen werden.
Ein Funktionsfeld hat ja keine Option "Nach Änderung Skript ausführen", weshalb ich deinen Code in das Mehrfachauswahlfeld platziert habe. Wenn ich dort aber meine Auswahl ändere von z. B. case1 auf case2 ändert sich bei Zeitdauer und Entfernung nichts. Über einen Button, der den gleichen Code enthält, ändern sich die Einträge bei Zeitdauer und Entfernung.
Grüße
Maurice
-
Das Fatale ist: nur über ein Zahlfeld 'Entfernung' bzw. Zeitdauerfeld kann ich die Daten in das PDF-Layout übernehmen. Steht die Entfernung in einem Berechnungsfeld mit Google-API - das war ja mein Ausgangsproblem -, dann steht im PDF-Feld nur ein 0 km, obwohl in der Tabelle eine km-Berechnung ausgegeben wird.
-
Hallo,
hier bin ich zwar fündig geworden, aber nicht weiter gekommen:
Dort lese ich, dass im Trigger-Feld keine Feldinhalte geändert werden können. Den dort vorgeschlagenen Workaround konnte ich nicht umsetzen (vielleicht, weil ich ihn nicht verstanden habe).
Ich habe den Google-Code einschl. die Anweisung für die Felder Zeitdauer und Entfernung in eine Funktion ins TRigger-feld der Tabelle gepackt. Ein Ja/Nein Feld wird über meine Auswahlfelder für die Startadresse gesteuert. Leider kein Erfolg.
Hat noch jemand eine Idee?
Grüße
Maurice
-
Hallo, kennt jemand den Grund, warum:
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + 'Start-Adresse' + "&destinations=" + 'Dienstgeschäft-Adresse' + "&mode=bicycling" + "departureTime:" + 'Beginn der Reise' + "&key=*************************")
end;
'Dauer Hinfahrt' := number(last(first(gcode.result.rows).elements).duration.value) * 1000;
mir als Reisezeit (Dauer Hinfahrt) immer die Zeit mit dem Auto ausgibt. Egal, was ich bei mode einstelle, es erscheint die Autoreisezeit.
Hat jemand einen Tipp?
Grüße
Maurice
-
Hallo
seit ein paar Wochen funktioniert mein alter Code zum Berechnen der Entfernung nicht mehr. Ich habe nun diese hier probiert, gehen auch nicht. Alles angepasst, keine Chance. Gibts da irgendeine umstellung seitens ninox oder google die hier nicht berücksichtig wurde? Danke für eure Unterstützung.
VG Dominik
-
Stimmt, bei mir auch. Keine Zeit, keine Entfernung, nur leere Felder.
-
Diese Formel funktioniert bei mir:
---
l
et gURL := url("https://maps.googleapis.com/maps/api/distancematrix/json", {
origins: Startadresse,
destinations: Zieladresse,
mode: "car",
key: "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
});
let gcode := do as server
http("GET", gURL)
end;
Zeitdauer := number(last(first(gcode.result.rows).elements).duration.value) * 1000;
Entfernung := number(first(first(gcode.result.rows).elements).distance.value) / 1000
---
Leo
-
Hallo.
Ich hatte diesen Fehler schon am 18.01.21 dem Ninox-Support gemeldet. Auch folgte mit Sam ein sehr intensiver Austausch zu dieser Problematik.
Weder die "do as Server", noch die "normale" Version funktionierte in der Mac-App / Web-Version und in der iPad-App. In der iPhone-App funktionierte die Google-Distanzabfrage bis zur Version 2.7.3. Ab der iPhone-Version 2.8.0 funktioniert es auch in der iPhone-App nicht mehr.
Ich habe auf dem iPad noch die 2.7.3 iPhone-App installiert, da funktioniert es auch heute noch.
Ninox weiß vom Fehler, ignoriert es aber hartnäckig.
-
Hallo Jens,
die Formel, die ich gepostet habe funktioniert sowohl als Button als auch als Trigger bei Änderung in Web (Windows, Chrome), in der Mac App (letzte Version), Mac Web Safari, iPhone App letzte Version. Ich habe leider kein iPad, daher keine Aussage diesbezüglich.
Leo
-
Hallo Leo.
Danke für die schnelle Hilfe.
Die Distanzabfrage verhält sich eigenartig.
Der Code mit "do as Server" funktionierte in der Vergangenheit in der Mac-App und iPhone-App über iCloud. Ab einem Update Anfang des Jahres ging nur noch die iphone APP.
Dann hatte ich nach Rücksprache mit Sam den Code ohne "do as Server" geschrieben. Mac-App = 0 / iPhone App 2.7.3 = OK
Aktueller Stand:
Mac Safari Web Ninox Cloud: Meine beiden Codes (die bisher immer funktionierten) = 0 / Dein Code = OK
Mac App Ninox-Cloud : Meine beiden Codes (die bisher immer funktionierten) = 0 / Dein Code = OK
Mac App iCloud: Meine beiden Codes (die bisher immer funktionierten) = 0 / Dein Code = 0
iPhone APP 2.8.1 Ninox-Cloud: Meine beiden Codes (die bisher immer funktionierten) = 0 / Dein Code = OK
iPhone APP 2.8.1 iCloud: Meine beiden Codes (die bisher immer funktionierten) = 0 / Dein Code = 0
iPhone APP 2.7.3 Ninox Cloud: mit "do as Server" = 0 / ohne "do as Server" = OK / Dein Code = OK
iPhone APP 2.7.3 iCloud: Meine beiden Codes (die bisher immer funktionierten) = OK / Dein Code = OK
Fazit:
Dein Code funktioniert mit der iCloud-Version mit den neuesten Updates Mac & iPhone auch nicht, aber über die Ninox-Cloud.
Alle drei Codes funktionieren mit der iCloud-Version auf dem iPhone mit der App 2.7.3
Hier die Codes, die früher funktionierten.
Mit do as server
"
//--- Google Maps km ohne und mit Autobahn abrufen und die optimalste Strecke (Entfernung mA) an 'einfache Strecke' übergeben.";
let API_Key := "'API-Key'";
"//--- Abruf Autobahn vermeiden und Übergabe Daten";
let gcode := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + Startadresse + "&destinations=" + Zieladresse + "&avoid=highways" + "&key=" + 'API-Key')
end;
'Zeit oA 1' := number(last(first(gcode.result.rows).elements).duration.value) * 1000;
'Km oA 1' := number(first(first(gcode.result.rows).elements).distance.value) / 1000;
"//--- Abruf optimale Strecke lt. Google - Autobahn erlaubt und Übergabe Daten";
let gcode2 := do as server
http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + Startadresse + "&destinations=" + Zieladresse + "&key=" + 'API-Key')
end;
'Zeit mA 1' := number(last(first(gcode2.result.rows).elements).duration.value) * 1000;
'Km mA 1' := number(first(first(gcode2.result.rows).elements).distance.value) / 1000;
"
//--- Ergebinsfeld zur Kontrolle, ob Daten abgerufen";
'Ergebnis Abfrage mit Server' := text(gcode2.result)ohne do as server
"
//--- Google Maps km ohne und mit Autobahn abrufen und die optimalste Strecke (Entfernung mA) an 'einfache Strecke' übergeben.";
let API_Key := 'API-Key';
"//--- Abruf optimale Strecke lt. Google - Autobahn erlaubt und Übergabe Daten";
let gcode_mA := text(http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + Startadresse + "&destinations=" + Zieladresse + "&key=" + API_Key));
'Zeit mA 2' := number(extractx(extractx(gcode_mA, "Minuten...value..\d+"), "\d+")) * 1000;
'Km mA 2' := number(extractx(extractx(gcode_mA, "\d+.\d+ km"), "\d+."));
"//--- Abruf Autobahn vermeiden und Übergabe Daten";
let gcode_oA := text(http("GET", "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + Startadresse + "&destinations=" + Zieladresse + "&avoid=highways" + "&key=" + API_Key));
'Zeit oA 2' := number(extractx(extractx(gcode_oA, "Minuten...value..\d+"), "\d+")) * 1000;
'km oA 2' := number(extractx(extractx(gcode_oA, "\d+.\d+ km"), "\d+."));
"//--- Ergebinsfeld zur Kontrolle, ob Daten abgerufen
";
'Ergebnis Abfrage ohne Server' := gcode_mA
Content aside
- vor 3 JahrenZuletzt aktiv
- 84Antworten
- 23967Ansichten