Array leeren und Kommastellen erhalten [erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Array leeren und Kommastellen erhalten [erledigt]

Beitrag von Ewald »

Hallo liebe Gemeinde,
kann mir mal bitte jemand einen kleinen Anschub verpassen ?
Ich habe mir diese Funktion geschrieben, in die ich Arrays schieben kann, welche dort geleert werden sollen. Ursprünglich wird das Array mit den Feldern
eines Datensatzes gefüllt und enthält somit z.B. die Kommastellen einen N-Feldes.
Ganz einfach - dachte ich bis zum ersten Absturz ;-)
Es geht um den nummerischen Teil. Wenn ich das so mache, kann ich in der weiteren Verarbeitung keine Dezimalstellen in das Arrayelement eingeben.
Es gibt einen Absturz, sobald ich die Kommataste drücke.
Ich müsste also statt 0 den Wert 0.00 reinpacken. Oder auch 0.000 wenn vorher 3 Kommastellen im Array-Element standen.
Könnte in dieser Funktion ja alles passieren.
Also wäre es gut zu wissen, wie viele Kommastellen das übergeben Arrayelement hat. Oder gibt es dazu eine Funktion ?
Mir fällt im Moment dazu nichts mehr ein.
Hat jemand einen Tip für mich ?
Danke
Ewald

Code: Alles auswählen

function arrleer(xa,xlist)
for i = 1 to len(xa)
do case
   case valtype(xa[i]) = "C"
        xa[i] = space(len(xa[i]))
   case valtype(xa[i]) = "D"
        xa[i] = ctod("")
   case valtype(xa[i]) = "N"
        xa[i] = 0     // oder bei Bedarf  0.00
   case valtype(xa[i]) = "L"
        xa[i] = .f.
endcase
next
*dc_getrefresh(xlist)
return .t.
Zuletzt geändert von Ewald am Mi, 06. Aug 2014 15:49, insgesamt 1-mal geändert.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten

Beitrag von brandelh »

alle numerischen Typen mit 0 vorbelegen.
Wenn du nach STR() Kommas hast, aber numerisch brauchst schlägt VAL() fehl, dafür habe ich eine eigene Funktion:

Code: Alles auswählen

*-----------------------------------------------------------------------------
function HB_VAL(cNUM)
   local nWert, nAnzKomma, nAnzPunkt
   nAnzKomma  := CharCount(cNUM,",")
   nAnzPunkt  := CharCount(cNUM,".")
   do case
      case empty(nAnzKomma) .and. empty(nAnzPunkt)
           * nichts ändern
      case empty(nAnzKomma) .and. nAnzPunkt=1
           * nichts ändern
      case empty(nAnzPunkt) .and. nAnzKomma=1
           cNUM := strtran(cNUM,",",".")
      case nAnzKomma=1 .and. nAnzPunkt > 1
           cNUM := strtran(cNUM,".","")    // Tausender Trennpunkte entfernen
           cNUM := strtran(cNUM,",",".")   // Komma auf Punkt umsetzten
      case nAnzPunkt=1 .and. nAnzKomma > 1
           cNUM := strtran(cNUM,",","")    // Tausender TrennKOMMA entfernen
      case nAnzKomma=1 .and. nAnzPunkt = 1
           * was ist jetzt welches ?
           if at(".",cNUM) > at(",",cNUM)
              cNUM := strtran(cNUM,",","")    // Tausender TrennKOMMA entfernen
           else
              cNUM := strtran(cNUM,".","")    // Tausender Trennpunkte entfernen
              cNUM := strtran(cNUM,",",".")   // Komma auf Punkt umsetzten
           endif
   endcase

   nWert := VAL(cNUM)

return nWert
Gruß
Hubert
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2934
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten

Beitrag von Wolfgang Ciriack »

Wäre es nicht einfacher, statt des Funktionsaufrufs einen Leersatz zu erzeugen ? Dann würde statt der Funktion ein einfaches
ASize(xa,0) und AAdd(ax, aLeer) reichen.
Viele Grüße
Wolfgang
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten

Beitrag von Ewald »

Moin Wolfgang,
da hast du natürlich Recht. So mache ich das auch an 1000 Stellen in meinen Programmen.
Da springe ich an der Ende der DBF. Das funktioniert super mit der Struktur einer DBF.
Ich stelle aber nach und nach auf mysql um und dann ist damit Schluss. Da ist beispielsweise ein leeres Feld nicht N 10,2 sondern NIL. Das wäre dann auch das Arrayelement.
Wie auch immer, da muss ich mir die Arrays anders zusammendengeln. Und wenn ich die mal habe, will ich die über die neue Funktion für neue Eingabe leeren.

Code: Alles auswählen

asize(abest,0)
go lastrec()+1
for i = 1 to fcount()
aadd(abest,fieldget(i))
next
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten

Beitrag von brandelh »

Ewald hat geschrieben:Ich stelle aber nach und nach auf mysql um und dann ist damit Schluss. Da ist beispielsweise ein leeres Feld nicht N 10,2 sondern NIL.
das kommt darauf an, wie du die Felder definierst !
ICH nutze immer DEFAULT damit das Verhalten dem von DBF Dateien entspricht.
0 bei numerisch, " " bei String.
So ist immer etwas da. Ich hatte z.B. schon mal eine Abfrage ob in einem der Adresszeilen ein Text auftaucht.
Wenn eine der abgefragten Adressfelder auf NULL stand, wurde der Satz komplett ignoriert (ich weiß jetzt aber nicht wirklich ob das immer so ist).
Ewald hat geschrieben:Und wenn ich die mal habe, will ich die über die neue Funktion für neue Eingabe leeren.
Bei GUI oder bei @ GET Feldern ?
Bei GUI (ich habe da abgeleitete SLE für numerisch, Datum etc.) reicht ein oXbp:clear() und es passt.
Ewald hat geschrieben:MYSQL: Da ist beispielsweise ein leeres Feld nicht N 10,2
MySQL (oder SQL immer ?) zählt den Punkt nicht mit, 10,2 sind also 8 Vor- und 2 Nachkommastellen. Bei DBF wäre das also N 11,2.
Gruß
Hubert
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten

Beitrag von Ewald »

Moin Hubert,
stimmt, das mit der " " und 0 Default Belegung in SQL mache ich auch. Allerdings habe ich bei vorhandenen Datenbanken nicht immer den Einfluss darauf.

Dein Beispiel hat mich dann aber darauf gebracht den Dezimalpunkt zu suchen und diese Lösung zu dengeln. Funktioniert gut, erscheint mir aber reichlich umständlich.
Aber was soll's. Allein das Endergebnis zählt.

Gruß
Ewald

Code: Alles auswählen

function arrleer(xa,xlist)
local i,vlen:=0,vpos:=0,vanz:=0,vwert:=""
for i = 1 to len(xa)
do case
   case valtype(xa[i]) = "C"
        xa[i] = space(len(xa[i]))
   case valtype(xa[i]) = "D"
        xa[i] = ctod("")
   case valtype(xa[i]) = "N"
        vwert = alltrim(str(xa[i]))
        vlen  = len(vwert)
        vpos  = rat(".",vwert)
        vanz  = vlen-vpos
        xa[i] = val(str(0,11,vanz))
   case valtype(xa[i]) = "L"
        xa[i] = .f.
endcase
next
*dc_getrefresh(xlist)
return .t.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Array leeren und Kommastellen erhalten

Beitrag von AUGE_OHR »

Ewald hat geschrieben:Ich stelle aber nach und nach auf mysql um und dann ist damit Schluss. Da ist beispielsweise ein leeres Feld nicht N 10,2 sondern NIL.
wenn du die native Schnittstelle von Hector nimmst musst du dich schon selbst um die Type-Umwandlung kümmern.
deine Function arrleer(xa,xlist) versucht den "Inhalt" festzustellen

Code: Alles auswählen

   case valtype(xa[i]) = "N"
welches du auf Table Feld Type umstellen solltest.

was du mit "Kommastellen" meinst ist mir immer noch nicht klar ?

Code: Alles auswählen

xa[i] := xa[i] - INT(xa[i])
gruss by OHR
Jimmy
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von Ewald »

Moin Jimmy
Mein oben geschildertes Problem hat nichts mit SQL zu tun und mit Kommastellen meinte ich die Anzahl der Stellen hinter dem Dezimalpunkt.

Ein Bild sagt mehr als 1000 Worte.

Also hier ist ein kleines Beispielprogramm. Gelinkt stellt es mein ursprüngliches Problem viel besser dar als ich es je beschreiben könnte.

Code: Alles auswählen

proc main

aa:={}
aadd(aa,1)
aadd(aa,1.1)
aadd(aa,1.11)
aadd(aa,1.111)

? "Inhalt mit Anzahl Dezimalstellen"
for i = 1 to len(aa)
? aa[i]
next

arrleer(aa)

?
? "Problem: Inhalt 0 aber keine Info mehr über vorher vorhandenen Dezimalstellen"
for i = 1 to len(aa)
? aa[i]
next

asize(aa,0)
aadd(aa,1)
aadd(aa,1.1)
aadd(aa,1.11)
aadd(aa,1.111)

arrleer1(aa)
?
? "Das wollte ich erreichen. Inhalt ist 0 und die Dezimalstellen bleiben erhalten"
for i = 1 to len(aa)
? aa[i]
next

inkey(0)
return
* ---------------------------
function arrleer(xa)
for i = 1 to len(xa)
    xa[i] = 0
next
return .t.
*----------------------------
function arrleer1(xa)
for i = 1 to len(xa)
    vwert = alltrim(str(xa[i]))
    vlen  = len(vwert)
    vpos  = rat(".",vwert)
    vanz  = if(vpos=0,0,vlen-vpos)
    xa[i] = val(str(0,11,vanz))
next
return .t.
Zuletzt geändert von Ewald am Do, 07. Aug 2014 15:54, insgesamt 1-mal geändert.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von brandelh »

Numerische Werte haben beliebig viele Dezimalstellen nach dem Komma, das kann man nicht einschränken.
Was du wohl meinst ist die Darstellung mit Str() oder Transform(), bzw. dem @ SAY System.
Der numerische Wert im Array selbst, ist immer entweder LONG = KEINE Nachkommastellen, oder FLOAT = beliebig viele Nachkommastellen, wobei die Genauigkeit begrenzt ist.

Was genau willst du erreichen ?
GUI-Anzeige => meine numerischen SLE haben eine Format-Maske
Listen => STR() oder Transform()
?
Gruß
Hubert
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von Ewald »

Moin Herbert,
Was ich im Detail erreichen will bzw. erreicht habe ist dieses:
Am Anfang eines Programmes lese ich wie weiter oben beschrieben einen leeren Datensatz (DBF lastrec()+1) in das Array an.
Danach stehen mir die korrekt vorbelegten Arrayelemente für die Eingabe von Daten im Programm zur Verfügung. Irgendwann speichere ich das Array in die DBF zurück.
Um das Array für die nächste Eingabe zu nutzen müssen die Daten raus. Das kann ich wie bisher machen, indem ich mit ASIZE(aa,0) arbeite und wieder einen leeren Datensatz (das Array neu fülle) oder aber mit dem Versuch von arrleer().
Auf den Punkt gebracht entstand beim Versuch mit arrleer() aber dieses Problem. Nach dem Leeren in der Funktion stand im Arrayelement immer nur 0 und es ist im weiteren Verlauf des Programmes bei mir nicht möglich gewesen, Daten mit Dezimalstellen in dieses Element einzugeben. Der Rechner knallt ab sobald ich die Kommataste drücke. Frag mich warum, aber bei mir kann ich in einem mit 0 vorbelegten Arrayelement nur Zahlen ohne Dezimalstellen eingeben. Wenn ich Dezimalstellen eingeben will muss ich nicht 0 sondern 0.00 vorbelegen.
Noch zur Information. Ich arbeite mit Express und lese mit dcget ein und meine Xbase Version ist 1.90.331. Kann ja sein, das dieses Problem nur noch bei mir existiert.
Aber wie gesagt, es ist mit der Änderung In der Funktion erledigt.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von brandelh »

Das muss dann eine Eigenart von Express sein bzw. dessen Control sein.
Wie schon geschrieben ist es intern ein Unterschied ob man 0 oder 0.0 zuweißt:
a := 0 => LONG Variablen, sind in Schleifen schneller als FLOAT
a := 0.0 => FLOAT Variable.
a := 0.00 ist identisch zu a := 0.0
Normalerweise wird Xbase++ intern immer die richtige Umwandlung vornehmen, aber Express könnte da Unterschiede machen.

Ich hätte aber eher vermutet, dass es eine Formatmaske wie bei Transform() oder @ SAY GET erwartet.
Gruß
Hubert
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von Ewald »

@ Hubert,
hast du meinen Quellcode (Eintrag vom 10:03 Uhr) mal gelinkt ? Das ist ja reiner XBase Code.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von brandelh »

Ich finde nur einen von 9:30, und kann dir ohne zu linken sagen was dort geschieht:

aadd(aa,1) => intern LONG 1 == 1
aadd(aa,1.1) => FLOAT binärwert ähnlich 1.1
aadd(aa,1.11) => " 1.11
aadd(aa,1.111) => " 1.111

die interne Darstellung kannst du so nicht erfahren, das muss man wissen ;-)

? aa

das ist bei FLOAT nicht die interne Darstellung, sondern ein für die Anzeige gerundeter Wert. Ähnlich str(i,10) ...
Nur wenn man FELDER so anzeigt, erhält man den Inhalt des Feldes (das wird als Text gespeichert !)

... aber ich kann es ja mal ausprobieren ;-)
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von brandelh »

du meinst das:

Code: Alles auswählen

Das wollte ich erreichen. Inhalt ist 0 und die Dezimalstellen bleiben erhalten
         0
        0,0
       0,00
      0,000
mit einer kleinen Code-Änderung siehst du ...

Code: Alles auswählen

?
? "Der Inhalt des Arrays ist immer gleich 0.0 ;-) - die Anzeige allerdings seltsam"
for i = 1 to len(aa)
? aa[i],aa[i]=0.0
next
dass intern (da gibt ja auch keine ",") alles gleich 0.0 ist.

Code: Alles auswählen

Der Inhalt des Arrays ist immer gleich 0.0 ;-) - die Anzeige allerdings seltsam
         0 J
        0,0 J
       0,00 J
      0,000 J
Schon seltsam das Ganze ;-)
Gruß
Hubert
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Array leeren und Kommastellen erhalten [erledigt]

Beitrag von Ewald »

Und wie so oft gibt es mehrere Wahrheiten :?

Code: Alles auswählen

? "Das wollte ich erreichen. Inhalt ist 0 und die Dezimalstellen bleiben erhalten"
for i = 1 to len(aa)
? aa[i],aa[i]=0.0,aa[i]=0
next

Das wollte ich erreichen. Inhalt ist 0 und die Dezimalstellen bleiben erhalten 
         0 Y Y                                                                 
        0,0 Y Y                                                                
       0,00 Y Y                                                                
      0,000 Y Y                      
Antworten