Serial port in VBA without MSComm - vba

I need to read and write byte arrays using COM-port and VBA.
I found a nice solution here
But this solution works only for String type for input/output data. I need a byte array. I tried to write new functions but I don't know how to accurately read this data. Can you help me?

You can sending an array in this way:
Dim bWrite(1 To 3) As Byte
bWrite(1) = &HA1
bWrite(2) = &HB2
bWrite(3) = &HC3
Dim wr As Long
rc = WriteFile(h, bWrite(1), 3, wr, 0) 'wr indicates how many bytes went to the port.
Example from here: https://strokescribe.com/en/serial-port-vb-winapi.html

Related

VB.NET - Convert String Representation of a Byte Array back into a Byte Array

I have an application that makes a call to a third party web API that returns a String that looks something like this:
"JVBERi0xLjMNCiXi48/TDQoxIDAgb2JqDQo8PA0KL1R5cGUgL091dGxpbmVzDQovQ291bnQgMA0KPj4NCmVuZG9iag0KMiAwIG9iag0KDQpbL1BERiAvVGV4dCAvSW1hZ2VDXQ0KZW"
(It's actually much longer than that but I'm hoping just the small snippet is enough to recognize it without me pasting a string a mile long)
The documentation says it returns a Byte array but when I try to accept it as a Byte array directly, I get errors. Part of my problem here is that the documentation isn't completely clear what the Byte array represents. Since it's a GetReport function I'm calling, I'm guessing it's a PDF but I'm not 100% sure as the documentation doesn't say at all.
So, anyway, I'm getting this String and I'm trying to convert it to a PDF. Here's what that looks like:
Dim reportString As String = GetValuationReport(12345, token.SecurityToken)
Dim report As Byte() = System.Text.Encoding.Unicode.GetBytes(reportString)
File.WriteAllBytes("C:\filepath\myreport.pdf", report)
I'm pretty sure that the middle line converts the String into a new Byte array rather than simply converting it into its Byte array equivalent but I don't know how to do that.
Any help would be fantastic. Thanks!
It looks like your string may be Base64 encoded, in which case you would use this to convert it to bytes:
Dim report As Byte() = Convert.FromBase64String(reportString)

VB.NET - Converting MP3 to Base64-String

I'm trying to find a way to store mp3-sounds in text-files. My plan was to convert the original mp3-file into a base64-string and then save it.
I spent a lot of time asking Google but could only find a way to convert the base64-string back to mp3.
Is this even possible? I am also open for other solutions, I do only have to be able to convert the files to text and then back to mp3-format. I am using Visual Basic .NET, but I think C# could help me out as well.
Use the Convert.ToBase64String method to convert a byte array to a base64 string:
' load file into a byte array
Dim data As Byte() = File.ReadAllBytes(filename)
' convert the byte array to base64
Dim str As String = Convert.ToBase64String(data)
' write the string to a file
File.WriteAllText(newFilename, str)

Read a matrix from a binary file

I'm trying to read two matrix from a binary file (256x256x2) but couldn't do it without iterating 256x256x2 times which takes too long. For now I just want to check the data and make sure it's corect (not only zeros). This is what I have:
Dim msg As String
Dim b(256 * 256 * 2) As Byte
Dim i As Int32
Dim reader As New BinaryReader(File.Open(path, FileMode.Open))
b = reader.ReadBytes(b.Length)
For i = 0 To b.Length
msg = msg & ", " & b(i)
Next
TextBox1.Text = msg
The data on the matrix are just numbers (0-255).
What's the best way to save the data to an array, if possible with the format
array[matrixno][row][column]
because later I will need to find specific values of the array based on its position.
PS. I'm using the old Visual Studio 2003 because that's what I have available.
Thanks
Edit:
Figured out what was taking long was actually displaying all the bytes, problem solved!
Almost two years later, it's time to take this off the unanswered list.
The loop worked just fine, the problem was printing every single value read instead of simpling saving it to a variable.
Lesson learned (long ago): Printing takes time.

Serialize/Deserialize two-dimensional array

For some reason my previous question was considered too vague. So let me be more specific.
I have a 2 dimensional array of type single.
I want to serialize it to save in an Access database.
The suggestion was to save it as a Memo field which is fine.
I want to later read the Memo field and deserialize it to retrieve the original array.
I have searched extensively on the web and here and can not find the answer. I believe I am serializing the array correctly but do not know how to deserialize it.
This code appears to work for serializing but I can not figure out how to deserialize:
Dim f As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms As New MemoryStream
f.Serialize(ms, arLHS)
Dim byArr As Byte() = ms.ToArray
I then save byArr to the Memo field.
Please provide sample code.
You can deserialize it via base64 converter:
Dim str_b64 As String = Convert.ToBase64String(byArr)
Dim ms2 As New MemoryStream(Convert.FromBase64String(str_b64))
Dim intArr2(,) As Int32 = f.Deserialize(ms2)
This may look somewhat awkward, but it works - tested in a console app in VS 2010.
Credit goes here. Through this link, you can also find the full version of the code to play with.
I changed the data type of the Access field from Memo to OLE Object and that seems to work. When I look at the data in Access it tells me the field is "Long binary data" and I was able to use the following code after reading the record from Access:
Dim f As New System.Runtime.Serialization.Formatters.BinaryFormatter
Dim byArr As Byte()
byArr = DirectCast(dtLHS.Rows(0).Item("LHS"), Byte())
Dim theArrayAsString As String = Convert.ToBase64String(byArr)
Dim ms2 As New MemoryStream(Convert.FromBase64String(theArrayAsString))
Dim newLHS(,) as single = f.Deserialize(ms2)
Is this correct?

Copy byte array in VB.NET

I am retrieving a byte blob from an SQLite database/record set. I am not experienced with garbage collection yet.
When I say:
Dim bt() As Byte
bt = r.fields("mybyteblob").value
... is that okay or unsafe?
I would like to make a copy of the byte array in the record set field, and I am not sure if I am simply referencing the byte array here instead of copying it.
In your code you are only referencing the byte array.
If you want to copy it you need
Dim bt() As Byte
if r.fields("mybyteblob").Value Is not Nothing then
dim lenArray = r.fields("mybyteblob").Length
bt = new Byte(lenArray)
Array.Copy(r.fields("mybyteblob").value, bt, lenArray)
end if
There is another alternative.
The Buffer class is faster than Array and more appropriate because you are using a byte array
Dim bt() As Byte
if r.fields("mybyteblob").Value Is not Nothing then
dim lenArray = r.fields("mybyteblob").Length
bt = new Byte(lenArray)
Buffer.BlockCopy(r.fields("mybyteblob").value, 0, bt, 0, lenArray)
end if
Here a good question on the two methods
It is very unusual to run into garbage collection problems if you only write managed code (i.e. no P/Invoke).
Many smart people has put a lot of effort into making garbage collection work without you having to worry about it, so do just that: don't worry about it. Just write your code, and if you run into a specific behavior you don't understand, then ask about that particular behavior (and I can assure you that in 99.9967% [1] of the cases it will not be the garbage collector).
[1] This is not a random number. I've ran into a garbage collection gotcha once in ~10 years of programming. Assuming 10 bugs a day and 300 days of work per year, that makes 29999/30000 bugs which are not garbage-collection related = 99.9967%.