PDA

Vollständige Version anzeigen : Dezimal in Binärcode umwandeln


SirYoshy
10.05.2011, 14:38
hallo,

ich bin relativ neu im Access-Geschäft und bau mir gerade meine ersten Abfragen zusammen. Das klappt auch bisher ganz gut, dennoch habe ich eine Frage:

Ich habe eine DB mit Dezimalwerten in einer Spalte, benötige aber den Binärwert oder noch besser die Quersumme des Binärwerts. Zur Veranschaulichung ein Beispiel:

In der DB ist eine 127 eingetragen. Ich benötige nun den Binärwert, in diesem Fall 1111111
letztendliches Ziel ist es, nicht die "1111111" stehen zu haben, sondern 1+1+1+1+1+1+1, also eine 7

Ich weiß, dass ich in Access-Abfragen neue Spalten bilden kann, die durch Rechenoprationen gebildet werden. Gibt es einen oder mehrere Operatoren, mit denen ich meinen Zielwert in eine Spalte abbilden lassen könnte?

P.S.: Bisher habe ich fast ausschließlich mit der Access-Maske gearbeitet und kaum im SQL-Code. Da ich ein wenig programmieren kann, könnte ich jedoch auch versuchen, mit diesem zu arbeiten.


Wäre euch unendlich dankbar für Eure Hilfe

Yoshy

************
Hintergrund: Jede Ziffer des Binärwerts steht für einen Wochentag, an dem entweder ein Ereignis stattfindet (1) oder eben nicht (0). Ziel meiner Abfrage ist es nun, nicht herauszufinden, ob ein Ereignis an einem bestimmten Tag stattgefunden hat, sondern wie oft pro Woche es stattgefunden hat.

Toast78
10.05.2011, 14:48
Hast du schon Google bemüht, um dir die FUnktionen für Binärdarstellung und Quersumme zu suchen? Das ist doch wohl erstmal das Grundproblem

Der Rest ist ja nur noch ein berechnetes Feld in deiner Abfrage. getQuersumme(getBinaerwert(DeineDezimalZahl)) AS DeinErgebnis

Hurra, ich liebe solche Bit-Schubsereien! :rolleyes:

Edgar Basler
10.05.2011, 14:59
Zuerst braucht man eine Funktion die die Umwandlung vollzieht. Hier eine der Möglichkeiten:

Public Function Long2Binary(ByVal lngNumber As Long) As String

Dim lngRest As Long
Dim i As Integer
Dim j As Integer

If lngNumber = 0 Then
Long2Binary = "0"
ElseIf lngNumber > 0 Then
i = 0
While 2 ^ i <= lngNumber
i = i + 1
Wend
Long2Binary = String(i, "0")
Mid(Long2Binary, 1, 1) = 1
j = i
lngRest = lngNumber - 2 ^ (i - 1)
For i = j - 1 To 0 Step -1
If 2 ^ i <= lngRest Then
lngRest = lngRest - 2 ^ i
Mid(Long2Binary, j - i, 1) = 1
End If
Next
End If

End Function

Edgar Basler
10.05.2011, 15:24
.... und dann braucht man noch die Bildung der Quersumme .....


Public Function Binary2Quer(Binaer As String) As Integer

Dim i As Integer

For i = 1 To Len(Binaer) Step 1
If Mid(Binaer, i, 1) = 1 Then
Binary2Quer = Binary2Quer + 1
End If
Next

End Function

Thomas Möller
10.05.2011, 17:36
Hallo Yoshy,

In der DB ist eine 127 eingetragen. Ich benötige nun den Binärwert, in diesem Fall 1111111
letztendliches Ziel ist es, nicht die "1111111" stehen zu haben, sondern 1+1+1+1+1+1+1, also eine 7

ich bin mir nicht ganz sicher, ob die Vorgehensweise in allen Fällen erfolgversprechend ist.

Wie möchtest Du

1010101 = 1+0+1+0+1+0+1 = 4

von

1011100 = 1+0+1+1+1+0+0 = 4

unterscheiden?

CU

SirYoshy
10.05.2011, 22:37
dass ich die verschiedenen binären zahlen nicht mehr auseinanderhalten kann, ist nicht schlimm. Wie oben beschrieben (ok, liest wahrscheinlich keiner, weils wie ne signatur aussieht) geht es darum zu wissen, wie oft in einer woche ein ereignis stattfindet. Jede ziffer der binären zahl steht dabei für einen wochentag. An welchem tag das ereignis genau stattfindet ist egal. Es geht lediglich um die anzahl der einsen in der binären zahl.

ebs17
10.05.2011, 23:38
Anmerkung: Aus einem Datum kann man den Wochentag wie auch die Kalenderwoche ermitteln und daraus abgeleitet auch Ereignisse zählen/summieren. So würde man es in einer Datenbank machen.

Aber die Ermittlung dieser Dezimalzahl und die Konvertierung in eine Binärzahl sowie die Bildung der Quersumme sehen natürlich spannender aus.

Marsu65
10.05.2011, 23:48
Hallo Yoshy,
bist du mit den dir angebotenen Lösungen weitergekommen?

Ich hab hier noch eine ("etwas" kürzere) Alternative zu Edgars Funktionen, die die Quersumme direkt aus der Zahl bildet. Da ja max. 2^7 dargestellt werden müssen, reicht die Umrechnung in Byte.
Public Function Byte2QSum(ByVal Value As Byte) As Integer
Do While Value
If Value And 1 Then Byte2QSum = Byte2QSum + 1
Value = Value \ 2
Loop
End Function

Die Funktion kopierst du in ein normales Modul.
Dann kannst du Sie in einer Abfrage verwenden.
In ein Feld schreibst du z.B. AnzahlTage:Byte2QSum([DeinZahlenfeld])
DeinZahlenfeld musst du natürlich noch durch deine Feldbezeichnung ersetzen, in dem die Werte stehen.

SirYoshy
11.05.2011, 09:09
Hallo Leute,

schonmal einen riesigen Dank für eure Antworten! echt super und so schnell!
Leider hab ich als NAP mal wieder die Frage nicht zu 100% korrekt gestellt und so habe ich noch ein winziges Problem (soweit ich sonst sehen kann, klappt alles).
Und zwar ist in meiner Ausgangsspalte Datenmüll in Form von zwei Nullen enthalten, die natürlich die Funktionen nicht funktionieren lassen. So steht in der Spalte keine "127" sondern eine "12700", bei einer "72" sähe die Zahl fogendermaßen aus: "07200".

Ich benötige also in jedem Fall die ersten drei Zeichen von links.
ich habe das ganze auf diese Weise versucht zu lösen:

Public Function Long2Binary(ByVal lngNumber As Long) As String

Dim lngRest As Long
Dim i As Integer
Dim j As Integer


lngNumber = Left(lngNumber, 3)

If lngNumber = 0 Then
Long2Binary = "0"
ElseIf lngNumber > 0 Then
i = 0
While 2 ^ i <= lngNumber
i = i + 1
Wend
Long2Binary = String(i, "0")
Mid(Long2Binary, 1, 1) = 1
j = i
lngRest = lngNumber - 2 ^ (i - 1)
For i = j - 1 To 0 Step -1
If 2 ^ i <= lngRest Then
lngRest = lngRest - 2 ^ i
Mid(Long2Binary, j - i, 1) = 1
End If
Next
End If

End Function

habe also folgende Zeile einfach eingefügt:

lngNumber = Left(lngNumber, 3)

So hätte ich es in Excel halt gemacht, leider hatte das ganze nicht den gewünschten Erfolg. Kann mir jemand eine Lösung sagen und vielleicht einen Tip geben, was ich falsch gemacht habe, damit ich die Logik von VBA in Access besser verstehe?

Wäre fantastisch!


@marsu: mit deiner Funktion habe ich es ebenso versucht die ersten drei Zeichen zu verwenden, aber das hat wahrscheinlich aus dem selben Grund nicht funktioniert. Außerdem habe ich die Logik hinter Deiner Funktion nicht zu 100% durchblickt, deswegen habe ich die obenstehende hier gepostet.

@ebs17: Leider geht es hier um Planungsdaten. Da sich die Ereignisse in jeder Woche des Jahres wiederholen, stehen in den Planungsdaten keine genauen Daten/KW/Wochentage zur Verfügung. Es wird lediglich diese Codierung angegeben, mit der zu 100% feststeht, an welchen Daten die Ereignisse stattfinden werden. Weitere Angaben sind also im Normalfall nicht nötig, es sei denn man ist selber kein Computer, so wie ich ;)

ebs17
11.05.2011, 09:53
Dann liegen wohl noch keine Dezimalzahlen vor, sondern Strings mit Ziffern. Eine Umwandlung könnte man wie folgt versuchen:
?Val("07200")/100
=> 72

SirYoshy
11.05.2011, 10:04
ach, danke, an das Teilen durch 100 bin ich gar nicht gekommen, habe versucht mit der String-Länge zu arbeiten und das hat leider nicht funktioniert. So langsam versteh ich die Funktionsweise von VBA in Access ein wenig glaube ich.

Habe das ganze letztendlich so gelöst:

Public Function Byte2QSum(ByVal Value As Long) As Integer

Dim IHelp As Integer

IHelp = Int(Value / 100)
Do While IHelp
If IHelp And 1 Then Byte2QSum = Byte2QSum + 1
IHelp = IHelp \ 2
Loop
End Function

Vielen Dank nochmal für eure Hilfe!!