Aktuelle Zeit: 16.06.2019 12:33

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 18.05.2019 19:39 
Offline

Registriert: 21.07.2017 22:36
Hallo,

Ich lese zur Zeit Daten aus einer .json Datei aus und extrahiere sie dann in eine Variable, die einer Struktur zugeordnet ist.

Code:
Structure JSON_ITEM
  Name.s
  Row.i
  Type.i
  CompareWith.s
EndStructure

Structure JSON_SHEET
  List Items.JSON_ITEM()
  Name.s
  FirstClientRow.i
  FirstClientColumn.i
EndStructure

Structure JSON_FORM
  Revision.s
  LastSaved.i
  RequiredSheets.s
  List Sheets.JSON_SHEET()
EndStructure

Global Form.JSON_FORM

Define.i hJSON
Define.s jsonFile
jsonFile = "R:\_json.json"

hJSON = LoadJSON(#PB_Any, jsonFile)
If hJSON
  ExtractJSONStructure(JSONValue(hJSON), @Form.JSON_FORM, JSON_FORM)
Else
  Debug "Malformed JSON detected!" + #CRLF$ + #CRLF$ +
        "Message: " + JSONErrorMessage() + #CRLF$ +
        "Line:    " + JSONErrorLine() + #CRLF$ +
        "Column:  " + JSONErrorPosition()
EndIf


Das ist soweit fein und unproblematisch. Das Ganze wird aber spaeter im Programm sehr zeitkritisch,
weil ich in einem aeusseren foreach loop jedesmal durch die Liste Items.JSON_ITEM() durchgehen
muss, um den Eintrag "Name" von dort mit einem anderen String zu vergleichen.

Viel schneller ginge es, wenn ich es mit einem FindMapElement() machen koennte, was mir gleichzeitig
auch sofort den Zeiger auf das Element liefern wuerde, dessen Daten ich brauche...

Deshalb die Frage ob es moeglich ist, die folgenden .json Daten so zu veraendern, dass ich statt
List Items.JSON_ITEM()
Map Items.JSON_ITEM()
in der JSON_SHEET Struktur verwenden kann.

Also das "S1_PV_K_GM", "S1_PV_K_GW", etc. zu "MapKeys" werden?

Anmerkung:
UTF-8 Datei erstellen, folgende Daten reinkopieren, als "_json.json" abspeichern und Pfad anpassen:
Code:
   {
      "Revision"       : "v1",
      "LastSaved"      : 23432432,
      "RequiredSheets" : "GS,MB",
      "Sheets"         : [
         {
            "Name"              : "GS",
            "FirstClientColumn" : 6,
            "FirstClientRow"    : 7,
            "Items"             : [
               {
                  "Name"        : "S1_PV_K_GM",
                  "Row"         : 7,
                  "Type"        : 1,
                  "CompareWith" : "männlich"
               },
               {
                  "Name"        : "S1_PV_K_GW",
                  "Row"         : 7,
                  "Type"        : 1,
                  "CompareWith" : "weiblich"
               },
               {
                  "Name"        : "S1_PV_K_FN",
                  "Row"         : 8,
                  "Type"        : 2,
                  "CompareWith" : ""
               }
            ]
         },
         {
            "Name"              : "MB",
            "FirstClientColumn" : 6,
            "FirstClientRow"    : 5,
            "Items"            : [
               {
                  "Name"        : "S4_ERG_IB_Y",
                  "Row"         : 203,
                  "Type"        : 1,
                  "CompareWith" : "ja"
               }
            ]
         }
      ]
   }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 18.05.2019 20:52 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Wenn ich das richtig verstehe ist die Json-Datei nicht von dir ?

Dann ist es recht simple, wenn du in die Struktur selbst eine
MAP einfügst, und den dann mit den Adressen der Elemente füllst. Am besten gleich nach ExtractJSONStructure.
Dieses wird bei ExtractJSONStructure übersprungen, weil kein Element so heisst... also bleibt es leer.

Code:
Structure JSON_ITEM
  Name.s
  Row.i
  Type.i
  CompareWith.s
EndStructure

Structure JSON_SHEET
  List Items.JSON_ITEM()
  Map *ItemName()
  Name.s
  FirstClientRow.i
  FirstClientColumn.i
EndStructure

Structure JSON_FORM
  Revision.s
  LastSaved.i
  RequiredSheets.s
  Map *SheetName()
  List Sheets.JSON_SHEET()
EndStructure

Global Form.JSON_FORM

Define.i hJSON
Define.s jsonFile
jsonFile = "d:\_json.json"

hJSON = LoadJSON(#PB_Any, jsonFile)
If hJSON
  ExtractJSONStructure(JSONValue(hJSON), @Form.JSON_FORM, JSON_FORM)
  ForEach Form\Sheets()
    Form\SheetName(Form\Sheets()\Name) = @Form\Sheets()
    ForEach Form\Sheets()\Items()
      Form\Sheets()\ItemName(Form\Sheets()\Items()\Name) = @Form\Sheets()\Items()
    Next
  Next
 
Else
  Debug "Malformed JSON detected!" + #CRLF$ + #CRLF$ +
        "Message: " + JSONErrorMessage() + #CRLF$ +
        "Line:    " + JSONErrorLine() + #CRLF$ +
        "Column:  " + JSONErrorPosition()
EndIf

Define *Sheet.JSON_SHEET
Define *Item.JSON_ITEM

If FindMapElement(Form\SheetName(), "GS")
  *Sheet = Form\SheetName()
  If FindMapElement(*Sheet\ItemName(), "S1_PV_K_FN")
    *Item = *Sheet\ItemName()
  EndIf
EndIf

If *Item
  Debug *Item\Name
  Debug *Item\Row
  Debug *Item\Type
  Debug *Item\CompareWith
  *Item = #Null
EndIf

_________________
PureBasic 5.70 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 18.05.2019 21:21 
Offline

Registriert: 21.07.2017 22:36
Hallo Bisonte,

vielen Dank fuer deine Hilfe!

Mit meiner alten Variante braucht das, was ich gerade tue bei einem Durchlauf
~440 ms (und ich brauche etwa 100 Durchlaeufe), also etwa 44 Sekunden.

Mit deiner Variante nur noch ~330 ms, respektive 33 Sekunden. :allright:

Zitat:
Wenn ich das richtig verstehe ist die Json-Datei nicht von dir ?

Doch, ist sie. Ich kann frei ueber ihren Aufbau bestimmen. Aendert das etwas
an deiner vorgeschlagenen Loesung?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 00:56 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Dann kann man die Listen gleich in Maps umbauen.

_________________
PureBasic 5.70 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 01:36 
Offline

Registriert: 21.07.2017 22:36
Ja, das war mein Anfangsgedanke. Dummerweise hab ich eine Denkblokade, wie ich das anstellen soll.
Irgendwie muss ich dann ja aus jedem "Name" unter "Items" direkt einen MapKey bauen und mir ist im
Moment unklar, wie das funktionieren soll...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 06:51 
Offline
Benutzeravatar

Registriert: 08.03.2013 14:27
Wohnort: ERB
Bei solchen "komplexeren" JSON-Strukturen würde ich, wenn ich gezielt in den Daten suchen will, die Daten in eine "In-Memory-SQLite" überspielen. In der kann ich gezielt und schnell nach einem bestimmten Datensatz suchen.

JSON ist eigentlich nur dazu da, Objekte und damit verbunden Daten strukturiert als String über das HTTP-Protokoll zu übertragen. Um aber gezielt in den Daten zu suchen ist es ratsamer, die Daten in einen anderen Typ zu übertragen, der sich leichter durchsuchen lässt. SQLite eignet sich dafür 1000x besser als verschachtelte Strukturen, Listen und/oder Maps.

Gerade bei JSON-Files, die Datensätze enthalten und nicht nur ein Datensatz sind, würde ich immer diesen Umweg gehen.

Alternativ kannst du aber auch Datensätze per regulärem Ausdruck im JSON-File suchen und dann nur diesen in eine Struktur zu überführen. Aber dafür muss man richtig Plan über reguläre Ausdrucke haben.

_________________
USAC Protokoll
Universal Stringbased Application Communication Protocoll

Github: Zum Spezifikationdokument v0.01


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 10:25 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
In der Tat. Wenn viele Daten vorhanden sind und es auf Geschwindigkeit ankommt, dann SQLite.

Bei deiner Messung der Zeit für 100 Durchläufe, wäre es interessant zu sehen, wie das passiert...
und das der Debugger, bei solch einer Messung, nicht eingeschaltet sein darf, sollte auch klar sein ;)

Nichtsdestotrotz wäre das evt. so in der JSON Variante :

Code:
Structure JSON_ITEM
  Name.s
  Row.i
  Type.i
  CompareWith.s
EndStructure
Structure JSON_SHEET
  Map Items.JSON_ITEM()
  Name.s
  FirstClientRow.i
  FirstClientColumn.i
EndStructure
Structure JSON_FORM
  Revision.s
  LastSaved.i
  RequiredSheets.s
  Map Sheets.JSON_SHEET()
EndStructure

Global Form.JSON_FORM

With Form
  \Revision = "v1"
  \LastSaved = 23432432
  \RequiredSheets = "GS,MB" 
EndWith

Procedure.i AddSheet(Name$, FirstClientRow, FirstClientColumn)  ; Keine Rückgabe
 
  Form\Sheets(Name$)\Name               = Name$
  Form\Sheets(Name$)\FirstClientRow     = FirstClientRow
  Form\Sheets(Name$)\FirstClientColumn  = FirstClientColumn
 
EndProcedure
Procedure.i AddItem(SheetName$, Name$, Row, Type, CompareWith$) ; Gibt #True zurück, wenn Item erstellt wurde, ansonsten #False
 
  Protected Result = #False
 
  If FindMapElement(Form\Sheets(), SheetName$)
    With Form\Sheets(SheetName$)\Items(Name$)
      \Name         = Name$
      \Row          = Row
      \Type         = Type
      \CompareWith  = CompareWith$
    EndWith
    Result = #True
  EndIf
 
  ProcedureReturn Result
 
EndProcedure
Procedure.i SaveData(File$)                                     ; Gibt #True zurück, wenn erfolgreich gespeichert, ansonsten #False
 
 
  Protected Result = #False, jSon = CreateJSON(#PB_Any, #PB_JSON_NoCase)
 
  If jSon
    InsertJSONStructure(JSONValue(jSon), @Form, JSON_FORM)
    Result = SaveJSON(jSon, File$, #PB_JSON_PrettyPrint)
    FreeJSON(jSon)
  EndIf
 
  ProcedureReturn Result
 
EndProcedure
Procedure.i LoadData(File$)                                     ; Gibt #True zurück, wenn geladen, ansonsten #False
 
  Protected Result = #False, jSon = LoadJSON(#PB_Any, File$, #PB_JSON_NoCase)
 
  If jSon
    ExtractJSONStructure(JSONValue(jSon), @Form, JSON_FORM)
    FreeJSON(jSon)
    Result = #True
  EndIf
 
  ProcedureReturn Result
 
EndProcedure

Procedure.i GetItem(SheetName$, ItemName$, *Item.JSON_Item)     ; Füllt *Item.JSON_ITEM. Wenn Erfolg dann #True, ansonsten #False
 
  Protected Result = #False
 
  If *Item
    If FindMapElement(Form\Sheets(), SheetName$)
      If FindMapElement(Form\Sheets()\Items(), ItemName$)
        *Item\Name        = Form\Sheets()\Items()\Name
        *Item\Row         = Form\Sheets()\Items()\Row
        *Item\Type        = Form\Sheets()\Items()\Type
        *Item\CompareWith = Form\Sheets()\Items()\CompareWith
        Result = #True
      EndIf
    EndIf
  EndIf
 
  ProcedureReturn Result
 
EndProcedure

AddSheet("MB", 6, 5)
AddItem("MB", "S4_ERG_IB_Y", 203, 1, "ja")

AddSheet("GS", 6, 7)
AddItem("GS", "S1_PV_K_GM", 7, 1, "männlich")
AddItem("GS", "S1_PV_K_GW", 7, 1, "weiblich")
AddItem("GS", "S1_PV_K_FN", 8, 2, "ja")

; SaveData("d:\__jsonNEU.json")
; LoadData("d:\__jsonNEU.json")

Define Item.JSON_ITEM

If GetItem("GS", "S1_PV_K_GW", @Item)
  Debug Item\Name
  Debug Item\Row
  Debug Item\Type
  Debug Item\CompareWith
EndIf

_________________
PureBasic 5.70 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 10:53 
Offline

Registriert: 21.07.2017 22:36
Danke Troax und Bisonte!

Pro json Datei hab ich im Maximum nicht mehr als 500 items und das ist schon relativ viel. Der Durchschnitt
bewegt sich eher bei 100-200. Ich bin nicht sicher, ob sich SQLite da schon wirklich lohnen wuerde aber
ich werde das mal implementieren und mir dann mal die Zeiten anschauen.

Zitat:
Bei deiner Messung der Zeit für 100 Durchläufe, wäre es interessant zu sehen, wie das passiert...
und das der Debugger, bei solch einer Messung, nicht eingeschaltet sein darf, sollte auch klar sein


Ich iteriere ueber ein COMateObject (COMatePLUS), genauer gesagt ueber eine Enumeration (Form fields
fuer ein Word Formular). Die noetigen Zuordnungen dafuer, was dann spaeter eingetragen werden soll (die
eigentlichen Elemente werden aus einer Excel-Tabelle geholt) stehen also in den .json Daten. Das Ganze
wird deshalb auf diese Art und Weise gemacht, damit ich fuer weitere Formulare das Hauptprogramm gar
nicht mehr anfassen brauch, sondern nur noch ein Formular mit Feldern erstelle und die zuegehoerige
.json Datei. Ich gebe fuer Geschwindigkeitstest die Angaben alle per OutputDebugString_ aus (und DbgView
stellt sie dann dar). Das Ganze nachdem die .pb Datei kompiliert wurde...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 11:53 
Offline
Benutzeravatar

Registriert: 08.03.2013 14:27
Wohnort: ERB
Öhm wenn du per ComMate mit Excel und Word bei jedem Durchlauf interaggierst, dann wundern mich die Zeite nicht wirklich. So ganz raff ich immernoch nicht, was du da genau zusammenbaust. Was ist genau der Ausgangspunkt? Wo willst du hin? Wie sieht genau dein bisheriger Weg aus?

Zur Zeit sieht es nach "Daten kommen aus Excel, werden irgendwie zu JSON, müssen irgendwie in Word und wird per ComMate gemacht." aus. Dazwischen sind aber aktuell zu viele Fragezeichen.

Wenn du nur Daten aus Excel in Word-Dokumente überführen willst, dann kannst du das in der Regel mit den beiden Programmen direkt. Egal ob über Datenquellen oder VBA. Ich weiß nicht, was man gerade als Rat mitgeben kann. Ich würde den Flaschenhals gerade bei ComMate vermuten.

_________________
USAC Protokoll
Universal Stringbased Application Communication Protocoll

Github: Zum Spezifikationdokument v0.01


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: json Daten - Struktur - Map-Zuordnung moeglich?
BeitragVerfasst: 19.05.2019 12:19 
Offline

Registriert: 21.07.2017 22:36
Ausgangspunkt ist der, dass Word-Formulare ausgefuellt werden sollen, deren Daten (zum Fuellen) aus Excel-Tabellen stammen u nd das gewuenschte Endprodukt sind wiederum .pdf Dateien (die aus Office 2010+ direkt gespeichert werden koennen).

Ja sicher, es gibt andere Moeglichkeiten, das zu tun, als per PureBasic / COMate. Serienbrief faellt aber aus, da die Excel-Tabellen vom Aufbau her fix sind und die eigentlichen Daten weder Spalten"-koepfe" besitzen, die als Ueberschriften herhalten koennen, noch die zu vearbeitenden Datei fortlaufend eingetragen sind. Das kann ich auch nicht aendern (Umformatierung ist nicht erwuenscht). VBA direkt unter Excel faellt aus, Makros sind in der Unternehmensinfrastruktur nicht erlaubt.

Man moechte unter einer einfachen Oberflaeche die Moeglichkeit eine Excel-Tabelle zu laden und zugehoerige Formulare (die Namen der zugehoerigen .docx Dateien entsprechen denen der Excel-Arbeitsblaetter) darueber ausgeben zu koennen.

Die Zuordnung per .json erlaubt es die Struktur der jeweiligen Excel-Arbeitsblaetter wiederzuspiegeln ohne das man fuer jedes
neue Formular das Hauptprogramm neu anfassen muesste.

Die Schritte die fuer das Ganze unternommen werden?
- Excel-Datei wird geladen
- Arbeitsblattnamen werden ausgelesen
- Zugehoerige .json Dateien werden geladen
- Drop-Down Felder zeigen an, fuer was Formulare erzeugt werden koennen
- Aufbauend darauf wird ein Formular geladen, ueber die Felder iteriert und
die noetigen Daten aus dem Excel-Arbeitsblatt geholt und eingetragen
- Abschliessend als .pdf gespeichert, Formular geloescht, rinse & repeat

Ja, COMate mag ein Flaschenhals sein, aber die Zeit um ein Word Formular mit 200 Elementen zu fuellen dauert im Moment weniger als 500ms und auch mit dem Loeschen aller Eintraege hinterher (das ist weniger zeitintensiv als das Formular ohne zu speichern zu schliessen und neu zu oeffnen) sind es keine 700 ms. Das ist von der Bearbeitungszeit vollkommen ok.

Ich haette nichts gegen eine schnellere Variante einzuwenden, ich kenne allerdings im Moment keine...


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye