Get and edit a file name - vba

I'm looking to retreive a txt file and then edit the file name (adding "converted" to the file name) and extension (from .r01 to .txt).
The purpose for this is so I can know if the txt file has been converted
Here's my code so far;
Dim infilename As Variant
infilename = Application.GetOpenFilename("Text & r01 Files (*.r01;*.txt),*.r01;*.txt", , "Open Neutral File", "OPEN")

InStrRev will allow you to find the last . and remove it and everything following from the string
FileNameWithoutExt = Left(Filename, InStrRev(Filename, ".") - 1)
An example with the workbooks FullName:
?activeworkbook.FullName
Z:\Individual Folders\Sean\transfers2.xlsx
?Left(activeworkbook.FullName, InStrRev(activeworkbook.FullName, ".") - 1)
Z:\Individual Folders\Sean\transfers2
You can wrap these in a function to make them easier to use. I've also added a function that will give the filename only instead of the one with the full path
Function FileNameOnly(fName)
'Changes "C:\Path\Filename.ext" to "Filename.ext"
FileNameOnly=mid(fName,instrrev(fName,"\")+1)
End Function
Function DelExt(fName)
'Changes "C:\Path\Filename.ext" to "C:\Path\Filename"
DelExt=left(fName,instrrev(fName,".")-1)
End Function
You can then use these in your program, with a line like NewFileName=DelExt(infilename) & "CONVERTED.txt"

I managed to get what I was looking for using part of Sean Cheshire's code.
Dim newFileName As Variant
newFileName = Left(inFileName, (InStrRev(inFileName, ".") - 1)) & "CONVERTED.txt"

Related

VBA FileExists and Sharepoint

I'm running into issues trying to pull info from files stored in Sharepoint.
Namely, FileExists isn't working and Overwrite file doesn't seem to be working either.
There was a discussion here, but few answers -> posting this question again in hopes some things have changed
My code runs like this:
strFileExists = Dir(Filepath & Filename)
And returns: File path not found -> I checked the path and even opened a file and recorded the macro to make sure it was the same file path without issue, but it appears DIR() is the issue.
The business dept I'm working with is entirely switching over to Sharepoint so hoping there's a straightforward solution without setting up network shares or doing C/personal/OneDrive things
You can navigate and look for files on OneDrive like this
Sub check_File_Exists()
Dim path As String
Dim strType As String
Dim file As Variant
Dim yourFile As String
'replace uname with your user name
path = "C:\Users\uname\OneDrive\"
strType = "*txt"
yourFile = "test.txt"
file = Dir(path & strType)
Do While (file <> "")
If file = yourFile Then
Debug.Print ("File: " & file & " found!")
Exit Do
End If
file = Dir
Loop
End Sub
Hope it helps

Opening an excel file with partial name

Is there a way to open an excel file without knowing the full path name?
For example:
TEST_03222018.csv is the file name located in C:\test\folder
the known part of the string\path is
C:\test\folder\TEST_03
is there a way to open this csv sheet without the rest of the path (preferably without using InStr() or any If, While loops
Function findFile(strFileStart as string) as string
findFile= Dir(strFileStart & "*", vbNormal)
End Function
Echo, #Ryan Wilson's comments about having more than one file with the same prefix though.
Use Dir with a wildcard to confirm the existence and if found, open it.
dim fp as string, fn as string
fp = "C:\test\folder\"
fn = "test_03"
fn = dir(fp & fn & "*.csv")
if cbool(len(fn)) then
workbooks.open fp & fn, delimiter:=","
end if

How to list only file name?

I have program to find files in a directory and list them in a listbox, but the following code I'm using adds the full path for the file found.
Is there something I'm missing to make it only add the file name and not the full path?
If My.Computer.FileSystem.DirectoryExists(My.Computer.FileSystem.CurrentDirectory & "\" & Details.IDL.Text) Then
For Each FoundFile As String In My.Computer.FileSystem.GetFiles(My.Computer.FileSystem.CurrentDirectory & "\" & Details.IDL.Text)
ListBox.Items.Add(FoundFile)
Next
Else
My.Computer.FileSystem.CreateDirectory(My.Computer.FileSystem.CurrentDirectory & "\" & Details.IDL.Text)
End If
so to fix it i only had to put ListBox.Items.Add(IO.Path.GetFileName(FoundFile)) instead of ListBox.Items.Add(FoundFile)
Here is a working example to list file name individually with GetFileNameWithoutExtension, along with the way you are using GetFileName.
Dim fileName As String = "C:\mydir\myfile.ext"
Dim pathname As String = "C:\mydir\"
Dim result As String
result = Path.GetFileNameWithoutExtension(fileName)
Console.WriteLine("GetFileNameWithoutExtension('{0}') returns '{1}'", fileName, result)
result = Path.GetFileName(pathname)
Console.WriteLine("GetFileName('{0}') returns '{1}'", pathname, result)

File extension validation

This searches for the end of a file name removes it's current file type of .docm and converts it to a .docx. Works great.
ActiveDocument.SaveAs2 Left(ActiveDocument.Name, InStrRev(ActiveDocument.Name, ".") - 1), WdSaveFormat.wdFormatXMLDocument
However, I noticed a little bug. If there is a . in the file name, it finds that first and obviously creates a file that is incorrect.
For example:
TestFileV1.2AlexTest.docm
Becomes the file
TestFileV.2AlextTest Where the new file type is a .2ALEXTEST file.
Kind of a funny error, but still a bug none the less.
Best course of action for validation?
Thanks!
Try the VBA.Strings.Split() function, which splits a string into an array.
Split the File name on '.' and the last element in the array will be your extension:
Public Function GetExtension(FileName As String) As String
'Returns a file's extension
' This does not go to the filesystem and get the file:
' The function parses out the string after the last '.'
' Useful for situations where a file does not yet exist
' Nigel Heffernan Excellerando.Blogspot.com
' **** THIS CODE IS IN THE PUBLIC DOMAIN ****
'Print GetExtension("C:\Temp\data.txt1.docx")
'Returns docx
Dim arrayX() As String
Dim iLast As Integer
arrayX = Split(FileName, ".")
iLast = UBound(arrayX)
GetExtension = arrayX(iLast)
Erase arrayX
End Function
If you don't care about readability, the quick-and-dirty answer is:
strExt = Split(strFile, ".")(UBound(Split(strFile, ".")))
However... I think you're looking for something more sophisticated than a string parser to extract the file extension.
Are you actually looking to validate the file extension?
I'm not coding up a registry lookup for the ShellExt application command to open your file, but I had a closely-related issue to yours a year or two ago, when I needed to populate a file dialog's filter list with a list of arbitrary file extensions.
It doesn't 'validate' as such, but unknown extensions will return a string containing 'unknown file type', and you can test for that:
VBA and the Registry: Returning a File Type from a File Extension
Public Function GetExtensionType(strExt As String) As String
' Return a file extension type descriptor, if the OS knows it
' Parses out the string after the last "." and reads the registry
' GetExtensionType("txt") Returns 'Text Document'
' GetExtensionType("SystemORA.user.config") 'XML Configuration File'
' GetExtensionType("Phishy.vbs") 'VBScript Script File'
' Nigel Heffernan Excellerando.Blogspot.com
' **** THIS CODE IS IN THE PUBLIC DOMAIN ****
On Error GoTo ErrSub
Dim strType As String
Dim strTyp1 As String
Dim strTyp2 As String
strExt = Trim(strExt)
' Set a default return: if an error is raised, return this value
GetExtensionType = Trim(strExt & " (unknown file type)")
strExt = Split(strExt, ".")(UBound(Split(strExt, "."))) '
If strExt = "" Then
Exit Function
End If
With CreateObject("WScript.Shell")
' This will go to error if there's no key for strExt in HKCR
strTyp1 = .RegRead("HKCR." & strExt & "\")
If strTyp1 = "" Then
strType = strExt & " File"
Else
' This value isn't very readable, eg: Access.ACCDEFile.14
' But we can use it to retrieve a descriptive string:
strTyp2 = .RegRead("HKCR\" & strTyp1 & "\")
If strTyp2 = "" Then
' So we didn't get a descriptive string:
' Parse some readability out of strType1:
strType = strTyp1
strType = Replace(strType, "File", " File")
strType = Replace(strType, ".", " ")
Else
strType = strTyp2
End If
End If
End With
If strType <> "" Then
GetExtensionType = strType
End If
ExitSub:
Exit Function
ErrSub:
Resume ExitSub
End Function
I made it error-tolerant but I didn't bother idiot-proofing it because someone, somewhere, is building a better idiot; and it's entirely possible that the user was actually right insofar as there really are files called that, and my system didn't have a registry entry for the file type in question.
There is an obvious source of errors in the code: GetExtensionType("docx") will give you 'Microsoft Word Document' on an English-Language workstation. If your user base are working with other languages and locales, they will see the descriptive name 'Microsoft Word Document' in their chosen language; and any validation logic you've coded up will fail to match that string (unless, of course, your string literals are internationalised in a conditional compiler block).
So any validation against a predefined application name or file type needs to be at the language-independent layer of the registry, using 'strTyp1' from the root instead of the locale-dependent strings passed into 'strTyp2'.
Use the FileSystemObject from the Scripting Runtime - it has a .GetBaseName() method to extract the basename from a file path:
'Early bound (reference to Microsoft Scripting Runtime):
Dim fso As New FileSystemObject
ActiveDocument.SaveAs2 fso.GetBaseName(ActiveDocument.Name), WdSaveFormat.wdFormatXMLDocument
'Late bound:
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
ActiveDocument.SaveAs2 fso.GetBaseName(ActiveDocument.Name), WdSaveFormat.wdFormatXMLDocument
You can also retrieve the extension with the .GetExtensionName() method, the path with .GetParentFolderName(), and the drive letter with GetDriveName() (which also works with UNC paths).
If you need to find the registered name of the extension in the current Windows install, you can either use the registry method #Nile answered with or an API call to AssocQueryStringA:
Const ASSOCSTR_FRIENDLYDOCNAME = 3
Private Declare Function AssocQueryString Lib "shlwapi.dll" _
Alias "AssocQueryStringA" ( _
ByRef Flags As Long, _
ByVal str As Long, _
ByVal pszAssoc As String, _
ByVal pszExtra As String, _
ByVal pszOut As String, _
ByRef pcchOut As Long) As Long
Sub Main()
Dim buffer As String
buffer = String$(255, " ")
Dim hresult As Long
hresult = AssocQueryString(0, ASSOCSTR_FRIENDLYDOCNAME, ".docm", _
vbNullString, buffer, 255)
If hresult = 0 Then
'Should be something like "Microsoft Word Macro-Enabled Document"
Debug.Print Trim$(buffer)
End If
End Sub
Note that you can also retrieve addition information about the associated file type by passing different values for the str parameter. See the ASSOCSTR enumeration.

replace file name have multiple extensions in vb.net

I have an issue while uploading documents have multiple periods. For example if I upload a file having an extension of ammu.gopu.docx. I would like to replace that as ammu_gopu.docx, means to preserve the extension and replace the file name with undescore.
This should do what your asking. Beware - If your file name also appears in the path it will also be updated.
Dim fullPath As String = "C:\Test\My.File.Name.txt"
Dim fileName As String = IO.Path.GetFileNameWithoutExtension(fullPath)
fullPath = fullPath.Replace(fileName, fileName.Replace("."c, "-"))
Use the System.IO.Path.GetExtension method.
Try this:
filePath = IO.Path.GetDirectoryName(filePath) & _
IO.Path.GetFileNameWithoutExtension(filePath).Replace("."c, "_"c) & _
"." & IO.Path.GetExtension(filePath)