Program fixed functions that does not need to be initialized - vb.net

I have written a function to extract a recieved token from a "xx":"..." format
Public Class HelperFunctions
Public Function ExtractToken(ByVal myToken As String) As String
'Split fields on comma
Dim fields = myToken.Split(":")
'Quote literal
Dim quote = """"c
'Use trim to remove quotes
Dim value = fields(2).Trim(quote)
Return value
End Function
End Class
But instead of initializing the function
Dim hc as New HelperFunctions
hc.ExtractToken(_string)
I want to use it straight forward
HelperFunctions.ExtractToken(_string)
I have not programmed for a while and cannot figure it out as well as come up with the name of this type of functions to find a tutorial.

You need to declare the Function as Shared:
Public Class HelperFunctions
Public Shared Function ExtractToken(ByVal myToken As String) As String
'Split fields on comma
Dim fields = myToken.Split(":")
'Quote literal
Dim quote = """"c
'Use trim to remove quotes
Dim value = fields(2).Trim(quote)
Return value
End Function
End Class
Or as #jmcilhinney said, you can use Module and you don't need to use Shared in the methods inside it (also you can't create an instance of an object from a Module):
Public Module HelperFunctions
Public Function ExtractToken(ByVal myToken As String) As String
'Split fields on comma
Dim fields = myToken.Split(":")
'Quote literal
Dim quote = """"c
'Use trim to remove quotes
Dim value = fields(2).Trim(quote)
Return value
End Function
End Module

Related

Replacing character in a text file with comma delimited

I have a comma delimited file with sample values :
1,1076103,22-NOV-16,21051169,50,1083,AAA,TEXT
Question : how to replace the comma in the last column which is "AAA,TEXT"
The result should be this way:
1,1076103,22-NOV-16,21051169,50,1083,AAATEXT
There is an overload of String.Split which takes an argument telling it the maximum number of parts to return. You could use it like this:
Option Infer On
Option Strict On
Module Module1
'TODO: think up a good name for this function
Function X(s As String) As String
Dim nReturnParts = 7
Dim parts = s.Split({","c}, nReturnParts)
If parts.Count < nReturnParts Then
Throw New ArgumentException($"Not enough parts - needs {nReturnParts}.")
End If
parts(nReturnParts - 1) = parts(nReturnParts - 1).Replace(",", "")
Return String.Join(",", parts)
End Function
Sub Main()
Dim s() = {"1,1076103,22-NOV-16,21051169,50,1083,AAA,TEXT",
"1,1076103,22-NOV-16,21051169,50,1083,BBBTEXT",
"1,1076103,22-NOV-16,21051169,50,1083,C,C,C,TEXT"}
For Each a In s
Console.WriteLine(X(a))
Next
Console.ReadLine()
End Sub
End Module
Outputs:
1,1076103,22-NOV-16,21051169,50,1083,AAATEXT
1,1076103,22-NOV-16,21051169,50,1083,BBBTEXT
1,1076103,22-NOV-16,21051169,50,1083,CCCTEXT
Is simple, but learn a bit how to use string ;)
Public Function MDP(strWork As String)
Dim splitted() As String = strWork.Split(","c)
Dim firsts As New List(Of String)
For i As Integer = 0 To splitted.Count - 3
firsts.Add(splitted(i))
Next
Dim result As String = System.String.Join(",", firsts)
Return result & "," & splitted(splitted.Count - 2) & splitted(splitted.Count - 1)
End Function
Then call with:
Dim finished As String = MDP("1,1076103,22-NOV-16,21051169,50,1083,AAA,TEXT")

Reference Variable names as strings

I am trying to reference the name of a variable as a string. I have a list of global variables
Public gvHeight As String = Blank
Public gvWeight As String = Blank
Public gvAge As String = Blank
I need to reference the name of the variables for an external API call. I am trying to avoid specific code per variable, instead allow me to add a new variable and everything reference correctly. I already have the rest of the code to deal with the name as a string.
example:
public Height as string
public weight as string
public age as string
[elsewhere in code]
for each var as string in {public variables}
CallToAPI(var.name) 'needs to send "height" "weight" or "age" but there are a lot so hardcoding is not a good solution
edited for example
You need to find the public fields through Reflection.
Having an example dll compiled from this source-code:
Public Class Class1
Public Field1 As String = "value 1"
Public Field2 As String = "value 2"
Public Field3 As Integer
End Class
Then you could do this:
' The library path.
Dim libpath As String = "...\ClassLibrary1.dll"
' The assembly.
Dim ass As Assembly = Assembly.LoadFile(libpath)
' The Class1 type. (full namespace is required)
Dim t As Type = ass.GetType("ClassLibrary1.Class1", throwOnError:=True)
' The public String fields in Class1.
Dim strFields As FieldInfo() =
(From f As FieldInfo In t.GetFields(BindingFlags.Instance Or BindingFlags.Public)
Where f.FieldType Is GetType(String)
).ToArray
' A simple iteration over the fields to print their names.
For Each field As FieldInfo In strFields
Console.WriteLine(field.Name)
Next strField
If all your variables are of the same type (here strings), you can use a Dictionary...
Public MyModule
Private myVars As Dictionary(Of String, String)
Public Function CallToAPI(VarName As String) As String
If myVars.ContainsKey(VarName) Then
Return myVars(VarName)
End If
Return ""
End Function
End Module
And somewhere else in your external code
Module TestModule
Public Sub Test()
Dim myVar = MyModule.CallToAPI("test")
End Sub
End Module
Now if your variables aren't the same, then you must use Reflection... and that's where the fun begins...

How to output data from Structure to CSV using StringBuilder

I have data in the following structure:
Structure student
Dim stdntpass As String
Dim fname As String
Dim sname As String
Dim age As Byte
Dim year As Integer
Dim stdntuser As String
End Structure
I need to take the data in that structure and output it to CSV. I was planning on using a StringBuilder object to do it, but I can't figure out how to give the structure to the StringBuilder.
Here is a function that uses reflection to determine what fields exist in the student structure:
Public Function StudentsToCSV(students As IEnumerable(Of student)) As String
Const separator As Char = ";"c
Dim sb As New StringBuilder
'Get the data elements
Dim studentFields = GetType(student).GetFields()
'Output headline (may be removed)
For Each field In studentFields
sb.Append(field.Name)
sb.Append(separator)
Next
sb.AppendLine("")
'Write a line for each student
For Each s In students
'Write the value of each field
For Each field In studentFields
Dim value As String = Convert.ToString(field.GetValue(s))
sb.Append(value)
'... followed by the separator
sb.Append(separator)
Next
sb.AppendLine("")
Next
Return sb.ToString()
End Function
You can pass any set of students to this function - may it be an array, a List(Of student) or whatever.
One way is to override the ToString function. now passing a whole object to a stringbuilder or even sending the Tostring function to the file will pass the values how you want them:
Structure student
Dim stdntpass As String
Dim fname As String
Dim sname As String
Dim age As Byte
Dim year As Integer
Dim stdntuser As String
Public Overrides Function ToString() As String
Return Join({stdntpass, fname, sname, age.ToString, year.ToString, stdntuser}, ","c) + vbNewLine
End Function
End Structure
The StringBuilder has no way to take a whole Structure and automatically append each of the properties from that Structure. If you must use a StringBuilder, you could do it like this:
builder.Append(s.stdntpass)
builder.Append(",")
builder.Append(s.fname)
builder.Append(",")
builder.Append(s.sname)
builder.Append(",")
builder.Append(s.age)
builder.Append(",")
builder.Append(s.year)
builder.Append(",")
builder.Append(s.stdntuser)
Dim csvLine As String = builder.ToString()
However, it would be easier to use the String.Join method, like this:
Dim csvLine As String = String.Join(",", s.stdntpass, s.fname, s.sname, s.age, s.year, s.stdntuser)
You could use reflection to dynamically get the list of properties from the structure, but then you won't have much control over the order in which the fields get appended without using attributes, or something, which could get ugly.
In any case, you should be careful, though, that values are properly escaped. If any of the strings in your structure contain commas, you need to surround that field with quotation marks. And if any of those strings quotation marks, they need to be doubled. You could fix the values with a method like this:
Public Function EscapeValueForCsv(value As String) As String
Return """" & value.Replace("""", """""") & """"
End Function
Then you could call that on each of the properties before passing it to String.Join:
Dim csvLine As String = String.Join _
(
",",
EscapeValueForCsv(s.stdntpass),
EscapeValueForCsv(s.fname),
EscapeValueForCsv(s.sname),
EscapeValueForCsv(s.age.ToString()),
EscapeValueForCsv(s.year.ToString()),
EscapeValueForCsv(s.stdntuser)
)

Converting Fixed length statement from VB6 to VB.Net

We perform a protocol based data sending to device where the device requires a formatted data packets.
the sample packet data is XXFSXXXFSXXXXXXXFSXXXXXX. The X mentioned is the max length size of each string. if data is less than string max length it should be filled with NULL character like ..11FS123FS1234XXXX (the remaining X will be filled with NULL).
I am just trying to convert one of VB6 function to VB.Net and below is the converted statement where i am facing issue
Option Strict Off
Option Explicit On
Imports Microsoft.VisualBasic.Compatibility.VB6
Imports System
Imports System.Runtime.InteropServices
Module FunctionCmd_Msg
Public FunCommand_Msg As Fun_CommandMessage = Fun_CommandMessage.CreateInstance()
'Function Command Message
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ _
Public Structure Fun_CommandMessage
<VBFixedString(1)> Public one As String
<VBFixedString(1)> Public two As String
<VBFixedString(3)> Public three As String
Dim five As String
<VBFixedString(8)> Public four As String
Public Shared Function CreateInstance() As Fun_CommandMessage
Dim result As New Fun_CommandMessage
result.one = String.Empty
result.two = String.Empty
result.three = String.Empty
result.four = String.Empty
result.five = String.Empty
End Function
End Structure
End Module
assuming:
one = "1"
two = "1"
three = "123"
four = "5678"
five = "testing"
FS = character (field separator)
on concatenating the strings i need a fixed length string such like this:
one & two & FS & three & FS & five & FS & four
output: since four is a fixed length string of 8 length remaining 4 characters should be filled with null as below
11 FS 123 FS testing FS 5678XXXX
Fixed-length strings simply make no sense in .NET any more. Microsoft tried to provide a similar class for easier upgrade but the truth is that you should change your code depending on usage:
What did the fixed-length string do in your VB6 code? Was it for no good reason? Then use a normal String in .NET.
Was it for interop with a C API? Then use marshalling to set a size for an array in the C API call.
Just forget about the fixed length, and use regular vb.net strings. They will return fine to whatever calls that code, including interop.
So, just pad your strings, and you off to the races.
In fact, build a Msg class that does the dirty work for you.
This looks quite nice to me:
NOTE how I set this up that you ONLY define the length of the string in ONE place. (so I use len(m_string) to determine the length from THEN on in the code.
Also, for debug and this example, in place of vbcharNull (which you should use), I used X for testing.
Now, in your code?
Just use this:
Dim Msg As New MyMsg
With Msg
.one = "A"
.two = "B"
.three = "C"
.four = "D"
.Five = "E"
End With
Debug.WriteLine(Msg.Msg("*") & vbCrLf)
Debug.WriteLine("total lenght = " & Len(Msg.Msg("X").ToString))
Output:
A*B*CXX*EXXXXXXX*DXXXXXXX
total lenght = 25
I note in your code that you have FIVE before FOUR - but if that is what you want, then no problem
Note that the class ALWAYS maintains the lengths for you.
So just paste this code into your module or even a new separate class.
Public Class MyMsg
'Dim cPad As Char = vbNullChar
Dim cPad As Char = "X"
Private m_one As String = New String(cPad, 1)
Private m_two As String = New String(cPad, 1)
Private m_three As String = New String(cPad, 3)
Private m_four As String = New String(cPad, 8)
Private m_five As String = New String(cPad, 8)
Public Property one As String
Get
Return m_one
End Get
Set(value As String)
m_one = MyPad(value, m_one)
End Set
End Property
Public Property two As String
Get
Return m_two
End Get
Set(value As String)
m_two = MyPad(value, m_two)
End Set
End Property
Public Property three As String
Get
Return m_three
End Get
Set(value As String)
m_three = MyPad(value, m_three)
End Set
End Property
Public Property four As String
Get
Return m_four
End Get
Set(value As String)
m_four = MyPad(value, m_four)
End Set
End Property
Public Property Five As String
Get
Return m_five
End Get
Set(value As String)
m_five = MyPad(value, m_five)
End Set
End Property
Public Function Msg(FS As String) As String
Return m_one & FS & m_two & FS & m_three & FS & m_five & FS & m_four
End Function
Private Function MyPad(str As String, strV As String) As String
Return Strings.Left(str & New String(Me.cPad, Len(strV)), Len(strV))
End Function
End Class
As noted, change the commented out line of "X" for the char back to vbCharNull.
And of course you STILL get to choose the delimiter. I used
Msg.Msg("*")
so I used a "*", but you can use space, or anything you want.

VB.NET - Remove a characters from a String

I have this string:
Dim stringToCleanUp As String = "bon;jour"
Dim characterToRemove As String = ";"
I want a function who removes the ';' character like this:
Function RemoveCharacter(ByVal stringToCleanUp, ByVal characterToRemove)
...
End Function
What would be the function ?
ANSWER:
Dim cleanString As String = Replace(stringToCleanUp, characterToRemove, "")
Great, Thanks!
The String class has a Replace method that will do that.
Dim clean as String
clean = myString.Replace(",", "")
Function RemoveCharacter(ByVal stringToCleanUp, ByVal characterToRemove)
' replace the target with nothing
' Replace() returns a new String and does not modify the current one
Return stringToCleanUp.Replace(characterToRemove, "")
End Function
Here's more information about VB's Replace function
The string class's Replace method can also be used to remove multiple characters from a string:
Dim newstring As String
newstring = oldstring.Replace(",", "").Replace(";", "")
You can use the string.replace method
string.replace("character to be removed", "character to be replaced with")
Dim strName As String
strName.Replace("[", "")