This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
vba:cast:bitandbyte [30.04.2014 10:31:04] yaslaw created |
vba:cast:bitandbyte [29.04.2015 11:15:38] (current) yaslaw |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== [VBA] bitArray() und getByte() ====== | + | ====== [VBA] bitArray(), char2byte() und byte2char()====== |
- | Zwei Funktionen im Umgang mit Bits. bitArray() zerlegt ein Zahl in ihre Bit-Teile. Ist also das Rekusive zu 1+2+4+8+... | + | //Drei Funktionen im Umgang mit Bits.// |
- | Und mit getByte kann man die Bit-Darstellung einers Zeichens ermitteln | + | {{:vba:cast:bitandbyte.bas|Download bitAndBytes.bas Version 1.0}} |
- | <code vb _bitArray.bas> | + | - bitArray() zerlegt ein Zahl in ihre Bit-Teile. Ist also das Rekusive zu 1+2+4+8+... |
- | '------------------------------------------------------------------------------- | + | - Mit char2byte() kann man die Bit-Darstellung eines Zeichens ermitteln |
- | 'File : bitArray | + | - Und mit byte2char() das byte wieder in ein Zeichen. |
- | ' Copyright mpl by ERB software | + | |
- | ' http://wiki.yaslaw.info/dokuwiki/doku.php/vba/functions/byteArray | + | |
- | 'Environment : VBA 2007 + | + | |
- | 'Version : 1.0 | + | |
- | 'Author : Stefan Erb (ERS) | + | |
- | 'History : 29.04.2014 - ERS - Creation | + | |
- | '------------------------------------------------------------------------------- | + | |
- | Option Explicit | + | |
- | Public Enum baValueType | + | |
+ | =====Public Defintions===== | ||
+ | ====Enum byValueType==== | ||
+ | <code vb>Public Enum baValueType | ||
baBitPosition = 1 'Der Array-Value beinhaltet die Bitpositionen von allen gesetzten Bit. Bei nicht gesezten Bits ist der Value false (also -1) | baBitPosition = 1 'Der Array-Value beinhaltet die Bitpositionen von allen gesetzten Bit. Bei nicht gesezten Bits ist der Value false (also -1) | ||
baBit = 2 'Gibt das Bit an der entsprechenden Position zurück. 0 oder 1 | baBit = 2 'Gibt das Bit an der entsprechenden Position zurück. 0 oder 1 | ||
baValue = 3 'Gibt den Wert des Bits zurück: 2^Bitposition | baValue = 3 'Gibt den Wert des Bits zurück: 2^Bitposition | ||
- | End Enum | + | End Enum</code> |
- | Public Enum baBitCode | + | ====Enum byBitCode==== |
+ | <code vb>Public Enum baBitCode | ||
baDefault = 0 'Bei Ziffern wird der BCD, bei allen anderen der ASCII verwendet | baDefault = 0 'Bei Ziffern wird der BCD, bei allen anderen der ASCII verwendet | ||
- | baBCD = 1 'Im BCD-Code werden die Ziffern 0 bis 9 in vier Bits codiert. Dabei können die Zahlen von 0000 bis 1001 entstehen. Der BCD-Code wird auch als 8-4-2-1-Code bezeichnet. | + | baBCD4 = 1 'Im BCD-Code werden die Ziffern 0 bis 9 in vier Bits codiert. Dabei können die Zahlen von 0000 bis 1001 entstehen. Der BCD-Code wird auch als 8-4-2-1-Code bezeichnet. |
'Wenn der Paramenter keine Nummer ist, wird der Fehler C_BITCODE_CAST_ERROR geworfen | 'Wenn der Paramenter keine Nummer ist, wird der Fehler C_BITCODE_CAST_ERROR geworfen | ||
baASCII = 2 'Der American Standard Code for Information Interchange codiert alle Zeichen inklusive der englischen Sonderzeichen in sieben Bits. Insgesamt können mit dem ASCII-Code 128 ( \textstyle 2^7 ) verschiedene Zeichen codiert werden | baASCII = 2 'Der American Standard Code for Information Interchange codiert alle Zeichen inklusive der englischen Sonderzeichen in sieben Bits. Insgesamt können mit dem ASCII-Code 128 ( \textstyle 2^7 ) verschiedene Zeichen codiert werden | ||
- | End Enum | + | End Enum</code> |
- | Public Const C_BITCODE_CAST_ERROR = vbObjectError + 6000 | + | ====Konstanten==== |
+ | <code vb>Public Const C_BITCODE_CAST_ERROR = vbObjectError + 6000</code> | ||
+ | =====bitArray()===== | ||
+ | ====Definition==== | ||
+ | <code vb>Public Function bitArray( _ | ||
+ | ByVal iNumber, _ | ||
+ | Optional ByVal iValueType As baValueType = baBit, _ | ||
+ | Optional ByVal iFilteredOut As Boolean = False _ | ||
+ | ) As Variant()</code> | ||
+ | ***iNumber** Die Nummer, welche 'zerlegt' werden soll | ||
+ | ***iValueType** Art des Inhalt des Array. | ||
+ | ***iFilteredOut** Flag, ob alle 0er-Bit ausgefiltert werden sollen | ||
+ | ====Beispiele==== | ||
+ | <code vb> | ||
+ | 'example 1) Gib das Bitmuster zurück. Key = Bitposition, Value = Bit | ||
+ | print_r bitArray(5) | ||
+ | <Variant()> ( | ||
+ | [0] => <Integer> 1 | ||
+ | [1] => <Integer> 0 | ||
+ | [2] => <Integer> 1 | ||
+ | ) | ||
+ | |||
+ | 'example 2) Gib die Werte zurück, mit denen bei Bitvergleichen gerehncet werden soll | ||
+ | ' Key = Bitposition, Value = 2 ^ Bitposition, wenn der Bit gesetzt ist. Ansonsten 0 | ||
+ | print_r bitArray(5, baValue) | ||
+ | <Variant()> ( | ||
+ | [0] => <Long> 1 | ||
+ | [1] => <Boolean> False | ||
+ | [2] => <Long> 4 | ||
+ | ) | ||
+ | |||
+ | 'example 3) Gib einfach ein Array aus, der die besetzten Bitpositionen zurückgint | ||
+ | ' Key = Laufnummer, Value = Bitposition bei welcher det Bit 0 ist | ||
+ | print_r bitArray(5, baBitPosition, True) | ||
+ | <Variant()> ( | ||
+ | [0] => <Long> 0 | ||
+ | [1] => <Long> 2 | ||
+ | ) | ||
+ | </code> | ||
+ | |||
+ | =====char2byte()===== | ||
+ | |||
+ | ====Definition==== | ||
+ | <code vb> | ||
+ | Public Function char2byte( | ||
+ | ByVal iChar As Variant, | ||
+ | Optional iBitCode As baBitCode = baDefault | ||
+ | ) As String | ||
+ | </code> | ||
+ | ***iChar** Charakter, der gewandelt werden soll. Null wird als 0 gewertet | ||
+ | ***iBitCode** Die Codierung. baAscii oder ba BCD | ||
+ | |||
+ | ====Beispiele==== | ||
+ | <code vb> | ||
+ | 'example 1) Byte einer Zahl. Zahlen sind tandart nach BCD-Codierung | ||
+ | print_r getByte(9) | ||
+ | <String> '1001' | ||
+ | |||
+ | 'example 2) Dito, aber nach ASCII-Codierung | ||
+ | print_r getByte(9, baASCII) | ||
+ | <String> '10011100' | ||
+ | |||
+ | 'example 3) String, Standart nach Ascii | ||
+ | print_r getByte("A") | ||
+ | <String> '10000010' | ||
+ | |||
+ | 'example 4) Null, Standart nach Ascii | ||
+ | print_r getByte(Null, baBCD) | ||
+ | <String> '00000000' | ||
+ | |||
+ | 'example 5) Null nach BCD | ||
+ | print_r getByte(Null) | ||
+ | <String> '0000' | ||
+ | </code> | ||
+ | |||
+ | =====byte2char()===== | ||
+ | |||
+ | ====Definition==== | ||
+ | <code>Public Function byte2char(ByVal iByte As String) As Variant</code> | ||
+ | ***iByte** Byte, das in ein Charakter gewandelt werden soll | ||
+ | |||
+ | ====Beispiele==== | ||
+ | <code vb> | ||
+ | 'example 1) Byte einer Zahl. Zahlen sind tandart nach BCD-Codierung | ||
+ | print_r getChar("1001") | ||
+ | <Integer> 9 | ||
+ | |||
+ | 'example 2) Dito, aber nach ASCII-Codierung | ||
+ | print_r getChar("10011100") | ||
+ | <String> '9' | ||
+ | |||
+ | 'example 3) String, Standart nach Ascii | ||
+ | print_r getChar("10000010") | ||
+ | <String> 'A' | ||
+ | |||
+ | 'example 4) Null, Standart nach Ascii. Es kommt die Rückgabe von chr(NULL) zurück | ||
+ | print_r getChar("00000000") | ||
+ | <String> '\u0000' | ||
+ | |||
+ | 'example 5) Null nach BCD. Ist nciht mehr von 0 unterscheidbar | ||
+ | print_r getChar("0000") | ||
+ | <Integer> 0 | ||
+ | </code> | ||
+ | |||
+ | =====Codes===== | ||
+ | ====Code bitArray()==== | ||
+ | <code vb> | ||
'/** | '/** | ||
' * Zerlegt eine Nummer ihn ihre Bits. | ' * Zerlegt eine Nummer ihn ihre Bits. | ||
- | ' * @example 1) Gib das Bitmuster zurück. Key = Bitposition, Value = Bit | ||
- | ' * print_r bitArray(5) | ||
- | ' * <Variant()> ( | ||
- | ' * [0] => <Integer> 1 | ||
- | ' * [1] => <Integer> 0 | ||
- | ' * [2] => <Integer> 1 | ||
- | ' * ) | ||
- | ' * @example 2) Gib die Werte zurück, mit denen bei Bitvergleichen gerehncet werden soll | ||
- | ' * Key = Bitposition, Value = 2 ^ Bitposition, wenn der Bit gesetzt ist. Ansonsten 0 | ||
- | ' * print_r bitArray(5, baValue) | ||
- | ' * <Variant()> ( | ||
- | ' * [0] => <Long> 1 | ||
- | ' * [1] => <Boolean> False | ||
- | ' * [2] => <Long> 4 | ||
- | ' * ) | ||
- | ' * @example 3) Gib einfach ein Array aus, der die besetzten Bitpositionen zurückgint | ||
- | ' * Key = Laufnummer, Value = Bitposition bei welcher det Bit 0 ist | ||
- | ' * print_r bitArray(5, baBitPosition, True) | ||
- | ' * <Variant()> ( | ||
- | ' * [0] => <Long> 0 | ||
- | ' * [1] => <Long> 2 | ||
- | ' * ) | ||
' * | ' * | ||
' * @param Long Die Nummer, welche 'zerlegt' werden soll | ' * @param Long Die Nummer, welche 'zerlegt' werden soll | ||
Line 93: | Line 173: | ||
bitArray = retArray | bitArray = retArray | ||
End Function | End Function | ||
+ | </code> | ||
+ | ====Code char2byte==== | ||
+ | <code vb> | ||
'/** | '/** | ||
' * Gibt für einen Char das Byte aus | ' * Gibt für einen Char das Byte aus | ||
- | ' * | ||
- | ' * @example 1) Byte einer Zahl. Zahlen sind tandart nach BCD-Codierung | ||
- | ' * print_r getByte(9) | ||
- | ' * <String> '1001' | ||
- | ' * @example 2) Dito, aber nach ASCII-Codierung | ||
- | ' * print_r getByte(9, baASCII) | ||
- | ' * <String> '10011100' | ||
- | ' * @example 3) String, Standart nach Ascii | ||
- | ' * print_r getByte("A") | ||
- | ' * <String> '10000010' | ||
- | ' * @example 4) Null, Standart nach Ascii | ||
- | ' * print_r getByte(Null, baBCD) | ||
- | ' * <String> '00000000' | ||
- | ' * @example 5) Null nach BCD | ||
- | ' * print_r getByte(Null) | ||
- | ' * <String> '0000' | ||
- | ' * | ||
' * @requiered bitArray() | ' * @requiered bitArray() | ||
' * | ' * | ||
Line 119: | Line 185: | ||
' * @retuen String Bitmuster | ' * @retuen String Bitmuster | ||
' */ | ' */ | ||
- | Public Function getByte(ByVal iChar As Variant, Optional iBitCode As baBitCode = baDefault) As String | + | Public Function char2byte(ByVal iChar As Variant, Optional iBitCode As baBitCode = baDefault) As String |
- | | + | 'Wenn der Input mehr als ein Zeichen ist, Fehler werfen |
+ | If Len(Nz(iChar)) > 1 Then Err.Raise C_BITCODE_CAST_ERROR, "getByte", "Input is to large. Only one Character is alloud" | ||
'Leere Strings in NULL wandeln | 'Leere Strings in NULL wandeln | ||
If Len(Nz(iChar)) = 0 Then iChar = Null | If Len(Nz(iChar)) = 0 Then iChar = Null | ||
Line 127: | Line 194: | ||
| | ||
'Prüfen ob der BCD COde angewendet werden kann. Nur wenn der Input eine Ziffer ist und der Codee Default oder BCD ist | 'Prüfen ob der BCD COde angewendet werden kann. Nur wenn der Input eine Ziffer ist und der Codee Default oder BCD ist | ||
- | If IsNumeric(Nz(iChar)) And (iBitCode = baDefault Or iBitCode = baBCD) Then | + | If IsNumeric(Nz(iChar)) And (iBitCode = baDefault Or iBitCode = baBCD4) Then |
- | Dim numVal As Integer: numVal = CInt(Nz(iChar)) | + | Dim numVal As Integer: numVal = CInt(Nz(iChar, 0)) |
- | getByte = Join(bitArray(numVal), "") | + | char2byte = Join(bitArray(numVal), "") |
- | getByte = getByte & String(4 - Len(getByte), "0") | + | char2byte = char2byte & String(4 - Len(char2byte), "0") |
'Wenn der Input keine Zahl ist und BCD angewählt wirde, ein Error werfen | 'Wenn der Input keine Zahl ist und BCD angewählt wirde, ein Error werfen | ||
- | ElseIf iBitCode = baBCD Then | + | ElseIf iBitCode = baBCD4 Then |
Err.Raise C_BITCODE_CAST_ERROR, "getByte", "Inputcharakter is not a number" | Err.Raise C_BITCODE_CAST_ERROR, "getByte", "Inputcharakter is not a number" | ||
'Die ASCII-Formatierung anwenden | 'Die ASCII-Formatierung anwenden | ||
Else | Else | ||
Dim ascVal As Integer: ascVal = IIf(IsNull(iChar), 0, Asc(Nz(iChar, " "))) | Dim ascVal As Integer: ascVal = IIf(IsNull(iChar), 0, Asc(Nz(iChar, " "))) | ||
- | getByte = Join(bitArray(ascVal), "") | + | char2byte = Join(bitArray(ascVal), "") |
- | getByte = getByte & String(8 - Len(getByte), "0") | + | char2byte = char2byte & String(8 - Len(char2byte), "0") |
End If | End If | ||
+ | End Function | ||
+ | </code> | ||
+ | |||
+ | ====Code byte2char== | ||
+ | <code vb> | ||
+ | '/** | ||
+ | ' * Umkehrfunktion zu getByte: Gibt aus einem Byte-Code wieder das Zeichen zurück | ||
+ | ' * | ||
+ | ' * | ||
+ | ' * @param String Byte-Code | ||
+ | ' * @return Varaint Das Zeichen. Bei Ascii-Zeichen nach der Regel von chr() | ||
+ | ' */ | ||
+ | Public Function byte2char(ByVal iByte As String) As Variant | ||
+ | 'Überprüfen ob es sich um ein ASCII oder BCD handelt | ||
+ | Dim bitCode As baBitCode: bitCode = Switch(Len(iByte) = 8, baASCII, Len(iByte) = 4, baBCD4, True, baNA) | ||
+ | 'Falls es keinen von beiden ist, ein Fehler werfen | ||
+ | If bitCode = baDefault Then Err.Raise C_BITCODE_CAST_ERROR, "getChar", "Input is not a byte in type ASCII oder BCD" | ||
+ | | ||
+ | 'Die Zahl hochrechnen | ||
+ | Dim numVal As Integer: numVal = 0 | ||
+ | Dim i As Integer: For i = 0 To Len(iByte) - 1 | ||
+ | If Mid(iByte, i + 1, 1) = 1 Then numVal = numVal + 2 ^ i | ||
+ | Next i | ||
+ | | ||
+ | 'und gemäss Code umwandeln | ||
+ | Select Case bitCode | ||
+ | Case baASCII: byte2char = Chr(numVal) | ||
+ | Case baBCD4: byte2char = numVal | ||
+ | End Select | ||
End Function | End Function | ||
</code> | </code> |