Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Anzahl Einträge in JsonArray (https://www.delphipraxis.net/215875-anzahl-eintraege-jsonarray.html)

rotwildmarcy 19. Sep 2024 20:01


Anzahl Einträge in JsonArray
 
Guten Abend,

ich muss für einen Schleifendurchlauf die Anzahl Einträge im JsonArray wissen.

Ich dachte, da käme man mit JsonArray.Count dran. Das wirft mir aber eime Zugriffsverletzung aus.

Delphi-Quellcode:
For i := 0 to JSonArray.Count do
Begin
   JSonObject := TJSonObject.Create;
   JsonValue:=JSonObject.ParseJSONValue(st);
   if (JSONValue is TJSONArray) then
    id := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('id').JSONValue.Value;
    name := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('name').JSONValue.Value;
    stringgrid1.Cells[1,j] := id;
Danke vorab für eine Tip in die richtige Richtung.

zeras 19. Sep 2024 20:59

AW: Anzahl Einträge in JsonArray
 
Nimm doch mal den Debugger. Dann wirst du sehen, dass er einige Male durch die Schleife kommt. Vielleicht auch mal mit "Count -1" probieren, da das Array in der Regel mit 0 anfängt und wenn bis Count iteriert wird, dann ist es einmal zuviel.

himitsu 19. Sep 2024 22:00

AW: Anzahl Einträge in JsonArray
 
Nicht nur "vielleicht"!

Aber das wird wohl nicht der Fehler sein, denn dort kommt ein Index-Fehler (OutOfRange, bzw. genauer eine EArgumentOutOfRangeException).
Viel eher würde ich auf das Get vom TJsonObject tippen,
denn das liefert NIL, wenn es kein SubObjekt mit diesem Namen (id oder name) gibt,
und demnach muß es im JSONValue knallen, weil DU die Rückgabe vorher nicht prüfst.

Und ich vermute mal stark, da sollte ein BEGIN END; hinterm
Delphi-Quellcode:
if (JSONValue is TJSONArray) then
vorkommen? :!:

Alles Dinge, die man beim Debuggen leicht bemerken könnte.




Ach ja, ParseJSONValue ist eine Class-Function,
welche man normaler Weise als
Delphi-Quellcode:
TJSONValue.ParseJSONValue(...)
aufruft.
Zitat:

Delphi-Quellcode:
JsonObject := TJsonObject.Create;
JsonValue := JsonObject.ParseJSONValue(st);

Delphi-Quellcode:
JsonValue := TJSONValue.ParseJSONValue(st);

Also das JsonObject ist unnötig. (auch wenn es zum Glück kein "Fehler" ist)

Und ich hoffe du gibst am Ende auch alles wieder brav frei. (Free)

Da es aber grad zufällig so wunderschön bei dir knallt ... Wäre super, wenn man mehr Ressorcen-Schutzblöcke (try finally) sehen würde.


PS: Den Knopf mit dem Delphi-Helm hattest du nicht zufällig bemerkt?
[delphi] dein Code [/delphi]

rotwildmarcy 20. Sep 2024 07:15

AW: Anzahl Einträge in JsonArray
 
Erstmal sorry für den vergessenen Code Tag - Ich bin hier nicht so oft unterwegs, und den hab ich tatsächlich verpennt.:wall:

Ich bin noch blutiger Anfänger, gerade was die Json Nummer betrifft.

Mir ist das leider immer noch nicht klar. Sollte denn JSonArray.Count nicht eigentlich eine Zahl auswerfen, jetzt ganz unabhängig von möglichen Fehlern in der Schleife?
Wenn ich mir das vor der Schleife, zb. mit Showmessage anzeigen lassen, kriege ich auch die Zugriffsverletzung.

DeddyH 20. Sep 2024 07:59

AW: Anzahl Einträge in JsonArray
 
Dann liegt der Verdacht nahe, dass Dein JSONArray überhaupt nicht initialisiert ist. Wenn Du vor der Schleife ein
Delphi-Quellcode:
//Vor dem Zugriff erst einmal prüfen
if Assigned(JSONArray) then
einfügst, kommt dann immer noch eine Zugriffsverletzung? Kommst Du trotzdem in die Schleife(Haltepunkt im Debugger setzen)?

rotwildmarcy 20. Sep 2024 08:21

AW: Anzahl Einträge in JsonArray
 
Er kommt dann bis zu Schleife und gibt die Zugriffsverletzung.
Wenn ich die Schleife komplett auskommentiere, geht die Anzeige von JsonArray.Count jetzt aber mit dem If Assigned

Der ausgeworfene Wert stimmt allerdings nicht. Es wird immer die 48 ausgeworfen, egal wieviel Einträge es tatsächlich sind.

DeddyH 20. Sep 2024 08:36

AW: Anzahl Einträge in JsonArray
 
Kannst Du das Array mal hier posten?

himitsu 20. Sep 2024 08:50

AW: Anzahl Einträge in JsonArray
 
Delphi-Quellcode:
for i := 0 to JSonArray.Count - 1 do
begin
  JsonValue := TJsonValue.ParseJSONValue(st);
  if (JSONValue is TJSONArray) then
    id := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('id').JSONValue.Value;

  name := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('name').JSONValue.Value;
  stringgrid1.Cells[1,j] := id;
Delphi-Quellcode:
for i := 0 to JSonArray.Count - 1 do
begin
  JsonValue := TJsonValue.ParseJSONValue(st);
  if (JSONValue is TJSONArray) then
  begin
    id := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('id').JSONValue.Value;
    name := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('name').JSONValue.Value;
    stringgrid1.Cells[1,j] := id;
  end;
Was fällt dir auf?


Delphi-Quellcode:
for i := 0 to JSonArray.Count - 1 do
begin
  JsonValue := TJsonValue.ParseJSONValue(st);
  try
    if (JSONValue is TJSONArray) then
    begin
      id := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('id').JSONValue.Value;
      name := ((JSONValue as TJSONArray).Items[i] as TJSonObject).Get('name').JSONValue.Value;
      stringgrid1.Cells[1,j] := id;
    end;
  finally
    JsonValue.Free;
  end;
Tipp: Füge mal ein
Delphi-Quellcode:
ReportMemoryLeaksOnShutdown := True;
in deine DPR oder ins OnCreate deiner Form ein.




Anzahl = Count
Bereich = 0 bis Anzahl-1 oder 1 bis Anzahl

10 = 0 bis 9 (0 1 2 3 4 5 6 7 8 9 = 10 Zahlen)
oder
10 = 1 bis 10 (1 2 3 4 5 6 7 8 9 10 = auch 10 Zahlen)
wenn bei 1 begonnen wird zu zählen

oder
10 = 99998 bis 100007 :angle2:

rotwildmarcy 20. Sep 2024 08:53

AW: Anzahl Einträge in JsonArray
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von DeddyH (Beitrag 1541270)
Kannst Du das Array mal hier posten?

Das enthält leider viele sensible Daten.
Das Array ist aber auf jeden Fall in Ordnung. (Screenshot anbei)
In diesem Fall sind es ja 10 Einträge.

Wenn's zur Problemlösung hilfreich ist, könnte ich natürlich ein kleines Beispiel Array anlegen zum testen..

Uwe Raabe 20. Sep 2024 09:00

AW: Anzahl Einträge in JsonArray
 
Wie aus dem Screenshot zu ersehen, geht der Index der Array-Elemente von 0 bis 9. Deine Schleife geht aber von 0 bis Count (= 10). Damit erzeugt der Zugriff auf das 10te Element eine Zugriffsverletzung. Die Schleife darf also nur bis Count - 1 gehen.

Das wurde auch bereits im ersten Kommentar erwähnt:
Zitat:

Zitat von zeras (Beitrag 1541249)
Vielleicht auch mal mit "Count -1" probieren, da das Array in der Regel mit 0 anfängt und wenn bis Count iteriert wird, dann ist es einmal zuviel.


himitsu 20. Sep 2024 09:08

AW: Anzahl Einträge in JsonArray
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1541274)
Damit erzeugt der Zugriff auf das 10te Element eine Zugriffsverletzung. Die Schleife darf also nur bis Count - 1 gehen.

Müsste aber eine EArgumentOutOfRangeException sein. :zwinker:

TJSONArray.GetValue -> TList<T>.GetItem -> CheckItemRange -> ErrorArgumentOutOfRange -> raise EArgumentOutOfRangeException

Ohhh, steht so sogar in der Doku drin.
Zitat:

Delphi-Quellcode:
    /// <summary> Returns the array element. Raises EArgumentOutOfRangeException exception if index is out of range </summary>
    /// <param name="Index">- element index</param>
    /// <returns>JSONValue element</returns>
    property Items[const Index: Integer]: TJSONValue read GetValue; default;


Wie gesagt, siehe #3 und #8 .... ich tippe auf das zu kurze IF, bzw. das dahinter :angle:


Zitat:

Das wirft mir aber eime Zugriffsverletzung aus.
Oder dieser Text ist gelogen falsch wiedergegeben.

Du wirst es nicht glauben, aber Strg+C funktioniert bei fast allen Dialog-Fenstern, sowie im Logfenster des Delphi,
und dann hier in einem [QUOTE] ein Strg+V.

rotwildmarcy 20. Sep 2024 09:20

AW: Anzahl Einträge in JsonArray
 
Danke für die ganzen Tips!

Bevor ich mich den Fehler in der Schleife widme, würde ich gerne die vorgelagerte Problematik der Anzahl Einträge lösen.

Array.Count gibt immer die 49 zuück, egal wieviele Einträge tatsächlich existieren.

rotwildmarcy 20. Sep 2024 09:22

AW: Anzahl Einträge in JsonArray
 
Zitat:

Das wirft mir aber eime Zugriffsverletzung aus.
Oder dieser Text ist gelogen falsch wiedergegeben.

Erste Gelegenheit für Exception bei $0086929C. Exception-Klasse $C0000005 mit Meldung 'access violation at 0x0086929c: read of address 0x81f98114'. Prozess Project1.exe (41052)

mytbo 20. Sep 2024 19:00

AW: Anzahl Einträge in JsonArray
 
Zitat:

Zitat von rotwildmarcy (Beitrag 1541276)
Bevor ich mich den Fehler in der Schleife widme, würde ich gerne die vorgelagerte Problematik der Anzahl Einträge lösen.

Du kannst den JSON-Viewer aus diesem Artikel ausprobieren. Der Quelltext ist mit dabei.

Bis bald...
Thomas

rotwildmarcy 25. Sep 2024 15:26

AW: Anzahl Einträge in JsonArray
 
Liste der Anhänge anzeigen (Anzahl: 1)
Vielen Dank an alle! Das ganze läuft mittlerweile, allerdings hat sich ein (für mich) viel größeres Problem aufgetan, wo mir so jeglicher Ansatzpunkt fehlt.

So sieht das ganze bis dato aus und läuft auch.

Code:
var
  JSonObject: TJSonObject;
  JSonValue: TJSonValue;
  JSonArray: TJsonArray;
  id, name, description, sku: string;
  i,j: integer;
begin
JsonValue := TJSONObject.ParseJSONValue(Memo1.Text);

  if Assigned(JsonValue) then
  try
    JSonArray := JsonValue as TJSONArray;
    j := 1;
    for i := 0 to JSonArray.Count-1 do
    begin
      JSonObject := JSonArray.Items[i] as TJSonObject;

      id := JSonObject.GetValue('id').Value;
      sku := JSonObject.GetValue('sku').Value;
      description := JSonObject.GetValue('description').Value;
      name := JSonObject.GetValue('name').Value;
     
      //Überschriften
      StringGrid1.Cells[0,0] := 'ID';
      StringGrid1.Cells[1,0] := 'Artikelnummer';
      StringGrid1.Cells[2,0] := 'Name';
      StringGrid1.Cells[3,0] := 'Preis';
      StringGrid1.Cells[4,0] := 'Beschreibung';

      // Daten
      StringGrid1.Cells[0,j] := id;
      StringGrid1.Cells[1,j] := sku;
      StringGrid1.Cells[2,j] := name;
      StringGrid1.Cells[3,j] := price1;
      StringGrid1.Cells[4,j] := description;

      Inc(j);
    end;
  finally
    JsonValue.Free;
  end;
end;
Jetzt habe ich aber festegestellt, dass ich auch noch ein paar Info's brauche, welche tiefer verschachtelt sind und sich (vermutlich) per Name nicht ansprechen lassen.
Und genau endet mein eh bescheidenes KnowHow im Moment.
Ich habe die Struktur mal angehangen. Der Knoten 'bm_psi_bulk_prices' ist auf jeden Fall immer vorhanden, aber nicht zwangsläufig gefüllt, und kann auch mehr oder weniger Einträge haben.
Danke für einen kleinen Ansatz, wie ich mich da rantasten kann.

fisipjm 26. Sep 2024 06:51

AW: Anzahl Einträge in JsonArray
 
Zitat:

Zitat von rotwildmarcy (Beitrag 1541522)
Ich habe die Struktur mal angehangen. Der Knoten 'bm_psi_bulk_prices' ist auf jeden Fall immer vorhanden, aber nicht zwangsläufig gefüllt, und kann auch mehr oder weniger Einträge haben.
Danke für einen kleinen Ansatz, wie ich mich da rantasten kann.

Wie Himitsu ja auch schon mehrfach geschrieben hat, würde ich ein
Delphi-Quellcode:
GetValue('bm_psi_bulk_prices') AS TJSONObject
oder
Delphi-Quellcode:
GetValue('bm_psi_bulk_prices') AS TJSONArray
versuchen, je nachdem was dort drin steht (Ohne JSON Struktur mehr Glaskugel als wirklich Hilfe). Ist der Punkt gefüllt hast du dein Arrray/Object in der übergabe oder eben NIL. Das heißt vorher auf nil prüfen wenn nil dann nix machen, wenn nicht nil, dann weiter mit dem was auch immer du machen willst.

Ich weiß der Einsprung in JSON kann einem einen guten Knoten in den Kopf machen, aber so Schwer ist das eigentlich nicht:
JSON hat eigentlich nur 3 Unterschiedliche Arten, der Datenübertragung.
1.) JSONArray - gekennzeichnet durch []
2.) JSONObject - gekennzeichnet durch {}
3.) JSONValue - Key/value pair im Aufbau "MeinString":"mein String" oder "MeinInteger":123

alles wird immer von nächsten Wert mit einem Komma abgegrenzt. Zu allen Teilen gibt es in Delphi Entsprechungen (Mehrfach) die das einlesen können und mit dem du die Struktur durchgehen kannst.
Alle Möglichkeiten findest du hier:
https://docwiki.embarcadero.com/RADS...Athens/en/JSON



vG
Patrick

PS: Hab gerade das BIld gesehen, ist noch Früh :)
Also die Abfrage wäre dann auf GetValue('value') AS TJSONArray. Das Array musst du dann wieder einzeln durchgehen und die einzelnen Objects auslesen, wenn das Array nicht nil ist.
Ich würde dir Empfehlen JSON Code in z.B. Notepad++ anzusehen, lade dir zur not einen JSON prettyfier herunter. Dann siehst du aber auch direkt was ein Array und was ein Objekt ist, hab das Gefühl durch deinen Viewer machst du dir den Einstieg nur noch schwieriger.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz