Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: Beaker s.a. am Januar 05, 2016, 13:25:17

Titel: Str vs Replace
Beitrag von: Beaker s.a. am Januar 05, 2016, 13:25:17
Hallo Franz,
Da im anderen Thread doch eher OT hier.
ZitatReplace()-Funktion:  Warum einfach, wenn's auch kompliziert geht?   ;)  Wenn die Str-Funktion nicht geht, geht auch die Replace-Funktion nicht....
Da mir nicht bewusst war, dass Str Komma in Punkt umwandelt habe ich mir die OH zu Str angeschaut, und bin etwas verwirrt.
ZitatDas erforderliche Argument Zahl ist ein Wert vom Typ Long, der einen beliebigen numerischen Ausdruck enthält.
.
.
.
Die Str-Funktion erkennt nur den Punkt (.) als zulässiges Dezimalzeichen.
Nun ergaben meine Tests aber Folgendes:
?Str(10.33)
10.33
?Str(10,33)
Ergibt Fehlermeldung: Falsche Anzahl von Argumenten ...

Leuchtet ein.
?Str("10,33")
10.33

Widerspricht IMO o.a. Zitat bezügl. Datentyp des Arguments, liefert aber das richtige Ergebnis.
Übersehe ich da was?
btw. Str("10.33") ergibt 1033
gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: Josef P. am Januar 05, 2016, 14:04:16
Hallo!

Zitatein Wert vom Typ Long
Da ist vermutlich ein Fehler in der Hilfe. Long glaube ich nicht. Da sollte eher numerischer Ausdruck bzw. Double stehen.

zu str("10.33"):
Bei String-Übergabe wird vermutlich der Text zuvor zu eine Zahl konvertiert.
Prinzip: str(cdbl("10.33"))

mfg
Josef
Titel: Re: Str vs Replace
Beitrag von: DF6GL am Januar 05, 2016, 14:07:30
Hallo,


naja,  Programmieren nach MS-Hilfe ist so wie Autofahren mit Blick (nur) auf's  Navi..  ;)

Die Aussage bzgl. des Argumententyps (besonderer Blödsinn ist "Long") basiert vielleicht noch auf uraltem Code aus Basic-Zeiten und es wurde übersehen, das anzupassen. Ich nehme an, VBA6(7) konvertiert ein String-Argument erst in eine numerische Zahl (unter Berücksichtigung der Regionseinstellungen bzgl. Dezimal-Trennzeichen) und dann wieder zurück in einen (Ziffern-) String mit einem Dezimal-Punkt an passender Stelle.

Jedenfalls erfüllt Str() die korrekte Konvertierung einer internen numerischen Zahl in eine Ziffern-Folge (String) mit passenden Vorzeichen und Dezimal-PUNKT (US-Darstellung einer Dezimalzahl) , so wie es in SQL-Zuweisungen oder auch VBA-Recordset-Feldzuweisungen erforderlich ist.


Titel: Re: Str vs Replace
Beitrag von: MzKlMu am Januar 05, 2016, 14:09:11
Hallo,
mit VBA kannst Du das nicht prüfen, da in VBA es kein Komma als Dezimaltrenner gibt, das ist immer der Punkt. In einer Abfrage (oder in Formularen als berechnetes Feld) geht das. Siehe Bild.
Titel: Re: Str vs Replace
Beitrag von: Beaker s.a. am Januar 05, 2016, 14:41:52
Hallo,
@Josef
ZitatBei String-Übergabe wird vermutlich der Text zuvor zu eine Zahl konvertiert.
Prinzip: str(cdbl("10.33"))
Aber das wäre dann doch eine ZAHL im korrekten (amerikanischen) Format; - ?

@Klaus
Hast Du es ausprobiert? Wenn ich da bei Zahl 10.33 einsetze erhalte ich im Feld String auch 1033, - und nu?
gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: MzKlMu am Januar 05, 2016, 14:45:20
Hallo,
natürlich habe ich das ausprobiert. Kannst Du doch im Bild sehen.
Du darfst da auch nicht 10.33 übergeben, sondern 10,33.
Du willst doch das Komma weg haben, was soll es da für einen Sinn machen 10.33 zu übergeben. In einer deutschen Version ist 10.33 ja gar nicht möglich.
Und wenn Du es trotzdem eingibst wird auch bei der Zahl aus der 10.33 > 1033 weil das mit dem deutschen Punkt als Tausendertrennzeichen kollidiert und die Str Funktion macht daraus richtigerweise 1033.
Titel: Re: Str vs Replace
Beitrag von: Josef P. am Januar 05, 2016, 14:54:51
ZitatAber das wäre dann doch eine ZAHL im korrekten (amerikanischen) Format; - ?
Nein, das ist ein Text. ;)
Diesen konvertiert z. B. CDbl gemäß Lädereinstellung in eine Zahl. Ich nehme an, dass innerhalb Str das auch (bzw. durch implizite Konvertierung) passiert.

Str erwartet einen numerischen Datentyp. Wird statt diesem ein String übergeben, kommt es vermutlich zu einen programmierten oder impliziten Konvertierung.

Prinzip:
Dim x As Double
x = "10.33"
Debug.Print x, Str(x), CStr(x)
   
x = "10,33"
Debug.Print x, Str(x), CStr(x)


mfg
Josef
Titel: Re: Str vs Replace
Beitrag von: Beaker s.a. am Januar 05, 2016, 16:06:55
Hallo,
@Klaus
Zitatnatürlich habe ich das ausprobiert. Kannst Du doch im Bild sehen.
Ich seh da nur Kommas.
ZitatDu darfst da auch nicht 10.33 übergeben, sondern 10,33.
Es ging ursprünglich auch nicht darum was ich darf (oder ob ich das mache), sondern um das für mich seltsame Ergebnis beim Testen der Str-Funktion.
Zitatweil das mit dem deutschen Punkt als Tausendertrennzeichen kollidiert und die Str Funktion macht daraus richtigerweise 1033.
Kann ich akzeptieren, aber als Nichtmathematiker + - ITler nicht verstehen (Position des .)

@Josef
???
Erst schreibst Du es wird in eine Zahl konvertiert, und dann ist die Text?
Ich habe es so verstanden, dass zuerst "10.33" in eine Zahl gewandelt wird und dann erst CDbl und Str angewendet werden. Das würde doch bedeuten, dass der Ausdruck NACH der Konvertierung so aussehen würde: str(cdbl(10.33)). Und das, nur die 10.33 meine ich, ist doch eine Zahl mit amerik. Dezimalzeichen, oder nicht?
gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: MzKlMu am Januar 05, 2016, 16:40:39
Hallo,
ZitatIch seh da nur Kommas.
wo siehst Du da nur Kommas ?
Lade das Bild herunter und schaue es Dir vergrößert an. In der Spalte "string" steht ein Punkt. Vielleicht hilft ja auch eine Brille.  :P
Aber es ist eigentlich ganz einfach. 10.33 gibt es auf einer deutschen Oberfläche nicht als Zahl. Das ist schlichtweg ausgeschlossen. Daher taugt es auch nicht als Vergleich.

Im Anhang noch ein vergrößertes Bild
Titel: Re: Str vs Replace
Beitrag von: Beaker s.a. am Januar 05, 2016, 17:12:01
Hallo Klaus,
Zitatwo siehst Du da nur Kommas ?
In der Spalte "Zahl", da Argument von Str., um das es ja ursprünglich ging.
EOT
gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: MaggieMay am Januar 05, 2016, 17:22:06
Hi,

wie gesagt ist es eine Länderspezifikation und in deutschsprachigen (und anderen europäischen) Ländern ist der Dezimalpunkt ein Komma. Eine Zeichenkette die sich wie "10.31" darstellt ist demnach keine Zahl, sondern ein Text.
Titel: Re: Str vs Replace
Beitrag von: MzKlMu am Januar 05, 2016, 17:30:20
Hallo,
ZitatIn der Spalte "Zahl",
das ist ja auch der Ausgangswert (die eigentliche deutsche Kommazahl). Die Spalte Zahl ist als Double in der Tabelle angelegt, und da geht ohnehin nur das Komma als Dezimaltrenner.  Zu betrachten ist also nur die Spalte "string".

Übrigens, die Aussage ich sehe da nur Kommas (ohne Bezug auf eine Spalte) ist da reichlich verwirrend, denn es sind deutlich Kommas und Punkte zu sehen.
Titel: Re: Str vs Replace
Beitrag von: DF6GL am Januar 05, 2016, 17:33:11
Hallo,

ich glaube. die ganze Verwirrung kommt daher, dass nicht zwischen der internen Darstellung einer Zahl (die ja nicht "lesbar" ist) und der visuellen Darstellung (die für den User relevant ist) dieser Zahl unterschieden wird.
Zitat
wo siehst Du da nur Kommas ?

Genau ums "Sehen" geht es....

Eine für den User lesbare Zahl ist IMMER ein String (eine Folge von Ziffern/Zeichen), der  auf einer Oberfläche (Papier, Monitor) erscheint.

SQL (der SQL-Interpreter)  braucht ("sieht") eine Dezimalzahl in Darstellung mit Dezimal-Punkt, der Amerikanische User "sieht" gerne die gleiche Darstellung, und der deutsche Anwender mag am Liebsten das Komma als Dezimal-Zeichen.


Um nochmal auf die STR-Funktion zu kommen,  so liefert die einfach nur grundsätzlich die Dezimalpunkt-Darstellung einer Zahl, egal, ob bei deren Parameter eine (VBA-dargestellte, d. h. mit Punkt geschriebene) Dezimalzahl (und die ja auch nur als Text in den VBA-Editor geschrieben wird), ein Lateralstring (dann mit Berücksichtigung der Regionseinstellung)  oder eine Variable (dann sinnvollerweise von Datentyp Single/Double/Currency) angegeben wird. Voraussetzung in allen Fällen ist natürlich, dass eine "gültige" Zahl dahintersteckt.
Titel: Re: Str vs Replace
Beitrag von: ebs17 am Januar 05, 2016, 17:41:52
Zitat...  und dann ist die Text?
Genau, denn eine SQL-Anweisung, die ja am Ende entsteht (oder Teile davon), ist ja nichts anderes als ein Text (Zeichenkette).

Eine Dezimalzahl (incl. Double, Single, Currency), die von außen kommt (aus Variable, Formularfeld, Arrayfeld) muss SQL-lesbar gewandelt werden. Dabei ist an der Stelle das Dezimaltrennzeichen schon der Punkt, siehe Hilfe:
ZitatDie Str-Funktion erkennt nur den Punkt (.) als zulässiges Dezimalzeichen.

Replace ist nicht wirklich ein Ersatz für Str, weil es eine dicke fette Funktion ist: Replace wurde mit VB6 (Acc2000) eingeführt. Hier (http://is.gd/fZcoGR) wird gezeigt, wie man mit vielen Anweisungen mit herkömmlichen VB5-Befehlen eine deutlich schnellere Ersatzfunktion basteln kann im Vergleich zur originalen MS-Variante.
Sowie: Mit Textverarbeitung (Links, rechts, ersetzen) auf Zahlen loszugehen ist zwar oft möglich, hat aber mit aufwandsarmen Rechnen recht wenig zu tun und sind schon stilistisch unschön.
Auch zu heutiger Zeit basiert das ganze Computerunwesen auf 1 und 0, also Zahlen, und da sind im Sinne der Effizienz Zahlenrechnungen immer einer Textverarbeitung vorzuziehen.
Titel: Re: Str vs Replace
Beitrag von: MzKlMu am Januar 05, 2016, 19:10:27
Hallo,
irgendwie ist das alles recht eigenartig.

Zitat von: Access VBA HilfeDie Str-Funktion erkennt nur den Punkt (.) als zulässiges Dezimalzeichen. Wenn die Möglichkeit zur Verwendung eines anderen Dezimalzeichens bestehen muß (zum Beispiel in internationalen Anwendungen), sollten Sie Zahlen mit der CStr-Funktion in eine Zeichenfolge umwandeln.

Dann aus dem Direktbereich:

?str(12.12)
12.12

?cstr(12.12)
12,12

?str(12,12)
Fehler

?cstr(12,12)
Fehler

Ich kann mir da auch keinen Reim darauf machen.
Titel: Re: Str vs Replace
Beitrag von: MaggieMay am Januar 05, 2016, 19:51:45
Hi,

die Fehler sind dadurch erklärbar, dass das Komma beim Funktionsaufruf als Parameter-Trenner gilt, die Str-Funktion aber nur einen Parameter erwartet und nicht zwei.

Ansonsten bringt es nicht allzuviel, sämtliche Varianten durchzuprobieren, wenn es (wie im auslösenden Fall) darum geht, einen gültigen SQL-String zu erzeugen. Wie Klaus schon sagte, es kommt nicht darauf an was man sieht...
Ich hatte diese Tests bereits vor etlichen Jahren schon mal gemacht (und auch irgendwo/-wie dokumentiert) und mein Fazit dabei war, dass die Str-Funktion zu favorisieren ist. Wenn ich morgen noch etwas dazu finde, lasse ich es euch gerne wissen.
Titel: Re: Str vs Replace
Beitrag von: Beaker s.a. am Januar 05, 2016, 21:18:05
Hallo,

@Klaus (#11)
Zitatdas ist ja auch der Ausgangswert
Genau, darum ging es ja von Anfang an, weshalb ich auch nur diese Spalte betrachtet habe.

@Franz
Zitatich glaube. die ganze Verwirrung kommt daher, dass nicht zwischen der internen Darstellung einer Zahl (die ja nicht "lesbar" ist) und der visuellen Darstellung (die für den User relevant ist) dieser Zahl unterschieden wird.
Ja, im Prinzip schon klar, aber wie wird den intern dargestellt? Entsprechend den Regionaleinstellungen (intern = sichtbar), oder immer mit Punkt.
Ich vermute dann eher Ersteres. Bei Letzterem würde dann ja die Umwandlung für SQL mit Str gar nicht nötig sein.

@Eberhard (#13)
ZitatGenau, denn eine SQL-Anweisung, die ja am Ende entsteht (oder Teile davon), ist ja nichts anderes als ein Text (Zeichenkette).
Das ist mir wohl bewusst; – es wird eine ZAHL generiert (SQL-konform), die als TEXT an SQL übergeben wird.
ZitatEine Dezimalzahl (incl. Double, Single, Currency), die von außen kommt (aus Variable, Formularfeld, Arrayfeld) muss SQL-lesbar gewandelt werden
Ja, aber was kommt denn da von aussen? Entsprechend Regionaleinstellungen (Komma)?
ZitatReplace ist nicht wirklich ein Ersatz für Str
Entsprang meiner Unwissenheit (siehe OP). Und weil ich das bei mir nun ändern wollte habe ich mir die Str-Funktion noch Mal angesehen. Und dabei bin ich eben auf meine Eingangsfrage gestossen.

@MaggieMay
Zitatdie Fehler sind dadurch erklärbar, dass das Komma beim Funktionsaufruf als Parameter-Trenner gilt, die Str-Funktion aber nur einen Parameter erwartet und nicht zwei.
Hatte ich schon im OP erwähnt.

gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: DF6GL am Januar 05, 2016, 22:03:16
Hallo,

ich befürchte, da ist Vieles noch nicht klar:

Was wir brauchen im SQL-STRING, um dem SQL-Interpreter eine DEZIMAL-ZAHL anzubieten, die er als solche verarbeiten kann:

Eine Zeichenfolge, die aus dem Vorzeichen ("+" oder "-")  , den eigentlichen Ziffern (nicht ZAHLEN) , dem Dezimal-PUNKT (weil amerikanisches Format erforderlich ist) und den restlichen Ziffern.

Je nachdem, woher eine solche Zahl nun stammt (manuell im VBA-Editor eingeben --> 123.12 oder über einen Variableninhalt ---> dblMeineDblZahl , bzw. einem Textfeldinhalt-->  Me!Textfeld1), muss dies in den o. g. erforderlichen STRING umgewandelt werden, und zwar ohne Berücksichtigung der Regionaleinstellungen.

Weil STR() nun mehrere "Zahlen"-Darstellungen als Argument akzeptiert (wie bekannt) , liefert die Funktion nun einen String zurück, der die "Zahl" im Argument im amerikanischen Format (also mit Dezimal-PUNKT) darstellt und beim Zusammenbau des SQL-Strings geeignet ist.

Wird eine Variable vom Datentyp Double direkt (also ohne Wandlung mit einer Funktion) mit "&" in einen (SQL-) String eingebaut, so greift hier die interne Konvertierung ( CStr() )  in einen String, aber mit Berücksichtigung der Region-Einstellungen, was eben bei "deutsch" das Komma und nicht den Punkt ergibt und damit bei SQL einen Fehler verursacht.

Dim dblVar1 as Double, strSQL as String
dblVar1 = 12345.12   ' VBA spricht amerikanisch, deshalb würde hier ein Komma falsch interpretiert

STRSQL = "Select * from Tabelle1 where DBLZAHL = " & dblVar1 & " order by ID"
--->  Select * from Tabelle1 where DBLZAHL = 12345,12 order by ID"

STRSQL = "Select * from Tabelle1 where DBLZAHL = " & CStr(dblVar1) & " order by ID"
--->  Select * from Tabelle1 where DBLZAHL = 12345,12 order by ID"

stellt man hier in den Regionseinstellungen das Dezimaltrennzeichen auf den Punkt ein (und ändert auch das Tausender-Trennzeichen), so würde auch CStr() (und auch das erste Beispiel) das richtige Resultat liefern:

STRSQL = "Select * from Tabelle1 where DBLZAHL = " & CStr(dblVar1) & " order by ID"
--->  Select * from Tabelle1 where DBLZAHL = 12345.12 order by ID"


Wie wir nun zu dem SQL-geeigneten Ziffern-String kommen, ist erst mal egal.  Es bietet sich halt die STR()-Funktion an, weil sie immer das richtige Ergebnis liefert.




ZitatEntsprechend den Regionaleinstellungen (intern = sichtbar), oder immer mit Punkt.

Was hat das mit intern/sichtbar zu tun?

In den Regionaleinstellungen wird festgelegt, wie das Dezimal-Trennzeichen am entspr. Rechner auszusehen hat, wenn man eine Dezimal-Zahl (intern dargestellt bei Double als Gleitkommazahl (Basis, Mantisse, Exponent, oder bei Währung als Festkommazahl) anzeigt oder in einen String umwandelt.

ZitatJa, aber was kommt denn da von aussen? Entsprechend Regionaleinstellungen (Komma)?

Es kommt von Dir (manuelle Eingabe in z. B. Form-Textfelder),  aus deinen Tabellen (entsprechend Datentyp) und ausgelesen mittels Recordset z. B. oder auch Dlookup, oder sonstigen Ergebnissen von Funktionen oder Ausdrücken...

Was auch schon erwähnt wurde:

Die "Hilfeleistung" des VBA-Interpreters (die automatischen internen Typkonvertierungen) bringen manchmal mehr Verwirrung/Unverständnis der Gesamtlage als sie nützen... :'(


Als letzte Anmerkung:

Ich lasse mich jetzt intern in eine 2-m-Horizontallage konvertieren.  :) ;) :D ;D
Titel: Re: Str vs Replace
Beitrag von: ebs17 am Januar 05, 2016, 22:29:27
ZitatJa, aber was kommt denn da von aussen?
sSQL = "SELECT * FROM TabX WHERE FieldA = 2.34"

sSQL = "SELECT * FROM TabX WHERE FieldA = FieldB"

sSQL = "SELECT * FROM TabX WHERE FieldA = Time()"

Hier liegt ein Double-Wert innen im SQL-String vor, er wird über eine Konstante, ein Tabellenfeld oder über eine Funktion (die bei Jet-SQL über den Expression Service direkt auswertbar ist) übergeben. Hier ist keine explizite SQL-Formatierung notwendig, wie z.B. auch nicht bei Date-Werten.

sSQL = "SELECT * FROM TabX WHERE FieldA = " & Str(dblVariable)
dblVariable ist ein Wert von außen und kann nicht von der Datenbankmaschine ausgewertet werden. Daher wird der Wert über die Stringzusammensetzung ausgewertet und dann erst an die SQL-Anweisung übergeben. Dazu ist dann eine SQL-konforme Formatierung notwendig. Auch hier hat man das gleiche Verhalten wie bei Date-Werten.
Titel: Re: Str vs Replace
Beitrag von: Beaker s.a. am Januar 06, 2016, 13:01:17
Hallo Franz, hallo Eberhard,
Vielen Dank für Eure ausführlichen Erläuterungen zu so später Stunde.
Bezügl. SQL ist mir das alles klar, es geht aber doch nur um die Ergebnisse, die Str auswirft.
Ich habe so das Gefühl, dass ihr euch nicht auf mein Niveau runterdenken könnt ;-).
ZitatWird eine Variable vom Datentyp Double direkt (also ohne Wandlung mit einer Funktion) mit "&" in einen (SQL-) String eingebaut, so greift hier die interne Konvertierung ( CStr() )  in einen String, aber mit Berücksichtigung der Region-Einstellungen, was eben bei "deutsch" das Komma und nicht den Punkt ergibt und damit bei SQL einen Fehler verursacht.
Das heisst doch, dass eine Variable den Punkt ja schon enthält (wegen Double). Dieser wird dann VBA-intern in ein Komma umgewandelt (wegen Regionaleinst.), dass ich dann wieder in einen Punkt umwandeln muss (wegen SQL). Dies habe ich vermutet, und kann ich auch verstehen.
Aber:
ZitatWeil STR() nun mehrere "Zahlen"-Darstellungen als Argument akzeptiert (wie bekannt) , liefert die Funktion nun einen String zurück, der die "Zahl" im Argument im amerikanischen Format (also mit Dezimal-PUNKT) darstellt und beim Zusammenbau des SQL-Strings geeignet ist.
Ausser der Darstellung als Zahl mit Punkt (amerikanisch) als String ("10.33").

Lasst es uns jetzt aber gut sein. War ein netter Exkurs, aber zurück zu Wichtigerem. Ich werde jetzt Mal meine Replaces durch Str ersetzen, dann werde ich ja sehen.
gruss ekkehard
Titel: Re: Str vs Replace
Beitrag von: DF6GL am Januar 06, 2016, 13:42:21
Hallo,


noch ein Kommentar zu   "Das heisst doch, dass eine Variable den Punkt ja schon enthält (wegen Double)."

Eine solche Variable enthält nie einen "Punkt" (das ist ja ein Text-Zeichen) , sie enthält eine ZAHL (bei Double intern dargestellt durch eine Bitkombination, die sich aus Basis, Mantisse und Exponent des Zahlenwertes ergibt.)

Der Punkt wird erst dann "hinzugefügt", wenn der Variablen-Inhalt visuell ANGEZEIGT (auf dem Monitor oder Drucker) oder aber durch irgendeine Maßnahme (interne Konvertierung oder durch eine Konvertierungs-Funktion) in einen String umgewandelt wird. D. h. es können nur Strings(!) angezeigt (visuell dargestellt) werden (auch dann, wenn die Schreibmarke z. B. im VBA-Editor über einer Double-Variablen steht)..


ZitatAusser der Darstellung als Zahl mit Punkt (amerikanisch) als String ("10.33")

Das ist auch nicht ganz richtig. Dieser Punkt im String wird in deutscher Umgebung (entspr. den Regionseinstellungen) als Tausender-Trennzeichen interpretiert und somit für eine Umwandlung nach Double schlichtweg ignoriert, so dass sich hier ein Wert von 1033 ergibt.


zufälliger Link:
http://de.ccm.net/contents/496-darstellung-von-ganzen-und-reellen-zahlen#darstellung-einer-naturlichen-zahl