0

Unerklärliches, willkürliches Verhalten beim automatisierten Erzeugen von Datensätzen unter macOS/iOS/android

Hallo an alle Ninox-Nutzer, 
seit ein paar Tagen beschäftige ich mich mit Ninox und bin bis dato sehr zufrieden. Als langjähriger Filemaker-User war ich auf der Suche nach einer Alternative und ich glaube, dass ich bei Ninox fündig geworden bin. 

Aber nun zu meinem Problem, meinen Fragen an das Forum, an Euch - in der Hoffnung, mir kann jemand helfen. Ich bin auf ein nicht nachvollziehbares Problem gestoßen, welches mir die Stunden raubt und auf das ich weder hier im Forum noch im Netz eine Antwort/Erklärung gefunden habe.

Folgender Sachverhalt:

Meine kleine Test-Datenbank enthält zwei Tabellen - in der 1. Tabelle (Textfilter) sollen umfangreiche Texte abgelegt werden, welche per Script soweit zerlegt werden, dass zum jeweiligen Text die "exakte" Wortanzahl inkl. Zeichenanzahl gespeichert werden - mehr erstmal nicht. 

Via Button/Script wird der aufbereitete/bereinigte Text, welcher ausschließlich aus Worten mit Trennzeichen(#) besteht, in eine weitere, zweite Tabelle (Worte) übertragen - Wort für Wort. 
Jedes Wort welches noch nicht in der Tabelle "Worte" vorhanden ist wird als neuer Datensatz angelegt und (vorerst) nur gezählt (Häufigkeit). Ist ein Wort bereits in der Tabelle "Worte" vorhanden, wird nur der Zählwert um jeweils 1 erhöht. Technisch funktioniert soweit alles fix und reibungslos. 

Hier meine Kopfnuss: 

Ein Datensatz in der 1. Tabelle "Textfilter" hat einen Text mit 13739 Zeichen und 2146 Worten. 
Per Script werden nun die Worte des Textes einzeln Wort für Wort in die (wie oben beschrieben) zweite Tabelle "Worte" abgelegt und gezählt. Die DB/Tabellen ist/sind laufen lokal auf drei Systemen (macOS / iOS / Android) und sind absolut identisch.

Auf dem Mac (High Sierra) hat die zweite Tabelle "Worte" nach dem Ausführen des Scripts konstant 969 Einträge (Worte) und in der Summe (Zählungen) ergeben sich 2146 Worte - das passt! Aber eben nur (und vorerst) auf dem Mac!

Unter Android werden mal 166 Einträge, mal 170 Einträge, dann 176 Einträge, 174 Einträge ... usw. in der Tabelle "Worte" erfasst - überwiegend unterschiedlich und in der Summe nie korrekt.

Unter iOS werden mal 586 Einträge, mal 589 Einträge, dann 594 Einträge, 592 Einträge ... usw. in der Tabelle "Worte" erfasst - überwiegend unterschiedlich und in der Summe nie korrekt.

Es kommt aber noch besser:

Ein Datensatz in der 1. Tabelle "Textfilter" hat nun einen Text mit 32447 Zeichen und 5066 Worte. 
Per Script werden nun auch hier die Worte einzeln Wort für Wort in die (wie oben beschrieben) zweite Tabelle "Worte" gespeichert und gezählt. Auch hier: lokal auf drei Systemen (macOS / iOS / Android) und absolut identisch.

Auf dem Mac (High Sierra) hat die Untertabelle 1117 Einträge (Worte), mal 1108 Einträge, dann 1114, dann 1110, dann 1119, dann 1115 .... es passt nicht - weder von den Datensätzen und schon garnicht in der Summe der Anzahl (Zählung).

Unter Android werden mal 142 Einträge, mal 145 Einträge, dann 163 Einträge, 154 Einträge ... usw. in der Tabelle "Worte" erfasst - überwiegend unterschiedlich und in der Summe nie korrekt.

Unter iOS werden mal 449 Einträge, mal 589 Einträge, dann 450 Einträge, 447 Einträge ... usw. in der Tabelle "Worte" erfasst - überwiegend unterschiedlich und in der Summe nie korrekt.

?????

Wenn ein Text in der Tabelle "Textfilter" klein/kurz ist (bsp. 606 Zeichen und nur 91 Worte) werden auf allen Geräten/Systemen die Worte in der zweiten Tabelle "Worte" korrekt erfasst und gezählt ... die Summe stimmt.

Wird die Wortanzahl jedoch größer - schreibt Ninox die Daten nicht mehr korrekt in die zweite Tabelle "Worte" - und werden die Texte noch umfangreicher (siehe oben 5066 Worte) - stimmt nichts mehr. Auf keinem System (macOS/iOS/android).

Wo liegt mein Denk- und Code-Fehler (siehe unten)? 
Ich finde keine logische Erklärung für dieses willkürliche Verhalten. Man könnte meinen, dass sich Ninox beim Prüfen/Schreiben/Anlegen verschluckt... nicht hinterherkommt und abbricht.

Ein closeRecord() brachte keine Abhilfe - eine "künstlich" erzeugte Pause (For-Schleife) vor dem  nächsten Schreiben eines Wortes/Datensatzes in die Tabelle "Worte" ebenfalls nicht. 

Kann mir jemand einen Tipp geben, was ich übersehen habe, wo mein Fehler liegt? 
Vor Allem aber: Warum Ninox auf drei unterschiedlichen Geräten/Systemen so unterschiedlich reagiert?

 

################################################
Hier der Code zur Bereinigung des Textes:
################################################
"/*** Textfilter v02.07***/";
"/***/";
if Text != null then
  txtf := null;
  let sz := "–@”#€_&-+()/*':;!?~`|•√π÷׶∆£¥$/¢^°={}\%©®™✓[]><,.½⅓¼⅛²⅔⅜³¾⁴⅝⅞∅ⁿ¡№₱$¢£¥—–·±[<{]>}★†‡”„»«’‚›‹¡¿‽~`|♪♣♠♥♦√ΩΠμ÷ק¢←↑↓→′″∞≠≈()\‰℅©‘\“®™✓[]0123456789…";
  let bs := "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉÈËÊĖŪÙÛÚŌØÕŒÓÒÔÆÃÅĀÂÀÁŠẞŚÑŃabcdefghijklmnopqrstuvwxyzäöüßėêéèëūùûúōøõœóòôæãåāâàášśñń";
  let sanz := length(sz);
  let banz := length(bs);
  let xtxt := trim(OriginalText);
  "/***/";
  "/*** entferne Zeilenumbruch ***/";
  "/***/";
  for i from 0 to 10 do
    xtxt := replace(trim(xtxt), "
", " ")
  end;
  "/***/";
  "/*** entferne Sonder/Satzzeichen ***/";
  "/***/";
  for i from 0 to sanz do
    xtxt := replace(xtxt, substr(sz, i, 1), " ")
  end;
  "/***/";
  "/*** entferne einzelne Buchstaben ***/";
  "/***/";
  for i from 0 to banz do
    xtxt := replace(xtxt, " " + substr(bs, i, 1) + " ", " ")
  end;
  "/***/";
  "/*** entferne Zeilenumbruch ***/";
  "/***/";
  for i from 0 to 10 do
    xtxt := replace(trim(xtxt), "
", " ")
  end;
  "/***/";
  "/*** entferne doppelte Leerzeichen ***/";
  "/***/";
  while index(xtxt, "  ") != -1 do 
    xtxt := replace(xtxt, "  ", " ")
  end
  ;
  "/***/";
  "/*** zähle Leerzeichen (Worte) ***/";
  "/***/";
  let ztxt := replace(trim(xtxt), " ", "#");
  let ytxt := ztxt;
  let z := 0;
  while index(trim(ztxt), "#") != -1 do 
    z := z + 1;
    ztxt := substr(trim(ztxt), index(trim(ztxt), "#") + 1)
  end
  ;
  "/***/";
  "/*** Auswertung ***/";
  "/***/";
  TextBehandelt := trim(ytxt);
  'Anzahl Zeichen' := length(trim(OriginalText));
  'Anzahl Worte' := z + 1
end

###################################################
Hier der Code zum Schreiben in die Tabelle "Worte":
###################################################
let ztxt := replace(trim(TextBehandelt), " ", "#");
let ztxt := trim(ztxt) + "#";
"/***/";
"/*** schreibe die Worte in zweite Tabelle ***/";
"/***/";
while index(ztxt, "#") != -1 do 
  "/***/";
  "/*** hole aktuelles Wort ***/";
  "/***/";
  let xx := substr(trim(ztxt), 0, index(trim(ztxt), "#"));
  ztxt := substr(trim(ztxt), index(trim(ztxt), "#") + 1);
  "/***/";
  "/*** nachsehen ob Wort/DS bereits vorhanden ist ***/";
  "/***/";
  if cnt((select Worte)[Wort = trim(xx)]) = 0 then
    "/***/";
    "/*** NEIN - lege neuen DS mit akt. Wort an ***/";
    "/***/";
    let newWort := (create Worte);
    newWort.(Wort := trim(xx));
    newWort.(Anzahl := 1)
  else
    "/***/";
    "/*** JA - aktualisiere Zähler im DS ***/";
    "/***/";
    let newWort := (select Worte)[Wort = trim(xx)];
    newWort.(Anzahl := number(newWort.Anzahl) + 1)
  end
end

###################################################

Vorab vielen Dank und Grüße!
Mike

2 Antworten

null
    • Leonid_Semik
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo Mike,

    ich würde es versuchen hier mit regex zu arbeiten umd den Text zu bereinigen und man kann dann die einzenen Worte über einen Array zählen. Etwa so:

    ---

    "
    /deklarieren alle Wortzeichen/
    ";
    let myB := "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉÈËÊĖŪÙÛÚŌØÕŒÓÒÔÆÃÅĀÂÀÁŠẞŚÑŃabcdefghijklmnopqrstuvwxyzäöüßėêéèëūùûúōøõœóòôæãåāâàášśñń";
    "
    /ersetzen alle whitespaces (auch doppelten) durch Leerzeichen/
    ";
    'Text Bereinigt' := replacex(Originaltext, "\s+", " ");
    "
    /Entferne alle nicht Wortzeichen, außer leerzeichen/
    ";
    'Text Bereinigt' := replacex('Text Bereinigt', "[^" + myB + "^ ]", "");
    "
    /entferne einzelnen Buchstaben/
    ";
    'Text Bereinigt' := replacex('Text Bereinigt', " [" + myB + "] ", " ");
    "
    /trimmen/
    ";
    'Text Bereinigt' := trim('Text Bereinigt');
    "
    /erstellen einen Array aus Einzelnen Wörter/
    ";
    let myArr := split('Text Bereinigt', " ");
    'Anzahl Zeichen' := length(trim(Originaltext));
    'Anzahl Worte' := cnt(myArr);
    "
    /Schreiben in die Tabelle Worte, die Tabelle ist mit der Tabelle Textfilter verknüpft/
    ";
    let my := this;
    for i in myArr do
    if cnt(select Worte where Wort = i) = 0 then
    (create Worte).(
    Wort := i;
    Anzahl := 1;
    Textfilter := my
    )
    else
    first(select Worte where Wort = i).(Anzahl := Anzahl + 1)
    end
    end

    ---

    • Mike
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo Leonid,

    herzlichen Dank! Schöner, schlanker Code und funktioniert super. Werde mir die regulären Ausdrücke mal genau anschauen.

    VG Mike

Content aside

  • vor 4 JahrenZuletzt aktiv
  • 2Antworten
  • 1268Ansichten