It's a personal preference thing (IMHO) on how to handle function returns. I've seen this convention used consistently on SO, and (for me) it makes for clearer reading. I prefer variables to begin with lowercase letters and a Sub or Function to start with an uppercase letter. I'll second 's suggestion on clearer function names, although my naming preference is for AsciiToHexString and HexStringToAscii. That way you're not assuming what the remainder might be - of course here it's either 1 or 0, but the point is that the way the comparison is written in foo Mod bar never has to change, regardless of what the value of bar is. "Is value a multiple of X" is usually written as: If value Mod x 0 Then This doesn't strike me as intuitive: If Len(hexRaw) Mod 2 = 1 Then That way the calling code can handle a runtime error 5 (aka invalid procedure call or argument) with a useful description: ?HexCode("test")Īnd now you have a function that's just as friendly to use as a UDF as it is in plain VBA code. If TypeName(Application.Caller) = "Range" Then OnHexDecodeError "Hex character '" & hexchar & "' is not a valid hexadecimal digit."Īnd then the error-handling subroutine could do this: DecodeError: OnHexDecodeError "Parameter value '" & HexString & "' is invalid." OnHexDecodeError "Parameter value '" & HexString & "' is not in the expected format." Instead of GoTo-jumping when there's an invalid argument to early-return an Excel error value that's only really useful when the function is used as a UDF (and confusing when it's called from VBA code), you could be raising an actual meaningful error (which would still be jumping to the DecodeError label).įirst, because we're raising an error in several places, I'd make a little utility procedure: Private Sub OnHexDecodeError(ByVal message As String) I think you have an opportunity for using Application.Caller in that error-handling subroutine, and make the function behave differently when it's used as a UDF vs. 'Return the concatenated bytes as a string Hexchar = VBA_HEX_PREFIX & Mid$(hexRaw, 1 + char * 2, 2) ReDim hexChars(0 To numHexChars - 1) As Byte 'Check if the string is valid for decoding HexRaw = Mid$(HexString, 1 + Len(HexPrefix)) If Not StrComp(Left$(HexString, Len(HexPrefix)), HexPrefix, vbTextCompare) = 0 Then Public Function HexDecode(HexString As String, Optional HexPrefix As String = HEX_STRING_PREFIX) He圎ncode = HexPrefix & Join(hexChars, "") HexChars(char) = Right$("00" & Hex$(asciiChars(char)), 2) ReDim hexChars(LBound(asciiChars) To UBound(asciiChars)) As Stringįor char = LBound(asciiChars) To UBound(asciiChars) Public Function He圎ncode(AsciiText As String, Optional HexPrefix As String = HEX_STRING_PREFIX) As StringĪsciiChars = StrConv(AsciiText, vbFromUnicode) I need to use this in Excel, so I'm using CVErr(xlErrValue) to return errors, but this could maybe benefit from being more generic. I'm assuming that assigning the results of CByte("&h80") to a byte array, and then using StrConv to convert the array to a Unicode string, is more efficient than assigning the results of Chr$("&h80") to a string array, and then using Join to concatenate the strings. I've avoided using concatenation in favour of performance. I've written an EncodeHex and a DecodeHex function to do the conversion. I needed to convert some Ascii text to binary in Hex format 0x00FF.
0 Comments
Leave a Reply. |