Need to strip numbers out of a filename string to change save location - vba

I'm having an issue where I need to strip a filename from a path but can't quite figure out the code.
An example filename would be C:\Checked out parts\001-1099-01.slddrw. I need to extract the "001-1099-01." portion. The file location to the left could be anything and the only constants in the file name are the "001-" portion (which I should point out, could repeat if the filename was 001-1001-03) and the ".slddrw". Other than that the filename could be named "001-10999-03-02-01".
I have stripped out the slddrw portion easily, I tried using Right and InStr functions to strip the rest off but I think that InStr only works with letters (couldn't find any number examples anyways)

I believe this is what you are looking for:
Public Sub test()
Dim strFileName As String
'Your sample file name
strFileName = "C:\Checked out parts\001-1099-01.slddrw"
'Search for the first occurance of \ in the reversed (!) file name
' if you substract this result from the length of the string
' you know where to start (+ 2 to avoid the \ itself)
strFileName = Mid(strFileName, Len(strFileName) - InStr(1, StrReverse(strFileName), "\") + 2)
'Remove the .slddrw portion from the end
strFileName = Replace(strFileName, ".slddrw", "")
'Done
Debug.Print strFileName
End Sub
Note the comments in the code for more information.

You can use a sub in which you define the path and extension of your file and it will give you the filename.
Sub getFileName()
Dim myString() As String
Dim path As String, extension As String
Dim fileName As String
path = "C:\Checked out parts\"
extension = ".slddrw"
'Say your string is in cell A1
myString = Split(Range("A1"), path)
fileName = Split(myString(1), extension)(0)
MsgBox fileName 'fileName can be used elsewhere after
End Sub
You could also do it as a function:
Function getFileName(cel As Range, path As String, extension As String)
Dim myString() As String
myString = Split(cel, path)
getFileName = Split(myString(1), extension)(0)
End Function
If you have the path and extensions stored in cells, you can use this function:
Function getFileName2(cel As Range, path As Range, extension As Range)
Dim myString() As String
myString = Split(cel, path)
getFileName2 = Split(myString(1), extension)(0)
End Function
Those are the options I can think of, hope it helps.
EDIT:
If you don't know the path nor the extension, you can use this instead:
myString = Split(Range("A1"), "\")
fileName = Split(myString(UBound(myString)), ".")(0)

Related

Copying a file from a directory to another one

I have a an application which is supposed to copy a selected file whose directory is written in txtbox1 to a folder of director written in txtbox2 as follows :
code :
Dim sourcepath As String = TextBox1.Text
Dim DestPath As String = TextBox2.Text
CopyDirectory(sourcepath, DestPath)
Called sub:
Private Shared Sub CopyDirectory(ByVal sourcePath As String, ByVal destPath As String)
If Not Directory.Exists(destPath) Then
Directory.CreateDirectory(destPath)
End If
For Each file__1 As String In Directory.GetFiles(Path.GetDirectoryName(sourcePath))
Dim dest As String = Path.Combine(destPath, Path.GetFileName(file__1))
File.Copy(file__1, dest)
Next
For Each folder As String In Directory.GetDirectories(Path.GetDirectoryName(sourcePath))
Dim dest As String = Path.Combine(destPath, Path.GetFileName(folder))
CopyDirectory(folder, dest)
Next
End Sub
This code copies all the files, not the specified one only. Can someone please tell me how to make this sub copy only the selected file not all the files in the folder?
You're taking the entire path as an argument (something like this: C:/someDirectory/filename.txt) and aren't comparing the filename to the other filenames in that directory.
Instead of using:
For Each file__1 As String In Directory.GetFiles(Path.GetDirectoryName(sourcePath))
Dim dest As String = Path.Combine(destPath, Path.GetFileName(file__1))
File.Copy(file__1, dest)
Next
Try:
Dim sourceFileName = Path.GetFileName(sourcePath)
For Each filePath As String in Directory.GetFiles(Path.GetDirectoryName(sourcePath))
Dim filename As String = Path.GetFileName(filePath)
If sourceFileName = filename
'Do your copy code here
End If
Next

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.

VBA - Split from right to left (REVERSED)

I want to extract the last folder from a folder path:
path = C:\Users\z204685\tecware\RESULTS\D1369_3 (R=0) Surface Failure
I want to extract the last part, after the "\", in a new string:
newString = "D1369_3 (R=0) Surface Failure"
Maybe reversing the path string, then using the Split function with "\" and then reversing it again...Any better ideas?
Here's my stab at it:
Sub test()
Dim testString As String
Dim test As Long
Dim output As String
testString = "C:\Users\z204685\tecware\RESULTS\D1369_3 (R=0) Surface Failure"
test = InStrRev(testString, "\")
output = Right(testString, Len(testString) - test)
End Sub
Hope it gets you close!
Look up the InStrRev function.
Another solution, according to #TimWilliams comment, You can achieve this using Split and UBound
Sub test()
Dim fpath As String
Dim newString As String
Dim temp_arr As Variant
fpath = "C:\Users\z204685\tecware\RESULTS\D1369_3 (R=0) Surface Failure"
temp_arr = Split(fpath, "\")
newString = temp_arr(UBound(temp_arr))
End Sub

Copy subfolders to another folder in VB.NET without overwriting

I have this code which I am using to copy a directory:
Private Sub CopyDirectory(ByVal sourcePath As String, ByVal destPath As String)
If Not Directory.Exists(destPath) Then
Directory.CreateDirectory(destPath)
End If
For Each file1 As String In Directory.GetFiles(sourcePath)
Dim dest As String = Path.Combine(destPath, Path.GetFileName(file1))
File.Copy(file1, dest)
Next
For Each dir1 As String In Directory.GetDirectories(Path.GetDirectoryName(sourcePath))
Dim destdir As String = Path.Combine(destPath, Path.GetFileName(dir1))
CopyDirectory(dir1, destdir)
Next
End Sub
And this is how I call CopyDirectory method:
Dim sourcepath As String = "E:\Crazy\"
Dim DestPath As String = "D:\Snippets\"
CopyDirectory(sourcepath, DestPath,)
The problem is that it continously copies the folder again and again. How do I stop this? And how do I copy the subfolder a single time? I have used recursion.
Your problem lies here:
For Each dir1 As String In Directory.GetDirectories(Path.GetDirectoryName(sourcePath))
This will get the parent folder of the destPath, not the correct path to copy from.
Also, you have a problem with File.Copy. If the file already exist in the destination path, calling File.Copy without an explict request to overwrite the destination will throw an exception.
Private Sub CopyDirectory(ByVal sourcePath As String, ByVal destPath As String)
If Not Directory.Exists(destPath) Then
Directory.CreateDirectory(destPath)
End If
For Each file1 As String In Directory.GetFiles(sourcePath)
Dim dest As String = Path.Combine(destPath, Path.GetFileName(file1))
File.Copy(file1, dest, True) ' Added True here to force the an overwrite
Next
' Use directly the sourcePath passed in, not the parent of that path
For Each dir1 As String In Directory.GetDirectories(sourcePath)
Dim destdir As String = Path.Combine(destPath, Path.GetFileName(dir1))
CopyDirectory(dir1, destdir)
Next
End Sub

Extract filename from path [duplicate]

This question already has answers here:
How to extract file name from path?
(16 answers)
Closed 1 year ago.
I need to extract the filename from a path (a string):
e.g.,
"C:\folder\folder\folder\file.txt" = "file" (or even "file.txt" to get me started)
Essentially everything before and including the last \
I've heard of using wildcards in place of Regex (as it's an odd implementation in VBA?) but can't find anything solid.
Cheers in advance.
I believe this works, using VBA:
Dim strPath As String
strPath = "C:\folder\folder\folder\file.txt"
Dim strFile As String
strFile = Right(strPath, Len(strPath) - InStrRev(strPath, "\"))
InStrRev looks for the first instance of "\" from the end, and returns the position. Right makes a substring starting from the right of given length, so you calculate the needed length using Len - InStrRev
Thanks to kaveman for the help. Here is the full code I used to remove both the path and the extension (it is not full proof, does not take into consideration files that contain more than 2 decimals eg. *.tar.gz)
sFullPath = "C:\dir\dir\dir\file.txt"
sFullFilename = Right(sFullPath, Len(sFullPath) - InStrRev(sFullPath, "\"))
sFilename = Left(sFullFilename, (InStr(sFullFilename, ".") - 1))
sFilename = "file"
I was looking for a solution without code. This VBA works in the Excel Formula Bar:
To extract the file name:
=RIGHT(A1,LEN(A1)-FIND("~",SUBSTITUTE(A1,"\","~",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))
To extract the file path:
=MID(A1,1,LEN(A1)-LEN(MID(A1,FIND(CHAR(1),SUBSTITUTE(A1,"\",CHAR(1),LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))))
`You can also try:
Sub filen()
Dim parts() As String
Dim Inputfolder As String, a As String
'Takes input as any file on disk
Inputfolder = Application.GetOpenFilename("Folder, *")
parts = Split(Inputfolder, "\")
a = parts(UBound(parts()))
MsgBox ("File is: " & a)
End Sub
This sub can display Folder name of any file
Here's simpler method: a one-line function to extract only the name — without the file extension — as you specified in your example:
Function getName(pf):getName=Split(Mid(pf,InStrRev(pf,"\")+1),".")(0):End Function
...so, using your example, this:
       MsgBox getName("C:\folder\folder\folder\file.txt")
  returns:
       
For cases where you want to extract the filename while retaining the file extension, or if you want to extract the only the path, here are two more single-line functions:
Extract Filename from x:\path\filename:
Function getFName(pf)As String:getFName=Mid(pf,InStrRev(pf,"\")+1):End Function
Extract Path from x:\path\filename:
Function getPath(pf)As String: getPath=Left(pf,InStrRev(pf,"\")): End Function
Examples:
(Source)
Using Java:
String myPath="C:\folder\folder\folder\file.txt";
System.out.println("filename " + myPath.lastIndexOf('\\'));
I used kaveman's suggestion successfully as well to get the Full File name but sometimes when i have lots of Dots in my Full File Name, I used the following to get rid of the .txt bit:
FileName = Left(FullFileName, (InStrRev(FullFileName, ".") - 1))
You can use a FileSystemObject for that.
First, include a reference for de Microsoft Scripting Runtime (VB Editor Menu Bar > Tools > References).
After that, you can use a function such as this one:
Function Get_FileName_fromPath(myPath as string) as string
Dim FSO as New Scripting.FileSystemObject
'Check if File Exists before getting the name
iF FSO.FileExists(myPath) then
Get_FileName_fromPath = FSO.GetFileName(myPath)
Else
Get_FileName_fromPath = "File not found!"
End if
End Function
File System Objects are very useful for file manipulation, especially when checking for their existence and moving them around. I like to use them early bound (Dim statement), but you can use them late bound if you prefer (CreateObject statement).
'[/vba]
' Keep It Simple
' .. why use FileSystemObject or Split when Left and Mid will do it
' the FSO has some 33 Subs or Functions
that have to be loaded each time it is created.
' and needs the file to exist ... yet is only a bit slower
... under twice time.. some good code in FSO
' conservation is good .. spare a few electrons. ????... save a few millionths of a sec
'Also
' .. why the format of a function that we all seem to use like
'
' .. Function GetAStr(x) as string
' dim extraStr as string
' a lot of work with extraStr..
' that could have been done with the string variable GetAStr
already created by the function
' then .. GetAStr=extraStr to put it in its right place
' .. End Function
Function GetNameL1$(FilePath$, Optional NLess& = 1)
' default Nless=1 => name only
' NLess =2 => xcopya.xls xcopyb.xls xcopy7.xlsm all as xcopy to get find latest version
' Nless = - 4 or less => name with name.ext worka.xlsm
GetNameL1 = Mid(FilePath, InStrRev(FilePath, "") + 1)
GetNameL1 = Left(GetNameL1, InStrRev(GetNameL1, ".") - NLess)
End Function
Function LastFold$(FilePath$)
LastFold = Left(FilePath, InStrRev(FilePath, "") - 1)
LastFold = Mid(LastFold, InStrRev(LastFold, "") + 1)
End Function
Function LastFoldSA$(FilePath$)
Dim SA$(): SA = Split(FilePath, "")
LastFoldSA = SA(UBound(SA) - 1)
End Function
[<vba]