How to update Format function from VB to VB.NET - vb.net

I am trying to port a VB function to VB.NET, but I cannot get the function to work correctly and update properly.
rFormat = Format(Format(Value, fmt), String$(Len(fmt), "#"))
It seems like the problem lies with the String$() function parameter which is used to align decimal points of values. How would I be able to properly fix this, or is there another way to achieve this?
EDIT
The following is an example console application that shows the issues that I am having.
Imports Microsoft.VisualBasic
Module Module1
Sub Main()
Dim rFormat As String
Dim fmt As String
Dim value As Object
fmt = "########.000"
value = 12345.2451212
'value = 12345
'~~~~~~~~~~~~~~~~~~~~~
'rFormat = Microsoft.VisualBasic.Format(Microsoft.VisualBasic.Format(value, fmt), "".PadLeft(fmt.Length, "#"c))
'Console.WriteLine(rFormat) ' <<Not working prints all "#" for any value!>>>
'rFormat = Microsoft.VisualBasic.Format(Microsoft.VisualBasic.Format(value, fmt), "".PadLeft(fmt.Length))
'Console.WriteLine(rFormat) '<<Not working prints nothing>>
'rFormat = (String.Format(value, fmt)).PadLeft(Len(fmt))
'Console.WriteLine(rFormat) ' <<Not working prints the value 12345.2451212>>> should print>>>>> 12345.245
'for integer values< works good>
rFormat = String.Format("{0," + fmt.Length.ToString + "}", String.Format(value, fmt))
Console.WriteLine(rFormat) ' <<Not working prints the value 12345.2451212>>> should print>>>>> 12345.245
'for integer values< works good>
End Sub
End Module

All String$ does is repeat the character specified in the second parameter the number of times specified in the first parameter.
So if fmt is, for example "9999", then the String$ command will produce "####".
You can replace this with the String.PadLeft method and continue to use the VB Format function from the Microsoft.VisualBasic namespace:
rFormat = Microsoft.VisualBasic.Format(Microsoft.VisualBasic.Format(value, fmt), "".PadLeft(fmt.Length, "#"c))
EDIT:
Based on the edit in the question, the correct format logic should be:
rFormat = String.Format("{0:" & fmt & "}", value)
It is very helpful to review the String.Format documentation since it has a lot of examples and explanation.

It sounds like you're wanting to pad out your results so they are a fixed length. How about using the String.PadLeft Method or the String.PadLeft(int32,char) Method to Pad out rFormat.
Something like this for spaces:
rFormat = (String.Format(value, fmt)).PadLeft(Len(fmt))
Edit
Boy is it hard to find VB6 documentation online. It appears that the # in a VB6 Custom Format has to do with String justification per this Forum posting and this SO answer they suggest something something like this.
rFormat = String.Format("{0," + fmt.Length.ToString + "}", String.Format(value, fmt))
This is using the Composite Formatting Alignment Component
Alignment Component
The optional alignment component is a signed integer indicating the preferred formatted field width. If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. If padding is necessary, white space is used. The comma is required if alignment is specified.
The main issue that I see in your updated example is that you are using an object to store your Double. By changing values declaration to a Decimal and changing the format function I was able to get it to work.
Sub Main()
Dim rFormat As String
Dim fmt As String
Dim value As Double
fmt = "#######0.000"
value = 12345.2451212
rFormat = String.Format("{0," + fmt.Length.ToString + "}", value.ToString(fmt))
Console.WriteLine(rFormat)
Console.ReadLine()
End Sub

In VBNet, you can also do this:
Dim rFormat As String = String.Empty
Dim fmt As String = "########.000"
Dim value As Object = 12345.2451212
rFormat = (CDbl(value)).ToString(fmt)

Related

string modifiers and properties do not work

I am trying to use Methods and Properties of the String Class to modify a string, but I keep getting an Invalid qualifier compile error. I even copied the following code* directly from the MSDN website and it throws the same error.
Public Sub Main()
Dim original As String
original = "aaabbb"
Dim modified As String
modified = original.Insert(3, " ")
End Sub
'This is the original code, but I had to change it slightly because the word-vba
'programming environment didn't like the syntax and highlighted everything red.
'Public Sub Main()
'Dim original As String = "aaabbb"
'Console.WriteLine("The original string: '{0}'", original)
'Dim modified As String = original.Insert(3, " ")
'Console.WriteLine("The modified string: '{0}'", modified)
'End Sub
Does word-vba not support string class modifiers and properties, am I not initializing the string correctly, or is there some other problem?
modified = original.Insert(3, " ")
You're thinking in VB.NET, but writing VBA. Strings (or any primitive or UDT type) don't have members in VBA. Not your fault, finding official VBA documentation is getting harder every day, with every "VBA" search yielding results for VB.NET.
That original code is clearly VB.NET.
If you mean to concatenate 3 spaces in front of original, then what you want to do is this:
modified = String(3, " ") & original
If you mean to get a new string in which a specified string is inserted at a specified index position in this instance (MSDN), then you want to do this (thanks #A.S.H!):
modified = Left$(original, 3) & " " & Right$(original, Len(original) - 3)

Split string on parentheses and braces

Let me say, I hate working with strings! I'm trying to find a way to split a string on brackets. For example, the string is:
Hello (this is) me!
And, from this string, get an array with Hello and me. I would like to do this with parentheses and braces (not with brackets). Please note that the string is variable, so something like SubString wouldn't work.
Thanks in advance,
FWhite
You can use regular expressions (Regex), below code should exclude text inside all parenthesis and braces, also removes an exclamation mark - feel free to expand CleanUp method to filter out other punctuation symbols:
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim re As New Regex("\(.*\)|{.*}") 'anything inside parenthesis OR braces
Dim input As String = "Hello (this is) me and {that is} him!"
Dim inputParsed As String = re.Replace(input, String.Empty)
Dim reSplit As New Regex("\b") 'split by word boundary
Dim output() As String = CleanUp(reSplit.Split(inputParsed))
'output = {"Hello", "me", "and", "him"}
End Sub
Private Function CleanUp(output As String()) As String()
Dim outputFiltered As New List(Of String)
For Each v As String In output
If String.IsNullOrWhiteSpace(v) Then Continue For 'remove spaces
If v = "!" Then Continue For 'remove punctuation, feel free to expand
outputFiltered.Add(v)
Next
Return outputFiltered.ToArray
End Function
End Module
To explain the regular expression I used (\(.*\)|{.*}):
\( is just a (, parenthesis is a special symbol in Regex, needs to be escaped with a \.
.* means anything, i.e. literally any combination of characters.
| is a logical OR, so the expression will match either left or ride side of it.
{ does not need escaping, so it just goes as is.
Overall, you can read this as Find anything inside parenthesis or braces, then the code says replace the findings with an empty string, i.e. remove all occurrences. One of the interesting concepts here is understanding greedy vs lazy matching. In this particular case greedy (default) works well, but it's good to know other options.
Useful resources for working with Regex:
http://regex101.com/ - Regex test/practice/sandbox.
http://www.regular-expressions.info/ - Theory and examples.
http://www.regular-expressions.info/wordboundaries.html - How word boundaries work.
Try this code:
Dim var As String = "Hello ( me!"
Dim arr() As String = var.Split("(")
MsgBox(arr(0)) 'Display Hello
MsgBox(arr(1)) 'Display me!
Something like this should work for you:
Dim x As String = "Hello (this is) me"
Dim firstString As String = x.Substring(0, x.IndexOf("("))
Dim secondString As String = x.Substring(x.IndexOf(")") + 1)
Dim finalString = firstString & secondString
x = "Hello (this is) me"
firstString = "Hello "
secondString = " me"
finalString = "Hello me"

Fitting the full File path in a label in one line by showing dots instead of some part of file path Vb.Net

Hi Guys, I have searched for different methods for this thing but couldn't get it right. Used AutoEllipses Property, Set the MaximumSize too but to no avail. How can i get a label to show the name of the file being scanned like in the pic i attached? I mean, the label should show some part from the beginning of full path of the file then some dots and then the file name with extension.
You might consider a few things; however, the range of possibilities is too large to cover, here.
There are three (3) things you need to know in order to code this properly: the actual measured size of the filepath string you are sending to the label; the measured size of the label; and the length (in characters) of your file name. There may be a fancy function that reduces the number of things you need to do and know; however, I am not about to read oodles of documentation.
All of the above things need to be dynamic so that your label can take different String objects and render them, properly.
Dim filePath As String = ""
Dim FileDirectory As String = ""
Dim fileName As String = ""
Dim filePathLength As SizeF = 0.0
Dim labelLength As Double = 0.0
Dim fileNameLength As Integer = 0.0
' Come up with a way for measuring your string:
Dim _GraphicsUnit As Graphics = Me.CreateGraphics()
' Receive your file path, here:
' and work with your file path-related Strings:
filePath = ' SOMETHING
fileDirectory = Path.GetDirectoryName(filePath)
fileName = Path.GetFileName(filePath)
fileNameLength = fileName.Length()
' Measure the length of you path
filePathLength = _GraphicsUnit.MeasureString(filePath, INSERTFONT) * _GraphicsUnit.Inches 'or other usable unit
If filePathLength > SIZEOFLABEL Then
While filePathLength > SIZEOFLABEL
' Grab a substring of the the fileDirecory, append the "...", and keep measuring until shorter
' than SIZEOFLABEL.
' Your algorithm will need to figure out how and when to re-append the fileName
End While
End If
The above is pseudo-code and is rife with errors. The above is means to demonstrate some of the tools .Net can provide you, here namely the GraphicsUnit stuff and the Path. stuff. Both of those are helpful. You will essentially be juggling those two 'things' and the SubString() method.
My attempt is to show you how to begin to think about the problem you have in front of you so that you can begin to tackle the problem (because as the comments above state, there isn't much out there that will do what you need). Your initial question does not provide any original code on which to base the above pseudo-code; in other words, I don't feel like coding your whole project but at least want to get the answers ball rolling.
An Additional Thought: .MaxLength
The above approach is quite memory intensive - requiring a lot of repetition that may not be be necessary. Simply knowing the size - in this case the MaxLength property - might be helpful. Setting the .MaxLength property of the TextBox will allow you to know how many characters can fit in the box (you'd need to consider a few other elements, e.g. font, size, etc.).
Knowing this number, you could avoid looping altogether:
SubString of fileDirectory equal to the length of .MaxLength property, remove number of characters equating to size of fileName and "..." and append the latter two.
I got an answer to this problem here Shorten The File Path and it's a very short solution as far as code is concerned.
You can use the PathCompactPathExW pInvoke method to accomplish this:
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Program
<DllImport("shlwapi.dll", EntryPoint:="PathCompactPathExW", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Public Shared Function PathCompactPathEx(<MarshalAs(UnmanagedType.LPTStr)> pszOut As System.Text.StringBuilder, _
<MarshalAs(UnmanagedType.LPTStr)> pszSrc As String, _
cchMax As UInteger, _
reserved As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Public Shared Sub Main()
Dim longPath As String = "c:\a\very\very\long\path\that\needs\to\be\shortened\by\calling\the\PathCompactpathEx.ext"
Dim length As Integer = 40
Dim result As String = CompactPath(longPath, length)
'Prints c:\a\very\very\...\PathCompactpathEx.ext
Console.WriteLine(result)
Console.ReadLine()
End Sub
Public Shared Function CompactPath(longPathName As String, wantedLength As Integer) As String
'NOTE: You need to create the builder with the required capacity before calling function.
'See http://msdn.microsoft.com/en-us/library/aa446536.aspx
Dim sb As New StringBuilder(wantedLength + 1)
PathCompactPathEx(sb, longPathName, CUInt(wantedLength + 1), 0)
Return sb.ToString()
End Function
End Class

Lowercase the first word

Does anybody know how to lowercase the first word for each line in a textbox?
Not the first letter, the first word.
I tried like this but it doesn't work:
For Each iz As String In txtCode.Text.Substring(0, txtCode.Text.IndexOf(" "))
iz = LCase(iz)
Next
When you call Substring, it is making a copy of that portion of the string and returning it as a new string object. So, even if you were successfully changing the value of that returned sub-string, it still would not change the original string in the Text property.
However, strings in .NET are immutable reference-types, so when you set iz = ... all you are doing is re-assigning the iz variable to point to yet another new string object. When you set iz, you aren't even touching the value of that copied sub-string to which it previously pointed.
In order to change the value of the text box, you must actually assign a new string value to its Text property, like this:
txtCode.Text = "the new value"
Since that is the case, I would recommend building a new string, using a StringBuilder object, and then, once the modified string is complete, then set the text box's Text property to that new string, for instance:
Dim builder As New StringBuilder()
For Each line As String In txtCode.Text.Split({Environment.NewLine}, StringSplitOptions.None)
' Fix case and append line to builder
Next
txtCode.Text = builder.ToString()
The solutions here are interesting but they are ignoring a fundamental tool of .NET: regular expressions. The solution can be written in one expression:
Dim result = Regex.Replace(txtCode.Text, "^\w+",
Function (match) match.Value.ToLower(), RegexOptions.Multiline)
(This requires the import System.Text.RegularExpressions.)
This solution is likely more efficient than all the other solutions here (It’s definitely more efficient than most), and it’s less code, thus less chance of a bug and easier to understand and to maintain.
The problem with your code is that you are running the loop only on each character of the first word in the whole TextBox text.
This code is looping over each line and takes the first word:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
line = line.Trim().ToLower()
If line.IndexOf(" ") > 0 Then
line = line.Substring(0, line.IndexOf(" ")).Trim()
End If
// do something with 'line' here
Next
Loop through each of the lines of the textbox, splitting all of the words in the line, making sure to .ToLower() the first word:
Dim strResults As String = String.Empty
For Each strLine As String In IO.File.ReadAllText("C:\Test\StackFlow.txt").Split(ControlChars.NewLine)
Dim lstWords As List(Of String) = strLine.Split(" ").ToList()
If Not lstWords Is Nothing Then
strResults += lstWords(0).ToLower()
If lstWords.Count > 1 Then
For intCursor As Integer = 1 To (lstWords.Count - 1)
strResults += " " & lstWords(intCursor)
Next
End If
End If
Next
I used your ideas guys and i made it up to it like this:
For Each line As String In txtCode.Text.Split(Environment.NewLine)
Dim abc() As String = line.Split(" ")
txtCode.Text = txtCode.Text.Replace(abc(0), LCase(abc(0)))
Next
It works like this. Thank you all.

Creating Newlines in PDF with VB.net

I have an application which creates a list from items in a collection. Then for each item, I will add it to an empty string, then add a newline character to the end of it. So ideally my string will look something like:
List1\nList2\nList3\n
Once this string is generated, I send it back to be placed in a placeholder for a pdf. If I try this code in a simple console application, it prints everything on a newline. But in my real world situation, I have to print it to a pdf. The items only show up with spaces in between them and not newlines. How can can format my strings so that pdf recognizes the newline symbol rather than ignoring it?
Here is my code that generates the string with newlines.
Private Function ConcatPlacardNumbers(ByVal BusinessPlacardCollection As BusinessPlacardCollection) As String
Dim PlacardNumbersList As String = Nothing
Dim numberofBusinessPlacards As Long = BusinessPlacardCollection.LongCount()
For Each BusinessPlacard As BusinessPlacard In BusinessPlacardCollection
numberofBusinessPlacards = numberofBusinessPlacards - 1
PlacardNumbersList = String.Concat(PlacardNumbersList, BusinessPlacard.PlacardNumber)
If numberofBusinessPlacards <> 0 Then
PlacardNumbersList = String.Concat(PlacardNumbersList, Enviornment.newline)
End If
Next
Return PlacardNumbersList
End Function
Try to add \u2028 instead:
Private Function ConcatPlacardNumbers(ByVal BusinessPlacardCollection As _
BusinessPlacardCollection) As String
Dim PlacardNumbersList As New StringBuilder()
For Each BusinessPlacard As BusinessPlacard In BusinessPlacardCollection
PlacardNumbersList.Append(BusinessPlacard.PlacardNumber)
'PlacardNumbersList.Append(ChrW(8232)) '\u2028 line in decimal form
PlacardNumbersList.Append(ChrW(8233)) '\u2029 paragr. in decimal form
Next
Return PlacardNumbersList.ToString
End Function
For paragraphs use \u2029instead. Fore more details:
http://blogs.adobe.com/formfeed/2009/01/paragraph_breaks_in_plain_text.html
The answer will depend on the tool that is being used to produce the PDF. Since newline doesn't work, I would actually try \n. The other possibility is that the PDF generation code is not designed to emit multiple lines; you can only determine this by examining the generation code.
However, there is a significant performance issue that you should address in your code: you will be generating a lot of string objects using this code. You should change the design to use System.Text.StringBuilder, which will greatly improve the performance:
Private Function ConcatPlacardNumbers(ByVal BusinessPlacardCollection As BusinessPlacardCollection) As String
Dim PlacardNumbersList As New System.Text.StringBuilder(10000)
For Each BusinessPlacard As BusinessPlacard In BusinessPlacardCollection
If PlacardNumbersList.Length <> 0 Then
' This is equivalent to Environment.NewLine
'PlacardNumbersList.AppendLine()
' The attempt to use \n
PlacardNumbersList.Append("\n")
End If
PlacardNumbersList.Append(BusinessPlacard.PlacardNumber)
Next
Return PlacardNumbersList.ToString
End Function
Note that you also do not need to keep track of the placard number: you can add a newline to the end of the previous item on each pass after the first one.