Using statement in Visual Basic - vb.net

I'm having difficultly with the using statement in Visual Basic. Does anyone know how this should be written?:
Using (Dim doc As WordprocessingDocument = WordprocessingDocument.Open(filename, True))
//blah blah
End Using
The code works fine without the using and its obviously as syntactic error. "Dim" is highlighted, and an expression is expected apparently. Sorry if this a bit basic, but the info on vb using statements is not clear and its obviously doesn't work in the c# style.

There's two things wrong.
First, you must remove the Dim keyword. The Using keyword replaces the Dim keyword. Both Dim and Using have the same effect of declaring a new variable, just in different ways.
Secondly, you must remove parentheses. The very first thing after the Using keyword must be the variable name.
Using doc As WordprocessingDocument = WordprocessingDocument.Open(filename, True)
' blah blah
End Using

Related

VB.Net corrupted strings - IDE Incorrectly interpreting a string as code

Today I opened a visual basic project which has several lines that declare some strings, which contain comma separated data. I amended one of the strings, rebuilt and closed the project. When I came to test it, there was an error. When I looked at the code, I discovered that the strings on lines after the one I had amended had also changed - they had spaces inserted after the commas.
Has anyone seen normal strings incorrectly having formatting applied by the IDE in visual studio 2015?
It seems like the string is being formatted as if it were code. I would suspect this has something to do with String Interpolation, though these are legacy projects that do not use it.
Edit, FWIW the code is similar to this, I've renamed the fields and headings to try keep it short.
fullColumnMappingsBuilder.Append(",field1,field2,field3,field4,field5,field6,field7,field8,field9,field10")
fullColumnHeadingsBuilder.Append(",heading1,heading2,heading3,heading4,heading5,heading6,heading7,heading8,heading9,heading10")
If clientCode = "ML" Then
fullColumnMappingsBuilder.Append(",mlField")
fullColumnHeadingsBuilder.Append(",mlHeading")
End If
defaultColumnMappingsBuilder.Append(",morefields1,morefields2,morefields3,morefields4")
defaultColumnHeadingsBuilder.Append(",moreHeadings1,moreHeadings2,moreHeadings3,moreHeadings4")
My edit was to simply add in field11 and heading11, and save. But the code ended up looking like this:
fullColumnMappingsBuilder.Append(",field1,field2,field3,field4,field5,field6,field7,field8,field9,field10,field11")
fullColumnHeadingsBuilder.Append(",heading1,heading2,heading3,heading4,heading5,heading6,heading7,heading8,heading9,heading10,heading11")
If clientCode = "ML" Then
fullColumnMappingsBuilder.Append(", mlField")
fullColumnHeadingsBuilder.Append(", mlHeading")
End If
defaultColumnMappingsBuilder.Append(", morefields1, morefields2, morefields3, morefields4")
defaultColumnHeadingsBuilder.Append(", moreHeadings1, moreHeadings2, moreHeadings3, moreHeadings4")
The problem is that the IDE has inserted spaces after the commas on lines that I did not edit.
Well, I think I know how I did it. If you start with something like this:
Public Class Class1
Sub New()
Dim string1 As String = "Hello there world asdfj asldfkja sad "
Dim string2 As String = "some code like words dim private as object sub"
End Sub
End Class
I think I must have taken the first double quotes character off the declaration of string1, and then moved the position of the text cursor to a different line. In previous versions of visual studio, the IDE would have marked the first line as being in error.
Now we have multi-line strings, it thinks you have a multi-line string running from the quotes at the end of the first line up to string2 As String", and that the following text is code, and so it gets changed (in this case the keywords are capitalized).
Dim string2 As String = "some code Like words Dim Private As Object Sub"
I'll just have to be more careful when editing strings.
Might not have been your fault.
I've seen VS 2015 automatically make changes very similar to the above example:
Dim string2 As String = "some code like words dim private as object sub"
... changing to:
Dim string2 As String = "some code Like words Dim Private As Object Sub"
This was on both multi-line and single-line strings, in procedures I had not touched at all, in a .vb file where I was changing strings in other procedures. Only reason I caught VS doing this was because I did a Compare before check-in.
In Visual Studio formatting Strings as VB.NET code it suggests un-checking Tools > Options > Text Editor > Basic > Advanced > Pretty listing (reformatting) of code, but am reluctant to turn off all the good things that does.
Feels like a bug in VS 2015 to me. Have never seen this in 16 years of using prior versions of VS, before 2015.

Linq ToList does nothing

I have Option Strict and Option Infer both set "On".
This code works fine:
Dim tBoxes = From t In MainForm.Frame2.Controls.OfType(Of TextBox).ToList
tBoxes.ToList().ForEach(Sub(c) c.DataBindings.Clear())
Why can't I combine them into the one line below (I believe it's related to the fact that the first line above does not set tBoxes to a list but remains an IEnumerable even though I am calling ToList, why is this?)
Dim tBoxes = From t In MainForm.Frame2.Controls.OfType(Of TextBox).ToList.ForEach(Sub(c) c.DataBindings.Clear())
This code results in an error
Expression does not produce a value
This might seem like much ado about nothing but it's not just the reduction to one line, I'd like to understand what's going on here.
VB.NET 2010
The problem is not the ToList call, but List.ForEach Method which is Sub, hence does not have a result and cannot be assigned to a variable.
If you want to use a single line, remove Dim tBoxes =.
Update In fact there is another problem in the above code.
Dim tBoxes = From t In MainForm.Frame2.Controls.OfType(Of TextBox).ToList
is equivalent to
Dim tBoxList = MainForm.Frame2.Controls.OfType(Of TextBox).ToList
Dim tBoxes = From t in tBoxList
so obviously tBoxes is IEnumerable<TextBox>.
Since the from t In .. part is unnecessary in this case, the "oneliner" should be something like this
MainForm.Frame2.Controls.OfType(Of TextBox).ToList.ForEach(Sub(c) c.DataBindings.Clear())
If you really need a query part, to avoid such confusions, don't forget to enclose it in (..) before calling ToList or other methods like Count, Any etc., like this
(from t In MainForm.Frame2.Controls.OfType(Of TextBox)).ToList.ForEach(Sub(c) c.DataBindings.Clear())
Small description but enough to understand
From t In MainForm.Frame2.Controls.OfType(Of TextBox) 'Filter all object of type text box
.ToList 'Convert IEnemerable(Of TextBox) to a IList type.
.ForEach(Sub(c) c.DataBindings.Clear())' Iterate through list and remove bindg of each text box
Issue is that .ForEach does not return any value so that there is nothing to assign the tBoxes object that you have created. It is just like a void method or Sub in VB.net.

Format number with leading zeroes in .NET 2.0

I have problem to format numbers and convert it to string with leading zeroes when application uses NET framework 2.0 with Visual Basic.
I try:
Dim myNum = 12
Dim myStr as String
Dim myStr = myNum.ToString("0000")
or
Dim myStr = myNum.ToString("D4")
... in order to get wanted string: 0012
Please help to solve this.
You have an old version of Visual Studio, one that doesn't have Option Infer yet. Or it isn't turned on. That makes the myNum identifier a variable of type Object.
So your code tries to call the Object.ToString() method. Which does not have an overload that takes an argument. The compiler now tries to make hay of your code and can only do so by treating ("0000") or ("D4") as an array index expression. Indexing the string that's returned by Object.ToString(). That has pretty funny side effects, to put it mildly. A string like "0000" is not a valid index expression, the compiler generates code to automatically convert it to an Integer. That works for "0000", converted to 0 and the result is a character, just "1"c. Converting "D4" to an integer does not work so well of course, that's a loud Kaboom!
The solution is a very simple one, just name the type of the variable explicitly:
Dim myNum As Integer = 12
Dim myStr = myNum.ToString("D4") '' Fine
VB.NET's support for dynamic typing is pretty in/famous. Meant to help new programmers getting started, it in fact is an advanced technique given the myriad ways it can behave in very unexpected ways.
The universal advice is always the same. Let the compiler help you catch mistakes like this. Put this at the top of your source code file:
Option Strict On

Comparing Strings in VB 6.5

I am trying to compare two strings in VB but compareTo, compare, equals etc all give compile errors.
If String.Compare(string_one, string_two) = 0 Then
'...do stuff
End If
If String.Equals(string_one, string_two) Then
'...do stuff
End If
Now both lines give me the error,
Compile error:
Expected: (
and it highlights the dot after String, i.e.
String.(whatever)
______↑__________
Do I need to include something, I normally program C, Java and C# so I am not very familiar with VB
Now I am doing this in a very crappy program that uses Microsoft Visual Basic 6.5 is it that these functions just simply do not exist?
VB6 just uses the = operator:
If string_one = string_two Then
''# Do Stuff
End If
For that matter you do it that way in VB.Net as well, though vb.net also allows the .Equals() function in this form:
If string_one.Equals(string_two) Then
''# Do Stuff
End If
You could also use StrComp function:
StrComp(String1, String2, [Compare As VbCompareMethod = vbBinaryCompare])

How I can use regex in VS macro?

I want create macro for replacing. But my problem is how to use regular expression in Visual Basic's macro for Visual Studio?
document.Selection.ReplacePattern("test{[^']+}test", "testAAAAtest")
Doesn't work.
First does the RegEx actually match something? Try it in the Find Dialog first.
Second you will need to tell the Replace Pattern how to match - It's essentially the same as doing a Find/Replace.
Here is something to get you started: (Note the vsFindOptions.vsFindOptionsRegularExpression)
Public Sub ReplaceRegEx()
DTE.UndoContext.Open("RegEx Replace")
Dim textSelection As TextSelection = DTE.ActiveDocument.Selection
textSelection.ReplacePattern("test{[^']+}test", "testAAAAtest", vsFindOptions.vsFindOptionsRegularExpression)
DTE.UndoContext.Close()
End Sub