VB.NET Path to file with unknown file extension (but known name) - vb.net

Could anyone help me with getting file path when I know file name (which is constant and won´t change) but don´t know file extension (can change depending on users selection in Excel):
Dim MyAppPath As String = My.Application.Info.DirectoryPath
Dim ExcelfilePath As String = IO.Path.Combine(MyAppPath, "bundle\" & "Rozpis.xlsm")
Dim ExcelfileBackupPath As String = IO.Path.Combine(MyAppPath, "bundle\backup\" & "Rozpis.xlsm")
I want it to be like this - to match any file with this particular name "Rozpis":
Dim MyAppPath As String = My.Application.Info.DirectoryPath
Dim ExcelfilePath As String = IO.Path.Combine(MyAppPath, "bundle\" & "Rozpis.*")
Dim ExcelfileBackupPath As String = IO.Path.Combine(MyAppPath, "bundle\backup\" & "Rozpis.*")
(This code is part of simple "self-protecting" mechanism for my app.)
What I tried:
I looked at regex (but if there is simpler way than regex it would be better - tried filemame.* - not working) as potential option (specifically this one: /(.)+(doc|docx|pdf)$/i ) but I don´t know much how to use it. I got error Regex cannot be converted to string when tried to use like this:
// Don´t remember the code exactly - something like this:
// regex = New Regex as regex
Dim ExcelfilePath As String = IO.Path.Combine(MyAppPath, "bundle\" & "Rozpis." & regex)
Dim ExcelfileBackupPath As String = IO.Path.Combine(MyAppPath, "bundle\backup\" & "Rozpis" & regex)

Related

VB.Net (2019) File I/O Mixed Data Help Please?

I am old and used to older VBA in Excel and Older VB code. Now I am trying to work in Visual Studio Community with VB. I have looked for help but everything I find for .NET comes up with C++ or C# code which I don't follow. I haven't even been able to find a book to help converting to the newer format of code. I am used to;
Dim outpath as integer
Dim aString as String
Dim aDouble as Double
aString = "Some Text"
aDouble = 3.1429
outpath = FreeFile
Open "C:\afolder\somedata.dat" For Output As outpath
print #outpath, aString
print #outpath, aDouble
close #outpath
To read data I'm used to using the aString = input #outpath instructions.
From what I have read it appears I should be using IO.Stream functions but have not found anything that would replicate the old method I am used to above.
Can somebody please point me to some internet pages that cover this in VB rather than falling into C code which I cannot translate to VB.
Thank you kindly.
Sure, there are a number of ways to do this. I also came from VB6, and lots of VBA.
So, to convert your above, and to write out to a file?
Well, one apporach (and we even did this in VBA) was to create a string, concentante the values to the string, and then write the string out to a file.
It is easy, but you have to in code toss in the next line character.
So, this will work:
Dim aString As String
Dim aDouble As Double
aString = "Some Text"
aDouble = 3.1429
Dim strPath As String = "C:\test\somedata.dat"
Dim strOutBuf As String = ""
strOutBuf = aString
strOutBuf = strOutBuf & vbCrLf & aDouble
File.WriteAllText(strPath, strOutBuf)
So, for a few easy lines of text - very easy.
However, for a lot of code, and a line by line output - similar to VBA?
Then you do it this way:
Dim FILE_NAME As String = "C:\test\test2.txt"
Dim MyFileWriter As New StreamWriter(FILE_NAME)
Dim aString As String
Dim aDouble As Double
aString = "Some Text"
aDouble = 3.1429
MyFileWriter.WriteLine(aString)
MyFileWriter.WriteLine(aDouble)
For i = 1 To 10
MyFileWriter.WriteLine(i)
Next
MyFileWriter.Close()
Note that in above, the file does not (can not) already exist.
So, you have to deal with that issue.
You can either delete the file before you start writing.
eg:
Dim FILE_NAME As String = "C:\test\test2.txt"
If File.Exists(FILE_NAME) Then
File.Delete(FILE_NAME)
End If
(and then the rest of your code follows. So there no need (or concept) of FreeFile() anymore.
output:
Some Text
3.1429
1
2
3
4
5
6
7
8
9
10
Edit: --------------------------------
Well, showing how to write out a file is kind of like the hug, without the kiss. So, now, how can we read the file?
Well, it really depends on what we want to do with that input. But .net tends to work reading (or in fact writing) the whole thing in one shot.
But, a line by line read would look like this:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim FILE_NAME As String = "C:\test\test2.txt"
Dim MyFileReader As New StreamReader(FILE_NAME)
Do While MyFileReader.EndOfStream = False
Debug.Print("one line of file = " & MyFileReader.ReadLine)
Loop
MyFileReader.Close()
End Sub
output:
one line of file = Some Text
one line of file = 3.1429
one line of file = 1
one line of file = 2
one line of file = 3
one line of file = 4
one line of file = 5
one line of file = 6
one line of file = 7
one line of file = 8
one line of file = 9
one line of file = 10
' vb.net has allowed declaration and assignment on the same line for more than 20yrs now
Dim aString as String = "Some Text"
Dim aDouble as Double = 3.1429
' New API methods do not use integers to track files.
' That was always kind of weird.
Dim outpath As String = "C:\afolder\somedata.dat"
' StreamReader/StreamWriter are great, and you should learn them,
' but you don't need them for this sample
System.IO.File.WriteAllText(outpath, $"{aString}{vbCrLf}{aDouble}")
' Interpolated strings (like above) are kind of fun, too
Again, without the comments and assuming an Imports directive for System.IO, to highlight how simple this can be:
Dim aString as String = "Some Text"
Dim aDouble as Double = 3.1429
Dim outpath As String = "C:\afolder\somedata.dat"
File.WriteAllText(outpath, $"{aString}{vbCrLf}{aDouble}")
If the interpolated string is too confusing, here's one more option:
Dim aString as String = "Some Text"
Dim aDouble as Double = 3.1429
Dim outpath As String = "C:\afolder\somedata.dat"
File.WriteAllText(outpath, aString)
File.AppendAllText(outpath, aDouble.ToString("r"))
However, that actually opens, writes, and closes the file twice. It's extra I/O, which is some of the slowest stuff you can do in a computer, so I don't recommend it.
Instead, you could build the output string with concatenation, but I'm sure you're aware that can also be cumbersome, so here's a final alternative with a System.IO.StreamWriter:
Dim aString as String = "Some Text"
Dim aDouble as Double = 3.1429
Dim outpath As String = "C:\afolder\somedata.dat"
'Using blocks (added way back in 2005) replace the need to Close the file
' Moreover, they promise to dispose of the file handle
' **even if there's an exception/error**,
' making your code safer and better.
Using writer As New StreamWriter(outpath)
writer.WriteLine(aString)
writer.WriteLine(aDouble)
End Using
Then to read the values back:
Dim filePath As String = "C:\afolder\somedata.dat"
Dim aString as String
Dim aDouble as Double
Using reader As New StreamReader(filePath)
aString = reader.ReadLine()
aDouble = Double.Parse(reader.ReadLine())
End Using

VB.Net Cant create "new line" "string"

I am in need of assistance... i am trying to create a textfile with links in it. the code i have..
dim domain as string = "http://www.mywebsite/"
dim name as string = "username"
Dim link As String = New String("domain" & "name")
TextBox1.AppendText(link & Environment.NewLine)
Msgbox(textBox1.lines(0))
The problem is that MsgBox only shows up as "http://www.mywebsite/". the textbox does show "http://www.mywebsite/username" but when copied to text document it is:
Line0: http://www.mywebsite/
Line1:username
any ideas... tried using
Dim link As String = String.Join(domain & name) but that doesnt work nor does
Dim link As String = new String.Join(domain & name)
i need
Msgbox(textBox1.lines(0)) to display "http://www.mywebsite/username" not one or the other.
That was quick got a message saying to use. Dim link As String = String.Concat(domain & name)
i think you should move to StringBuilder first import Imports System.Text
'create a string with multiple lines
Dim a As New StringBuilder
a.AppendLine("hi")
a.AppendLine("there")
a.AppendLine("this")
a.AppendLine("is")
a.AppendLine("a")
a.AppendLine("test")
'read will makes read line by line
Dim read As String() = a.ToString.Split(vbNewLine)
'count has number of lines
Dim count As Integer = a.ToString().Split(vbNewLine).Length - 1
'lines will be added to combobox one by one
For i As Integer = 0 To count - 1
ComboBox1.Items.Add(read(i))
Next
you just should edit it to suits your needs i didnt understand what you needed exactly

Renaming all files in a folder

I'm wondering if it's possible to rename all the files in a folder with a simple program, using vb.NET
I'm quite green and not sure if this is even possible.
Lets say there is a folder containing the files:
Text_Space_aliens.txt, fishing_and_hunting_racoons.txt and mapple.txt.
Using a few credentials:
Dim outPut as String = "TextFile_"
Dim fileType as String = ".txt"
Dim numberOfFiles = My.Computer.FileSystem.GetFiles(LocationFolder.Text)
Dim filesTotal As Integer = CStr(numberOfFiles.Count)
Will it be possible to rename these, regardless of previous name, example:
TextFile_1.txt, TextFile_2.txt & TextFile_3.txt
in one operation?
I think this should do the trick. Use Directory.GetFiles(..) to look for specific files. Enumerate results with a for..each and move (aka rename) files to new name. You will have to adjust sourcePath and searchPattern to work for you.
Private Sub renameFilesInFolder()
Dim sourcePath As String = "e:\temp\demo"
Dim searchPattern As String = "*.txt"
Dim i As Integer = 0
For Each fileName As String In Directory.GetFiles(sourcePath, searchPattern, SearchOption.AllDirectories)
File.Move(Path.Combine(sourcePath, fileName), Path.Combine(sourcePath, "txtFile_" & i & ".txt"))
i += 1
Next
End Sub
In your title you state something about chronologically, but within your question you never mentioned it again. So I did another example ordering files by creationTime.
Private Sub renameFilesInFolderChronologically()
Dim sourcePath As String = "e:\temp\demo"
Dim searchPattern As String = "*.txt"
Dim curDir As New DirectoryInfo(sourcePath)
Dim i As Integer = 0
For Each fi As FileInfo In curDir.GetFiles(searchPattern).OrderBy(Function(num) num.CreationTime)
File.Move(fi.FullName, Path.Combine(fi.Directory.FullName, "txtFile_" & i & ".txt"))
i += 1
Next
End Sub
I've never done Lambdas in VB.net but tested my code and it worked as intended. If anything goes wrong please let me know.

I need to use Directory.GetFiles but with a few more conditions

Here's an example. Lets say I have two files in a directory:
Filename_v1.pdf
Filename_v1_ABC.pdf
Here's some code:
Dim StorageRoot = "SomePath"
Dim RootName = "Filename"
Dim Suffix = "_v"
Dim matchingFiles as string()
matchingFiles = Directory.GetFiles(StorageRoot, Path.GetFileNameWithoutExtension(file.FileName.ToString) + "*.*")
This returns both files mentioned above, but I need to only match files where the first * in *.* if it is numeric. So I need it to ignore a file if it has anything other than a number after the Suffix.
---- Edit ----
It chewed some of my example. Here's some pseudo code:
matchingFiles = Directory.GetFiles(StorageRoot, Path.GetFileNameWithoutExtension(file.FileName.ToString) + "onlyifitisnumeric.*")
One possibility would be to use Regular expressions in order take only those file whose name is matching the pattern you want to have and filter the result from GetDirectory. The pattern in this case could be:
.*_v[0-9]\.pdf
meaning
.*_v <- all symbols followed by "_v"
[0-9] <- followed by a number
\.pdf <- followed by ".pdf"
The pattern can also use the \d character class that means Matches any decimal digit. and makes the pattern shorter:
.*_v\d\.pdf
And the code can look like this:
dim path = "d:\\temp\\xml\\"
dim files = Directory.GetFiles(path, "*.pdf")
Dim rx = new Regex(".*_v\d\.pdf") ' or Dim rx = new Regex(".*_v[0-9]\.pdf")
for each file in files
if rx.IsMatch(file) then
' do something with the file
Console.WriteLine(file)
end if
next file
If you want your code to be succinct then you could use LINQ to Objects:
dim path = "d:\\temp\\xml\\"
dim files = Directory.GetFiles(path, "*.*")
Dim rx = new Regex(".*\d\.pdf") ' or Dim rx = new Regex(".*[0-9]\.pdf")
dim filteredFiles = files.Where(function(file) rx.IsMatch(file))
Here is a sample:
Imports System.Text.RegularExpressions
Imports System.IO
[...]
Dim rx As New Regex("^filename_v\d$")
Dim f = (From fItem As String In IO.Directory.GetFiles("PathToFiles")
Where rx.IsMatch(IO.Path.GetFileNameWithoutExtension(fItem))
Select fItem).ToArray
' Test Output
MessageBox.Show(String.Join(vbCrLf, f))
Use Regex("^filename_v\d+$") to match numbers of any length.
Here what you can do. First Get files with _v*_*, which possible using regular wildcards. Then, apply additional pattern you need to get the subset of files.
Dim files As IEnumerable(Of String) = _
Directory.GetFiles("your path", "your initial optional wildcard").Where(Function(f) Regex.IsMatch(f, "<your pattern>"))

Insert variable into middle of url

how could I insert a variable into the middle of a URL using vb.net?
e.g.
Dim ver As String = "variable"
http://testurl.co.uk/folder/next_folder/" & ver & "/test.exe
(not sure if this is correct above)
Note: I know how to set a variable but not sure how to insert into the middle of a URL
You could do that (as #SysDragon has pointed out, you need to store the result in a variable). Another alternative would be:
Dim ver As String = "variable"
Dim url As String = String.format("http://testurl.co.uk/folder/next_folder/{1}/test.exe", ver)
It probably doesn't matter for something as trivial as this, but strings are immutable, so doing:
Dim myString as String = "a" & "b" & "c"
effectively destroys and recreates the string twice. StringBuilder (which I believe string.format uses internally) prevents this.
Almost, I think you want this:
Dim ver As String = "variable"
Dim url As String = "http://testurl.co.uk/folder/next_folder/" & ver & "/test.exe"
To browse the url in the form do something like this:
Dim wb1 As New Net.WebBrowser()
Form1.Controls.Add(wb1)
wb1.Navigate(url)