Rechenfehler in VBA
30.10.2003 08:56:32
Andreas Eckmann
ich hatte vor ca. 2 Wochen eine Anfrage zu obigem Thema gestellt. Leider konntet Ihr mir nicht abschließend helfen. Ich hatte am Schluß versprochen, meine Lösung zu präsentieren, sobald ich sie habe. Hier ist sie nun.
Ziel war es, eine bis zu 19stellige Zahl in einem Feld mit 10 Zeichen unterzubringen. Das Feld kann alle darstellbaren ASCII-Zeichen aufnehmen. Durch die Formel a^b=x^c (a=Anzahl vorkommenden Zeichen (hier 10), b=ursprüngliche Länge (hier 19), c=Länge des Feldes (hier 10), x=gesucht) ergibt sich x=79,4, rund 80. Also muß ich die max. 19stellige Zahl in Vielfache von 80^i zerlegen. Dieser Wert wird dann um 33 erhöht in ASCII umgewandelt (33 ist das erste darstellbare ASCII-Zeichen nach dem Leerzeuchen).
Leider läßt sich sowas weder in EXCEL noch VBA ohne ein paar ein Tricks berechnen. Bei der BErechnung des Rests einer Division verschlucken beide die letzten 2 bis 4 Ziffern.
In Excel habe ich dann die Berechnung des Rest ohne die letzten 6 Ziffern gemacht (weil für 80^i mit i>=6 sind die letzten 6 Ziffern = "000000") und habe anschließend die 6 Ziffern des vorherigen Rests mit verketten() wieder angefügt.
In VBA habe ich es wie unten aufgeführt gelöst. Die Lösung zur Behandlung großer Zahlen heißt hier z=CDec(...).
Genug der Vorrede. "9999999999999999999" ergibt "kIF-UHpppp".
Sub BerechneCPIu()
Dim iAusgangswert As Variant
Dim iRest As Variant
Dim iDivisor As Integer
Dim iVersatz As Integer
iDivisor = 80
iVersatz = 33
iAusgangswert = 1
iAusgangswert = "9999999999999999999"
iRest = iAusgangswert
For i = 9 To 0 Step -1
iExponent = iDivisor ^ i
iTeiler = Int(iRest / iExponent)
sZeichen = Chr(iTeiler + iVersatz)
sErgebnis = sErgebnis + sZeichen
If iTeiler > 0 Then
z = CDec(iTeiler * iExponent)
iRest = iRest - z
End If
Next i
'--- Ausgabe CPIu
Debug.Print sErgebnis
End Sub
Und hier die Umkehrung.
Sub BerechneCgPA2()
Dim sAusgangswert As String
Dim iVersatz As Variant
Dim iEndwert As Variant
Dim sEinzelnesZeichen As String
Dim y As String
iDivisor = 80
iVersatz = 33
sAusgangswert = "kIF-UHpppp"
For i = 0 To 9
sEinzelnesZeichen = Mid(sAusgangswert, 10 - i, 1)
y = Asc(sEinzelnesZeichen) - iVersatz
iExponent = (iDivisor ^ i)
iEndwert = CDec(iEndwert + iExponent * y)
Next i
'--- Ausgabe CPIu
Debug.Print Str(iEndwert)
End Sub