Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: hanskuhn am Februar 08, 2012, 14:22:47

Titel: Eval-Funktion
Beitrag von: hanskuhn am Februar 08, 2012, 14:22:47
Hallo zusammen,

ich lasse mir von VBA verschiedene Werte via Eval(strX) errechnen. Nur an einer Stelle hakt er und ich kann mir nicht erklären, wieso...

Folgenden strX errechnet er einwandfrei:
Eval("133662"-("10143"+"8430"+"19416"+"22344"+"1341"+"6"+"33152"+"9010,8"+"23232"))

Folgendes leider nicht:
Eval("336224"-("14027,3"+"10601"+"94811"+"22506"+"20767"+"6328"+"43744"+"34235,2"+"57654,8"))

Erhalte RTE 13: Typen unverträglich!

Weiss wer warum?

Gruß,
Hans
Titel: Re: Eval-Funktion
Beitrag von: daolix am Februar 08, 2012, 15:44:25
ZitatFolgenden strX errechnet er einwandfrei:
Eval("133662"-("10143"+"8430"+"19416"+"22344"+"1341"+"6"+"33152"+"9010,8"+"23232"))

Folgendes leider nicht:
Eval("336224"-("14027,3"+"10601"+"94811"+"22506"+"20767"+"6328"+"43744"+"34235,2"+"57654,8"))

Bei mir geht weder das eine noch das andere.

Aber so funktioniert es:
Eval("336224-(14027.3+10601+94811+22506+20767+6328+43744+34235.2+57654.8)")
oder
Eval("133662-(10143+8430+19416+22344+1341+6+33152+9010.8+23232)")

Punkt statt Komma und die Formel komplett als String
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 10, 2012, 11:04:54
Moin daolix,

danke erst mal für deinen Hinweis. Also die Kommata durch Punkte ersetzen ist logisch. Aber wenn ich die Anführungszeichen wie bei einem normalen String setze und nicht um jede Zahl, dann rechnet er es nicht.

Ich habe jetzt nochmal Leerzeichen rausgelöscht, die ich vorher in dem String übersehen hatte und nun funktioniert es mit meinem ursprünglichen Beispiel. Ich habe aber das dumpfe Gefühl, dass meine Lösung nicht wirklich die optimale ist...
Titel: Re: Eval-Funktion
Beitrag von: DF6GL am Februar 10, 2012, 11:08:44
Hallo,


kurze Nachfrage:

"ich lasse mir von VBA verschiedene Werte via Eval(strX) errechnen"

warum?



Ansonsten ist eine mathematische (numerische) Berechnung mit Lateralstrings eher ein gewagtes Vergnügen.

Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 10, 2012, 11:35:35
Hallo DF6GL,

ich habe leider keine Lösung gefunden, um das Ganze mit einer Abfrage zu berechnen.

Ich habe eine Tabelle mit Werten, die miteinander verrechnet werden können:

ID|Wert|Kürzel|Verrechnungregel
1|1234|A|A
2|2345|B|A+B
3|543|C|(A+B)-C
etc...

Ich lese also in einer Schleife die Verrechnungsregel für jeden Datensatz ein und in einer Unterschleife ersetze ich die Kürzel der Verrechnungsregel mit den jeweiligen Werten der Datensätze. Das alles schreibe ich dann in meinen strX und lasse es zum Schluss errechnen. Kann man das eleganter lösen?

Beste Grüße,
Hans
Titel: Re: Eval-Funktion
Beitrag von: DF6GL am Februar 10, 2012, 11:46:45
Hallo,

naja, etwas klarer, weiterhin nicht verständlich:


Sind die "Kürzel" identisch mit den Variablennamen in der Verrechnungsregel?

Soll also bei ID=3   ID1Wert + ID2Wert -ID3Wert   (---> (1234+ 2345) -543)  )   gerechnet werden?

Wenn so, gibt es dann für "Kürzel" keine mehrfachen Einträge?

So wie ich das sehe, soll das eine Summierung über das Feld Wert in der ganzen Tabelle ergeben, wobei der Wert 543 als negativ angenommen wird...


Titel: Re: Eval-Funktion
Beitrag von: daolix am Februar 10, 2012, 11:56:55
Ich hab eval nie benutzt, daher weis ich nicht was du da berechnen willst, oder mein rechner spinnt:


s = "(12.3 + (4.7 - 8)) * 4 "
   Debug.Print Eval(s)
   Debug.Print Eval(("12.3" + ("4.7" - "8")) * "4")

ergibt bei mir 2 verschiedene Ergebnisse.

wenn ich deine schreibweise stück für stück zusammensetzte komme ich in zahlenbereiche bei der mein Rechner aussteigt.

edit:
so wie ich das jetzt verstehe werden bei deiner Schreibweise die werte in Klammern als Zahl zusammengesetzt.
die Operatoren sollten daher Bestandteil deines stringes sein.
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 10, 2012, 12:01:14
ZitatSind die "Kürzel" identisch mit den Variablennamen in der Verrechnungsregel?
Soll also bei ID=3   ID1Wert + ID2Wert -ID3Wert   (---> (1234+ 2345) -543)  )   gerechnet werden?

Ja, genau!

Für Kürzel gibt es nur eindeutige Einträge, also nicht bei einem Datensatz A und beim nächsten AB!

ZitatSo wie ich das sehe, soll das eine Summierung über das Feld Wert in der ganzen Tabelle ergeben, wobei der Wert 543 als negativ angenommen wird...

In diesem Beispiel ist das so. Die Verrechnungsregel kann aber vom Nutzer angegeben werden, könnte also auch z.B. 2*A-B+C sein...
Titel: Re: Eval-Funktion
Beitrag von: DF6GL am Februar 10, 2012, 12:01:28
Hallo,

bei einer solchen Rechnung:


("12.3" + ("4.7" - "8")) * "4"


würde ich auch spinnen, zumindest in's Grübeln kommen...   ;D ;D ;D


PS: @HansKuhn


ok, aber warum steht dann bei JEDEM Datensatz eine extra Regel?.  Den Zusammenhang versteh ich noch nicht. M. E gehören die Rechnenregeln in eine extra Tabelle, aus den man eine bestimmte Regel auswählt und dann auf die Werte in der Werte-Tabelle anwendet.


Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 10, 2012, 12:03:52
Zitatwürde ich auch spinnen, zumindest in's Grübeln kommen...

Naja, dass das nicht so optimal ist, steht ja nun fest....

Zitats = "(12.3 + (4.7 - 8)) * 4 "


-> Wenn s = string, dann rechnet (eval(s)) er das bei mir nicht
Titel: Re: Eval-Funktion
Beitrag von: daolix am Februar 10, 2012, 12:18:41
Zitat von: DF6GL am Februar 10, 2012, 12:01:28
Hallo,
bei einer solchen Rechnung:
("12.3" + ("4.7" - "8")) * "4"
würde ich auch spinnen, zumindest in's Grübeln kommen...   ;D ;D ;D
ja, war aber oben so ähnlich angegeben.

Zitat von: hanskuhn
-> Wenn s = string, dann rechnet (eval(s)) er das bei mir nicht
ja s ist ein string.
hmm meine access version ist mit deiner nicht kompertibel.

Titel: Re: Eval-Funktion
Beitrag von: DF6GL am Februar 10, 2012, 12:25:08
HAllo,

also, ich weiß nicht, was ihr da genau macht...


Bei mir kommt hier überall das gleiche Ergebnis (36)  heraus

Dim s As String
s = "(12.3 + (4.7 - 8 )) * 4 "
   Debug.Print Eval(s)
   Debug.Print Eval(("12,3" + ("4,7" - "8" )) * "4")   ' dass das hier "geht", liegt an der "Kulanz" von MS, interne Typkonvertierungen in VBA eingebaut zu haben, die Rücksicht auf Windows-Ländereinstellungen nehmen.
   Debug.Print (12.3 + (4.7 - 8 )) * 4
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 10, 2012, 12:37:13
So, jetzt zeig ich euch einfach mal meinen Code, vielleicht seh ich ja den Wald vor lauter Bäumen nicht:

If rst.RecordCount > 0 Then rst.MoveFirst
Do While Not rst.EOF
   
    intID = rst.Fields(0)
   
    strBerechnung = Nz(DLookup("[SZBerechnung]", "[qryStromWertZähler]", "SWZJahrRef = " & intJahr & " AND SZID = " & intID & ""), 0)
   
    'Schleife 2 Start
    If y > 0 Then rst2.MoveFirst
    Do While Not rst2.EOF

        dblWert = Nz(DLookup("[DifferenzVJ]", "[qryStromWertZähler]", "SWZJahrRef = " & intJahr & " AND SZID = " & rst2.Fields(0) & ""), 0)
        strKürzel = Nz(DLookup("[SZKürzel]", "[tblStromZähler]", "SZID = " & rst2.Fields(0) & ""), 0)
        strBerechnung = Replace(strBerechnung, strKürzel, Str(dblWert))
   
    rst2.MoveNext
    Loop
   
    strBerechnung = Replace(strBerechnung, " ", "")
    strBerechnung = Chr(34) & strBerechnung & Chr(34)
    strBerechnung = Eval(strBerechnung)
    dblWert = CDbl(strBerechnung)
    strInfo = strInfo & Nz(DLookup("[SZBezeichnung]", "[tblStromZähler]", "SZID = " & intID & ""), 0) & ";" & dblWert & ";"
   
rst.MoveNext
Loop
Titel: Re: Eval-Funktion
Beitrag von: ebs17 am Februar 10, 2012, 13:27:26
Zwischenfrage an hanskuhn: Machst Du hier Experimentalprogrammiererei (danach sieht es zur Zeit aus), oder ist Dir an effektiv ermittelten Ergebnissen gelegen?

Wie man im letzten Beitrag sehen kann, hast Du Tabellen und möchtest irgendetwas berechnen. Dazu würde man im einfachen sowie im effektiven Fall Abfragen (SQL-Anweisungen) einsetzen. Deine bisherigen Erläuterungen liefern allerdings noch keinen Ansatz für konkretere Hinweise.

Per Schleifen Tabellen durchlaufen und per DLookup Einzelwerte herauspicken ist nicht effektiv, und das Eval-Problem ist dann nur ein Folgeproblem.

Es wäre also sinnvoll, die eigentliche Ausgangssituation (Tabellen) und das eigentliche Ziel (Berechnungsergebnis) darzustellen. Schätzungsweise wird Dir dann hier ein ganz anderer Lösungsweg als Deiner vorgeschlagen.

MfGA
ebs
Titel: Re: Eval-Funktion
Beitrag von: daolix am Februar 10, 2012, 13:57:10
Zitat von: DF6GL am Februar 10, 2012, 12:25:08
   Debug.Print Eval(("12,3" + ("4,7" - "8")) * "4")   ' dass das hier "geht", liegt an der "Kulanz" von MS, interne Typkonvertierungen in VBA eingebaut zu haben, die Rücksicht auf Windows-Ländereinstellungen nehmen.
Ahso, alles klar. Ich verstehe. Ich merk gerade das mir diese "ich mach mal alles schön im Hintergrund"-Kulanz manchmal auf'n Zeiger geht. Ich glaub ich werde Eval auch weiterhin nicht benutzen, denn wenn ich das (-) durch (+) ersetze steigt er auf meinem PC aus. ( Debug.Print Eval(("12,3" + ("4,7" + "8")) * "4") )
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 11, 2012, 19:03:21
ebs17: Das ist schon ein konkretes Anliegen von mir: Ich möchte halt, dass die Werte aus meiner Spalte "Wert" nutzerabhängig verrechnet werden. Ich weiss nicht, ob eine Abfrage effektiver ist - sicher nicht so aufwendig, klar. Aber wie bekomme ich sowas in eine Abfrage rein? Die müsste ich dann dynamisch zur Laufzeit zusammensetzen oder wie soll das funktionieren?!

Meine Ausgangstabelle ist, wie gesagt, folgende:

ID|Wert|Kürzel|Verrechnungregel
1|1234|A|A
2|2345|B|A+B
3|543|C|(A+B)-C
etc...

Mein Anliegen ist nun, die Verrechnung anhand der Spalte "Verrechnungsregel" durchzuführen, indem ich die "Kürzel" durch die Werte aus der Spalte "Wert" des betreffenden Datensatzes ersetze.

DF6GL schrieb es schon:
bei ID=3   ID1Wert + ID2Wert -ID3Wert   (---> (1234+ 2345) -543)  )
Titel: Re: Eval-Funktion
Beitrag von: ebs17 am Februar 11, 2012, 21:29:33
Franz schrieb auch:
Zitataber warum steht dann bei JEDEM Datensatz eine extra Regel?.  Den Zusammenhang versteh ich noch nicht. M. E gehören die Rechnenregeln in eine extra Tabelle, aus den man eine bestimmte Regel auswählt und dann auf die Werte in der Werte-Tabelle anwendet.

Etwas mehr musst Du einen solchen Fall schon erläutern. Solch eine Tabelle nimmt man im Normalfall nicht kritiklos entgegen.
Mir ist bisher nur ein Fall untergekommen, wo Formeln sinnvoll in Tabellen abgelegt und diese Tabelleneinträge für Berechnungen herangezogen wurden. Dabei handelte es sich um Aufmassberechnungen, wo Flächen und Volumen von geometrischen Körpern zu ermitteln waren, wobei der Nutzer allerdings keine Formeln eingegeben hat, sondern "nur" den jeweiligen geometrischen Körper ausgewählt hat.

Momentan hat Deine Tabelle eine deutliche Ähnlichkeit zu einer Exceltabelle (Werte und Formeln vereinigt). Eine solche gegenseitige Abhängigkeit der Datensätze in einer Datenbanktabelle untereinander habe ich noch gar nicht gesehen. Das ist weit ab von üblichen Regeln (die sich an Erfahrungen orientieren).
Es macht wenig Sinn, Excel in Access nachzubauen.

Um wiederum datenbankmäßig, also mit Abfragen zu arbeiten, ist eine entsprechende Datenmodellierung unabdingbar.

MfGA
ebs
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 15, 2012, 12:01:30
Ok, also folgendes Szenario:

Bei der Tabelle handelt es sich ja um Zähler und deren Werte. Allerdings sind das eine Unterzähler von anderen Zählern etc., d.h. die abgelesenen Werte müssen u.U. noch miteinander verrechnet werden. Die Spalte Wert enthält also den Ablesewert und die Spalte Verrechnungsregel gibt halt an, wie der letztendliche Wert zustande kommt. Da alle anderen Berechnungen wieder in Abfragen stehen, ist es auch sinnvoll, das in Access zu belassen.
Wie sollte eine neue Datenmodellierung etwas an dem Umstand ändern, dass userabhängig etwas berechnet werden soll ???
Titel: Re: Eval-Funktion
Beitrag von: DF6GL am Februar 15, 2012, 13:16:14
Hallo,

"Wie sollte eine neue Datenmodellierung etwas an dem Umstand ändern, dass userabhängig etwas berechnet werden soll"


es würde das Wörtchen "soll" in "kann" ändern...  ::)
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 15, 2012, 13:42:52
Also gut, ich habe meine Methode jetzt mal weiter verfolgt, da ich nicht sehe, wie ich durch eine Neustrukturierung meiner Tabellen das Grundproblem lösen kann. Die Eval-Funktion arbeitet bei mir, wenn ich die Anführungszeichen komplett weg lasse. Ich weiß auch nicht, warum ich die Eval-Funktion nicht verwenden sollte, wenn sie in Access zur Verfügung steht?!
Es macht für mich ja wenig Sinn, meine Formeln in eine Extra-Tabelle zu packen, wenn jeder Datensatz ohnehin eine individuelle Berechnung, also 1:1-Beziehung, zugewiesen bekommt.
Titel: Re: Eval-Funktion
Beitrag von: ebs17 am Februar 15, 2012, 15:27:21
Soll man aus Deinem vorletzten Beitrag schließen, dass ein User ein Zähler ist?

Um Verbräuche an Hand von Zählerständen zu ermitteln, muss man einfach nur addieren, eine passende Tabellenstruktur vorausgesetzt, und das geht mit SQL prima und rasant und deutlich einfacher als mit dem oben gezeigten Code-"Ungetüm" aus Recordset und Domänenaggregatfunktionen.

Was womit zu summieren wäre, ergibt sich aus Zuordnungen wie Nutzer - Zähler und Hauptzähler - Unterzähler.

ZitatIch weiß auch nicht, warum ich die Eval-Funktion nicht verwenden sollte, wenn sie in Access zur Verfügung steht?!
Vermutlich reden wir aneinander vorbei: Meine Fragen/Vorschläge gehen in die Richtung, die Anwendung an sich besser zu gestalten, eben in Richtung Datenbankanwendung. Dass man da i.d.R. Eval nicht benötigt, ist nur ein Nebeneffekt.

Wenn Du natürlich alles und in Deiner Art ausprobieren und verwenden möchtest, was Dir Access zur Verfügung stellt, so ist das Dein gutes Recht. Dafür wünsche ich viel Erfolg.

MfGA
ebs
Titel: Re: Eval-Funktion
Beitrag von: hanskuhn am Februar 16, 2012, 09:35:04
Hm, natürlich könnte ich das auch alles in getrennte Tabellen packen und miteinander verrechnen. Allerdings sind die Beziehungen zueinander doch recht komplex und da ich eh nur eine Handvoll Zähler habe, lohnt es sich imho nicht, da jetzt noch mehrere Tabellen anzuhängen. Deshalb halte ich diesen Weg, auch wenn ein wenig unkonventionell, in diesem Fall für gangbar.
Also, danke für eure Anmerkungen!
Titel: Re: Eval-Funktion
Beitrag von: Bitsqueezer am März 02, 2012, 15:34:18
Hallo,

ich würde mich zwar auch der Meinung anschließen, daß es hier etwas Tabellenkonzeptarbeit notwendig ist, aber prinzipiell läßt sich das Problem auch einfach mit SQL lösen (mit vielen VBA-Funktionen, versteht sich):

Zuerst eine simple Abfrage, die den Wert für jedes Kürzel ermittelt:

SELECT tblZaehler.Kürzel, tblZaehler.Wert
  FROM tblZaehler;


und dann kann man mit diesem "kleinen" Konstrukt (hier für die drei genannten Kürzel, wenn mehr benötigt werden, muß die Abfrage entsprechend erweitert werden) die Berechnung von SQL erledigen lassen:

SELECT ID, Wert, Kürzel, Verrechnungsregel,
   Eval(Replace(Replace(Replace(Verrechnungsregel,"A",
(SELECT TOP 1 qryKürzelWert.Wert FROM qryKürzelWert
  WHERE qryKürzelWert.Kürzel="A")
),"B",
(SELECT TOP 1 qryKürzelWert.Wert FROM qryKürzelWert
  WHERE qryKürzelWert.Kürzel="B")
),"C",
(SELECT TOP 1 qryKürzelWert.Wert FROM qryKürzelWert
  WHERE qryKürzelWert.Kürzel="C")
)
) AS Ergebnis
FROM tblZaehler;


(Wobei "tblZaehler" dann gegen den entsprechenden Abfragenamen zu ersetzen wäre.)

Gruß

Christian
Titel: Re: Eval-Funktion
Beitrag von: ebs17 am März 03, 2012, 00:52:28
@Christian: Das ist ein schöner systematischer Ansatz, wonach man auch die SQL-Anweisung per VBA erweitern kann.

Allerdings ist das auch ein mutiger Ansatz. Von drei Datensätzen auf eine Tabelle unbekannter Größe und unbekannten Inhalts in Folge zu schließen halte ich, insbesondere wegen der bisherigen Heransgehensweise des TE, für recht gewagt.
Ob dann die SQL-Anweisung für die Realtabelle einfach bleibt ... ?

MfGA
ebs
Titel: Re: Eval-Funktion
Beitrag von: Bitsqueezer am März 03, 2012, 01:25:42
Hallo,

naja, wie gesagt, es ist nur eine Möglichkeit, und nur darum gewählt, weil der Autor gesagt hat, es seien nur "eine Handvoll" Werte, so daß man das gerade noch so verwenden kann.

Gruß

Christian