understanding VB code - vb.net

i m working on translating code from VB to C#, though there are lots of great conversion websites, i still find the code ambiguous to me, since the documentation is really poor it approaches to useless, i thought about posting it here to see if i can get it clearer.
i need some elaboration on the code given below, and whats the use of the Buffer[] in the method below:
Function hexToBin(ByVal str As String, ByRef Buffer() As Byte)
Dim strRemain As String
Dim firstChar As Boolean
Dim i, count, inputLen, remainLen As Integer
i = 0
count = 0
firstChar = True
strRemain = str
While Len(strRemain) > 0
If Mid(strRemain, 1, 1) = " " Then
firstChar = True
strRemain = Mid(strRemain, 2)
ElseIf firstChar = True Then
If Len(strRemain) = 1 Then
Buffer(count) = myVal(strRemain)
ElseIf Len(strRemain) >= 2 Then
Buffer(count) = myVal(Mid(strRemain, 1, 1)) * 16 + myVal(Mid(strRemain, 2, 1))
strRemain = Mid(strRemain, 3)
End If
count = count + 1
firstChar = False
Else
strRemain = Mid(strRemain, 2)
End If
Wend
hexToBin = count
End Function
see, i know this code converts from hex to binary as the name suggests, yet i cant really figure the use of the Buffer[] in the context, i looked up the Mid function in string VB, but still can't figure out the use of the Buffer[] in this function, i would appreciate if someone explained the use of the buffer.

In the code above, the parentheses are used to access elements of an array. So, Buffer(i) refers to the ith element of the array Buffer.
You can learn more about arrays in VB from any text book, or indeed from MSDN: http://msdn.microsoft.com/en-us/library/wak0wfyt.aspx
As for why the array Buffer is used in the first place, well that's to store the output of the function. The function takes a hex string as input and populates the byte array Buffer with the binary equivalent.
This does seem to be rather inefficient code though. And it presents a somewhat clumsy interface because it asks the caller to allocate the array. Rather than translating it, I think I would start here: How can I convert a hex string to a byte array?

Related

Is there a VB function to convert 32 bit float to little endian hex

As shown here: https://gregstoll.com/~gregstoll/floattohex/
I need to convert a 32 bit float to a little endian hex (click the swap endiness button before converting). I've managed to do this in python by converting to big endian then reordering, but I have no idea how to approach this issue in VB as I'm entirely new to the language. Using the Hex inbuilt function returns 19a, which i assume means its not correctly evaluating my input as a single.
I've found a recommended solution here but cant get it working:
https://www.tek-tips.com/faqs.cfm?fid=6404
Any suggestions would be great, thanks in advance.
There are a number of ways you could do this - the most obvious being the Copy Memory API. Some time ago, a pretty neat solution was published here: Extracting bits from a float in vba which avoided the need for the API
Basically, you'd just need a couple of short functions:
Option Explicit
Type SingleType
Value As Single
End Type
Type FourBytesType
Value(3) As Byte
End Type
Private Function SingleToBytes(f As Single) As Variant
Dim sngType As SingleType
Dim bytesType As FourBytesType
sngType.Value = f
LSet bytesType = sngType
SingleToBytes = bytesType.Value
End Function
Private Function BytesToHex(bytes As Variant) As String
Dim result As String
Dim i As Long
For i = LBound(bytes) To UBound(bytes)
result = result & IIf(bytes(i) < 16, "0", "") & Hex(bytes(i))
Next
BytesToHex = result
End Function
If you wanted to test Endianness and reverse the array, then something like the following, which kind of uses a Byte Order Mark, could be added. I haven't tested it on a big-endian processor but I think it'd work:
Private Function IsLittleEndianProcessor() As Boolean
Const BOM As Single = 1
Const MSB As Byte = 63
Dim bytes() As Byte
Dim n As Long
bytes = SingleToBytes(BOM)
n = UBound(bytes)
IsLittleEndianProcessor = (bytes(n) = MSB)
End Function
Private Function ChangeEndianness(bytes As Variant) As Variant
Dim result() As Byte
Dim n As Long, m As Long
ReDim result(UBound(bytes))
m = UBound(bytes)
For n = LBound(bytes) To UBound(bytes)
result(m) = bytes(n)
m = m - 1
Next
ChangeEndianness = result
End Function
I'm not actually sure how you want the hex string displayed but you could step backwards through the array to write the hex if needed. Sample test would be:
Public Sub TestMe()
Dim bytes As Variant
Dim output As String
bytes = SingleToBytes(3.1415)
If Not IsLittleEndianProcessor Then
bytes = ChangeEndianness(bytes)
End If
output = BytesToHex(bytes)
Debug.Print output
End Sub

How to convert a string expression to vb code?

I have a string output from user interface as below,
strFormula ="gridControlName.Rows(i).cells("C1").value *
gridControlName.Rows(i).cells("C2").value"
if i write code like
dblRes=gridControlName.Rows(i).cells("C1").value *
gridControlName.Rows(i).cells("C2").value
it will give result.. but since its a string i could not get result
How can I remove the double quotes from the above string and get the values entered in the grid cells to be multiplied?
I don't think there's an 'easy' way to do this, since VB.Net doesn't have an "eval()" like some other languages. However, it does support run-time compilation. Here are a couple articles which may help you:
Using .NET Languages to make your Application Scriptable (VB.Net example)
Runtime Compilation (A .NET eval statement) (C# example)
Both are intended to be a bit more robust than just executing single lines of code, allowing users to input entire textboxes of their own code for example, but should give you some direction. Both include sample projects.
Hi guys thanks for your updates.. I wrote my own function by using your concepts and some other code snippets .I am posting the result
Function generate(ByVal alg As String, ByVal intRow As Integer) As String Dim algSplit As String() = alg.Split(" "c)
For index As Int32 = 0 To algSplit.Length - 1
'algSplit(index) = algSplit(index).Replace("#"c, "Number")
If algSplit(index).Contains("[") Then
Dim i As Integer = algSplit(index).IndexOf("[")
Dim f As String = algSplit(index).Substring(i + 1, algSplit(index).IndexOf("]", i + 1) - i - 1)
Dim grdCell As Infragistics.Win.UltraWinGrid.UltraGridCell = dgExcelEstimate.Rows(intRow).Cells(f)
Dim dblVal As Double = grdCell.Value
algSplit(index) = dblVal
End If
Next
Dim result As String = String.Join("", algSplit)
'Dim dblRes As Double = Convert.ToDouble(result)
Return result
End Function
Thanks again every one.. expecting same in future

Convert string from Base2 to Base4

I wish to convert text to base 4 (AGCT), by first converting it to binary (I've done this bit) and then break it into 2 bit pairs.
can someone help me turn this into code using vb.net syntax?
if (length of binary String is an odd number) add a zero to the front (leftmost position) of the String. Create an empty String to add translated digits to. While the original String of binary is not empty { Translate the first two digits only of the binary String into a base-4 digit, and add this digit to the end (rightmost) index of the new String. After this, remove the same two digits from the binary string and repeat if it is not empty. }
in this context:
Dim Base2Convert As String = ""
For Each C As Char In Result.Text
Dim s As String = System.Convert.ToString(AscW(C), 2).PadLeft(8, "0")
Base2Convert &= s
Next
Result.Text = Base2Convert
Dim Base4Convert As String = ""
For Each C As Char In Result.Text
'//<ADD THE STATEMENT ABOVE AS CODE HERE>//
Base4Convert &= s
Next
Result.Text = Base4Convert
.NET does not support conversion to non-standard base, such as 4, so this will not work:
Dim base4number As String = Convert.ToString(base10number, 4)
From MSDN:
[...] base of the return value [...] must be 2, 8, 10, or 16.
But you can write your own conversion function, or take the existing one off the web:
Public Function IntToStringFast(value As Integer, baseChars As Char()) As String
Dim i As Integer = 32
Dim buffer(i - 1) As Char
Dim targetBase As Integer = baseChars.Length
Do
buffer(System.Threading.Interlocked.Decrement(i)) =
baseChars(value Mod targetBase)
value = value \ targetBase
Loop While value > 0
Dim result As Char() = New Char(32 - i - 1) {}
Array.Copy(buffer, i, result, 0, 32 - i)
Return New String(result)
End Function
Used this answer. Converted with developer fusion from C# + minor adjustments. Example:
Dim base2number As String = "11110" 'Decimal 30
Dim base10number As Integer = Convert.ToInt32(base2number, 2)
Dim base4number As String = IntToStringFast(base10number, "0123")
Console.WriteLine(base4number) 'outputs 132
Notice that you don't need base 2 there as an intermediate value, you can convert directly from base 10. If in doubt, whether it worked correctly or not, here is a useful resource:
Number base converter
Converting the number to base first and then to base 4 doesn’t make a lot of sense, since directly converting to base 4 is the same algorithm anyway. In fact, representation of a number in any base requires the same general algorithm:
Public Shared Function Representation(number As Integer, digits As String) As String
Dim result = ""
Dim b = digits.Length
Do
result = digits(number Mod b) & result
number \= b
Loop While number > 0
Return result
End Function
Now you can verify that Representation(i, decimal) does the same as i.ToString():
Dim decimalDigits = "0123456789"
For i = 0 To 30 Step 3
Console.WriteLine("{0}, {1}", i.ToString(), Representation(i, decimalDigits))
Next
It’s worth noting that i.ToString() converts i to decimal base because this is the base we, humans, are mostly using. But there is nothing special about decimal, and in fact internally, i is not a decimal number: its representation in computer memory is binary.
For conversion to any other base, just pass a different set of digits to the method. In your case, that’d be "ACGT":
Console.WriteLine(Representation(i, "ACGT"))
Hexadecimal also works:
Console.WriteLine(Representation(i, "0123456789ABCDEF"))
And, just to repeat it because it’s such a nice mathematical property: so does any other base with at least two distinct digits.

Understanding assignment/comparison vb.net

This is my first time on Stack Overflow and I am trying to understand what '=' means in the last line of this code:
Dim label As Label = Me.labels.Item(String.Concat(New Object() { movimiento.Sector1.ID, "-", movimiento.X1, "-", movimiento.Y1 }))
Dim dictionary As Dictionary(Of Label, Integer)
Dim label3 As Label
dictionary = Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
Any kind of help will be welcome, thanks in advance!
The equals sign (=) is used for two entirely different operators in VB.NET. It is used as the assignment operator as well as for the equality test operator. The operator, to which the character evaluates, depends on the context. So, for instance, in this example:
Dim x As Integer = 1
Dim y As Integer = 2
Dim z As Integer = x = y
You might think, as in other languages, such as C#, that after executing that code, x, y, and z would all equal 2. However, VB treats the second equals sign as an equality test operator. Therefore, in actuality, it's doing this:
If x = y Then
z = True
Else
z = False
End If
You'll notice, though, that we are then trying to assign a boolean value to an integer variable. If you have Option Strict On (as you should), it would not allow you to do that. If that's really what you wanted to do, it would force you to cast it to an integer, which makes it slightly more obvious:
z = CInt(x = y)
However, it's still confusing, so typically, this kind of thing is discouraged in VB.NET. So, I suspect that the code you posted wouldn't even compile if Option Strict was turned on. But, this is what it's actually trying to do:
Dim temp1 As Boolean = (label3 = label) ' Evaluates to False
Dim temp2 As Boolean = (Me.demandas2.Item(temp1) = (dictionary.Item(label3) - 1)) ' Likely evaluates to False
dictionary = temp2 ' Couldn't possibly be a valid assignment
Let's look at this line of code:
dictionary = Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
The first = is an assignment. So we assign the right part to the dictionary. Now for the right part:
Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
The = between the two expressions is a comparison, so it returns a Boolean. So the supposed "dictionary" is assigned a boolean value. If we check the left part of that expression:
Me.demandas2.Item(label3 = label)
Once again, the = sign here is doing a comparison, so if label3 is the same as label, then the code would be equivalent to Me.semandas2.Item(True). This seems strange.
Overall, this code doesn't make much sense, and I'd be surprised if it compiled, considering it tries to assign a boolean to a dictionary. It certainly wouldn't compile with Option Strict On.
Thanks a lot, everyone. The snippet was result of decompile a dll. I was trying to help a partner.
.Net reflector decompiled based on VB.Net code, that was a mistake.
Finally we see that first it should decompile using C# code, that gives a complete different meaning to the code:
if (movimiento.Contenedor.Demanda2)
{
Dictionary<Label, int> dictionary;
Label label3;
(dictionary = this.demandas2)[label3 = label] = dictionary[label3] - 1;
if (this.demandas2[label] == 0)
{
label.ForeColor = Color.Black;
}
(dictionary = this.demandas2)[label3 = label2] = dictionary[label3] + 1;
label2.ForeColor = Color.DarkOrange;
}

mid()=foo in VBS?

In VBA and VB6 I can assign something to mid for Example mid(str,1,1)="A" in VBS this doesn't work.
I need this because String concatenation is freakin' slow
Here is the actual code i hacked together real quick
Function fastXMLencode(str)
Dim strlen
strlen = Len(str)
Dim buf
Dim varptr
Dim i
Dim j
Dim charlen
varptr = 1
buf = Space(strlen * 7)
Dim char
For i = 1 To strlen
char = CStr(Asc(Mid(str, i, 1)))
charlen = Len(char)
Mid(buf, varptr, 2) = "&#"
varptr = varptr + 2
Mid(buf, varptr, charlen) = char
varptr = varptr + charlen
Mid(buf, varptr, 1) = ";"
varptr = varptr + 1
Next
fastXMLencode = Trim(buf)
End Function
How can i get this to work in VBS?
Authoritative source explicitly stating it's not available in VBScript:
Visual Basic for Applications Features Not In VBScript:
Strings: Fixed-length strings LSet, RSet Mid Statement StrConv
VBA has both a Mid Statement and a Mid Function. VBScript only has the Mid Function.
The one other option you have if you are stuck doing this in VBScript is to make API calls. Since you are already comfortable working directly with the string buffer this might not be too big a jump for you. This page should get you started: String Functions
Sorry, it looks like API calls are out, too: Rube Goldberg Memorial Scripting Page: Direct API Calls Unless you want to write an ActiveX wrapper for your calls, but we're starting to get into an awful lot of work (and additional maintenance requirements) now.
You can't do that. You will have to rebuild the string from scratch.
This is not possible, mid(str,1,1) is a function which just returns a number (str is not passed 'by reference' and is not altered).
It's never too late to suggest an answer, even to a decade-old question...
One great thing about VBScript is that even though it's a subset of VB/VBA it still lets you declare (and use) classes. And having classes implies them having properties, with getters and/or setters... if you can guess where I'm going...
So if you wrap a class around a VBA-compatible implementation of Mid(), it's actually possible to emulate Mid() statements with a Let property. Consider the following code:
Class CVBACompat
' VB6/VBA-Like Mid() Statement
Public Property Let LetMid(ByRef Expression, ByVal StartPos, ByVal Length, ByRef NewValue) ' ( As String, As Long, As Long, As String)
Dim sInsert ' As String
sInsert = Mid(NewValue, 1, Length)
Expression = Mid(Expression, 1, StartPos - 1) & sInsert & Mid(Expression, StartPos + Len(sInsert))
End Property
' VB6/VBA-Like IIf() Function
Public Function IIf(Expression, TruePart, FalsePart)
If CBool(Expression) Then
IIf = TruePart
Else
IIf = FalsePart
End If
End Function
End Class: Public VBACompat: Set VBACompat = New CVBACompat: Public Function IIf(X, Y, Z): IIf = VBACompat.IIf(X, Y, Z): End Function
VBA's language specification says that when Mid( <string-expression>, <start> [, <length> ] ) is used as a statement, what's to be replaced in the source string <string-expression> is the lowest number of characters given the entire RHS expression or as limited by the <lenght> argument, when provided. Now, you can't have optional arguments in VBScript, so if you want to be able to also use statements of the sort Mid( <string-expression>, <start> ) = <expression> you'll have to have two separate implementations.
The implementation proposed above can be checked with the following code (not including checks for error-throwing conditions, which are the same as for the Mid() function anyway) :
Dim f ' As String
Dim g ' As String
f = "1234567890"
g = f
' VB6 / VBA: Mid(f, 5, 2) = "abc"
VBACompat.LetMid(f, 5, 2) = "abc"
' VB6 / VBA: Mid(g, 5, 4) = "abc"
VBACompat.LetMid(g, 5, 4) = "abc"
WScript.Echo "First call " & IIf(f = "1234ab7890", "passes", "fails")
WScript.Echo "Second call " & IIf(g = "1234abc890", "passes", "fails")
In any case, since the proposed solution is just an emulation of otherwise native code implementations (in VB6, VBA), and still implies string concatenation anyway with the overhead of class instantiation + VTable translations, the OP'd be better off creating and making available an ActiveX component (OCX) to do concatenations in series.