Getting the current line number using Visual Studio Macros? - vb.net

So I looked through other user's question but couldn't find on specifically upon what I am looking for. What I am trying to do is very simple. I am writing a Visual Studio Macro and am trying to obtain the number of the current line that the TextSelection is on. So that's it really, my question is quite simple. How do you get the number of the line that the selection is currently at? Any help is greatly appreciated!
Just so it's clear to anybody reading this, I am using VB and am writing Visual Studio Macro.

Keep in mind that a TextSelection can span multiple lines, so there's potentially a range of lines.
Looking at the docs for TextSelection (i.e. I haven't tested this), you should be able to do something like this:
Dim mySelection As EnvDTE.TextSelection = ' however you get the active selection
mySelection.TopPoint.Line ' gets the line of the top of the selection
If you want to get it based on where the cursor is (top or bottom of the selection) you can try this:
mySelection.ActivePoint.Line
It looks like the TextRanges might also be useful, but it sounds like it's for box selection only, so it might not apply.
mySelection.TextRanges.Item(0).Line

There is probably a better way than this, but the first way that comes to my mind is something like this.
First, make sure that the last line in your file is "xyz"
Dim linenumber As Integer = 1
dim mystring as string = ""
Using myfile As New IO.StreamReader("C:/myfile")
mystring = myfile.readline()
while mystring <> "xyz"
linenumber += 1
messagebox.Show(mystring & " is on line " & linenumber)
end while
End Using
So if the contents of C:/myfile looked like this....
I
Love
Pie
Then you would get as output....
"I is on line 1"
"Love is on line 2"
"Pie is on line 3"

Related

Change the drive-letter for multiple shortcuts

I got a little problem. I got three backupdiscs for my computer and a sick ammount of windows-shortcuts.
My goal is to change the "target" and "open in" value for multiple windows-shortcuts (.ink) from:
"A:\Folder\File.mpg"
to
"D:\Folder\File.mpg"
for around 2k files.
I'm just blank on how to find (and change) the "target" and "open in" value within the windows-shortcuts (.ink). To be clear, it's only the partition letter, "A":\ in this case, I wish to change (to "D"), nothing else in the string. (for multiple items)
was thinking something like:
dim letterOne = combobox1.text
dim letterTwo = combobox2.text
for each file
shortcut.TargetPath("letterOne ", "*.ink")
Change to
shortcut.TargetPath("letterTwo", "*.ink")
If I am reading the question correctly, you can just use the Replace string function:
MyString.Replace("A:","D:")
If you need to do it for a lot of files, build a collection of the filenames and then use a For Each loop.

Replacing nothing with a string

This may be a simple question, but I have searched quite a few sites and have tried a few of my own ideas and I still cannot seem to find a simple way to get Visual Studio to replace all of the listbox items with the string of nothing with some other text.
Using things such as :
For Each S In ListBox1.Items
S.Replace("", "Not Blank")
Next
Shows:
Error
String cannot be of zero length
Which is quite annoying because the actual listbox item contains no text.
This seems to be one of the easiest things I have ever encountered while using vb.net. But it now seems very hard for what should be a simple command.
A couple of problems. The Replace function returns a new value, and you promptly ignore it. Second, you can't really modify the collection as you For-Each over it, so a For-Loop would be more appropriate.
I think you want something like this instead:
For i As Integer = 0 To ListBox1.Items.Count - 1
If String.IsNullOrEmpty(ListBox1.Items(i).ToString) Then
ListBox1.Items(i) = "Not Blank"
End If
Next

CSV Data handling - vb.net

I've been asked at work to create a project to open a CSV and then use a set of conditions to change and save the data using Visual Basic.net (2010)
Although I am comfortable creating files in vb and opening them again into vb, I don't know how to declare the fields so I can query them. For example:
if field1 = "Yes" and field2 = "Blue" then textbox1.text = "abcd"
Then at a later stage I want to export a file which I'm happy doing where it writes lines to create a new CSV which could be Field1, textbox1.text, Field3 and so on
Also, would I have to declare line1.field1 and line2.field1 or could I declare line2.field1 as field25 for example or whatever the next sequential number may be?
Thanks
How are you going to read from the file?
If you do File.ReadAllLines
what does it return? A string array.
Does a string array have properties like line1? No, but they do have indexers.
How do you access an element in a string array? With a indexer,
e.g. array(0).
Does an string have properties like field1? Nope.
Can you use String.Split to split on the commas and separate the fields? Yes.
Could you write a class that has specific properties defined for each field that has a constructor that'd take a string that represents a row and put the value into the correct fields? Yes.
Could the same class know how to convert itself into a single CSV style line? Yup.
Are there other library that could help you do this? Probably.
All that being said, you can probably get away with doing something simple like this (warning: naive code sample):
Dim fileName = "C:\testFile.csv"
Dim lines = File.ReadAllLines(fileName)
Dim output As New List(Of String)
For Each line In lines
Dim fields = line.Split(","c)
fields(0) = "000" 'Blank out number
If fields(3) = "Y" Then 'Change Y to True
fields(3) = "True"
End If
output.Add(String.Join(","c, fields))
Next
File.WriteAllLines(fileName, output)
I gave it input that looked like this:
123,abc,Y,Y,N
456,def,Y,N,Y
789,ghi,N,Y,Y
012,jkl,N,N,N
and it changed the file to this:
000,abc,Y,True,N
000,def,Y,N,Y
000,ghi,N,True,Y
000,jkl,N,N,N
Utilities for working with CSV will do a better job than this. There are various ways this won't work (doesn't handle any escape sequences, etc.) but this could be sufficient if you're just wanting to do something quick and dirty and don't need to worry about some things. At the very least hopefully it'll give you a better understanding of how you'd go about solving a problem like this.
I'd recommend writing the output to a different file to test.

Trim file after a blank line

I have a text file that has multiple blank lines and Im trying to return all the lines between two of them specifically
so if I have a file that looks like this:
____________________________
1########################
2##########################
3
4########################
5##########################
6#######################
7
8#########################
9##########################
10#######################
11####################
12########################
13#########################
14
15##########################
----------------------------
I would like to grab lines 8-13. Unfortunately, it might not always be 8-13 as it could be 9-20 or 7-8, but it will however always be between the 2nd and 3rd line break.
I know how to trim characters and pull out singular lines, but I have no idea how to trim entire sections.
Any help would be appreciated, even if you just point me to a tutorial.
Thanks in advance.
The basic idea here is to get the entire thing as a string, split it into groups at the double line breaks, and then reference the group you want (in your case, the third one).
Dim value As String = File.ReadAllText("C:\test.txt")
Dim breakString As String = Environment.NewLine & Environment.NewLine
Dim groups As String() = value.Split({breakString}, StringSplitOptions.None)
Dim desiredString As String = groups(2)
MsgBox(desiredString)
Edit:
In response to the question in your comment -
Environment.NewLine is a more dynamic way of specifying a line break. Assuming you're running on windows - you could use VbCrLf as well. The idea is that if you were to compile the same code on Linux, it Environment.NewLine would generate a Lf instead. You can see here for more information: http://en.wikipedia.org/wiki/Newline
The reason I used Environment.NewLine & Environment.NewLine is because you want to break your information where there are two line breaks (one at the end of the last line of a paragraph, and one for the blank line before the next paragraph)
What I ended up doing was trimming the last part and searching for what I needed in the first part (I know I didnt include the searching part in the question, but I was just trying to figure out a way to narrow down the search results as it would have had repeated results). Im posting this incase anyone else stumbles upon this looking for some answers.
Dim applist() = System.IO.File.ReadAllLines("C:\applist.txt")
Dim findICSName As String = "pid"
Dim ICSName As New Regex("\:.*?\(")
Dim x = 0
Do Until applist(x).Contains("Total PSS by OOM adjustment:")
If applist(x).Contains(findICSName) Then
app = ICSName.Match(applist(x)).Value
app = app.TrimStart(CChar(": "))
app = app.TrimEnd(CChar("("))
ListBox1.Items.Add(app)
End If
x = x + 1
Loop
End If
How this works is that it looks through each line for the regex until it reaches first word in the breakpoint "Total PSS by OOM adjustment:"

VS 2010 macro - select from here to there

I'm writing a macro to let me replace the spaces in a string in my code file with underscores. I've gotten as far as finding the beginning and end of the string as instances of VirtualPoint. Now I'm trying to select from the first VirtualPoint to the second. And I can't figure it out.
I know the VirtualPoints are correct, because I'm using MessageBox.Show to tell me their values when I run the macro. I just don't know the correct command to set the TextSelection from the first to the second. I've tried this:
selection.MoveToPoint(firstVirtualPoint)
selection.MoveToPoint(secondVirtualPoint, True)
This seems like it ought to work, but it doesn't. The cursor just moves to the end of the line (as far as I can tell).
Does anybody know the correct command for doing this?
As these things tend to go, after I give up, suddenly it hits me. Perhaps this will help someone else, though.
A fuller sample of the code is this:
Dim selection As TextSelection =
CType(DTE.ActiveDocument.Selection, TextSelection)
selection.StartOfLine()
selection.FindText("some string at start")
Dim pointAfterStart = selection.BottomPoint
selection.FindText("some string at end")
Dim pointBeforeEnd = selection.TopPoint
selection.MoveToPoint(pointAfterIt)
selection.MoveToPoint(pointBeforeLambda, True)
The idea is to find the initial text, then the ending text, and then select everything in between. What I found in the debugger was that the values in pointAfterStart and pointBeforeEnd were changing. Perhaps deceived by the name (since System.Drawing.Point is a struct), I wasn't realizing they were references that pointed to the current selection position.
I solved it this way:
selection.FindText("It ")
Dim pointAfterIt = selection.BottomPoint.CreateEditPoint
selection.FindText(" = () =>")
Dim pointBeforeLambda = selection.TopPoint.CreateEditPoint
This made copies of the selection points, so that they didn't change when the selection moved later.