A vbs script to remove annotation - excel

I have a basic vbs code to split a file name at the first underscore. Eg:t_e_s_t becomes t.
I dont want to split the file name, I want to remove the annotation of the file name
that would consist out of "." "_" and spaces.
Please can someone just have a look at the code and tell me how to modify it?
Option Explicit
Dim strPath
Dim FSO
Dim FLD
Dim fil
Dim strOldName
Dim strNewName
Dim strFileParts
'Define the path to the file
strPath = inputbox("File path:")
'Create the instance of the FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
'Set the folder you want to search. NOTE - some antivirus may not like this
Set FLD = FSO.GetFolder(strPath)
'Loop through each file in the folder
For Each fil in FLD.Files
'Get complete file name with path
strOldName = fil.Path
'Check the file has an underscore in the name
If InStr(strOldName, "_") > 0 Then
'Split the file on the underscore so we can get everything before it
strFileParts = Split(strOldName, "_")
'Build the new file name with everything before the
'first under score plus the extension
strNewName = strFileParts(0) & ".txt"
'Use the MoveFile method to rename the file
FSO.MoveFile strOldName, strNewName
End If
Next
'Cleanup the objects
Set FLD = Nothing
Set FSO = Nothing

How about:
strNewName = Replace(strOldName, "_", "") & ".txt"

Instead of publishing code that does not do what you want, you should specify exactly what input should be transformed to what output. E.g: "t e.s_t" should become "test". Then it would be easy to come up with some proof of concept code:
>> Function qq(s) : qq = """" & s & """" : End Function
>> Function clean(s)
>> clean = Replace(Replace(Replace(s, " ", ""), ".", ""), "_", "")
>> End Function
>> a = Array("test", "t e s t", "t_e.s t")
>> For i = 1 To UBound(a)
>> c = clean(a(i))
>> WScript.Echo qq(a(i)), qq(c), CStr(c = a(0))
>> Next
>>
"t e s t" "test" True
"t_e.s t" "test" True
>>
and really interesting questions like:
Why apply the modification to the full path (strOldName = fil.Path)?
What should happen to the dot before the extension?

Use a regular expression:
Set re = New RegExp
re.Pattern = "[._ ]"
re.Global = True
For Each fil in FLD.Files
basename = FLD.GetBaseName(fil)
extension = FLD.GetExtensionName(fil)
fil.Name = re.Replace(basename, "") & "." & extension
Next
If you want to mangle the extension and append a new extension .txt to each file regardless of type use this loop instead:
For Each fil in FLD.Files
fil.Name = re.Replace(fil.Name, "") & ".txt"
Next

Related

Unable to copy files (.pdf/.jpeg/.jpg) from one folder to another

Using 2010 Excel VBA - I need to use look up the image/pdf with the Branch Code as a part of its name at "C:\ECB Test\ECB IR COPY" and paste it at "C:\ECB Test\" RO if it exists. If it doesn't, the program needs to highlight the Branch Code.
(File Name Examples: 28-Kochi-ecb-sdwan completed.pdf, 23 eCB Kozhikode completed.pdf/0036.jpeg)
Having done this manually twice for two other excel sheets (4k+ cells), I decided to Frankenstein a module together and, well, it does not work and I have no idea why.
Sub Sort()
Const SRC_PATH As String = "C:\ECB Test\ECB IR COPY"
Const DEST_PATH As String = "C:\ECB Test"
Dim Row_Number As Integer
Dim fso As Object
Set fso = VBA.CreateObject("Scripting.FileSystemObject")
Dim Folder_Name As String
Dim Branch_Code As String
Dim Final_Path As Variant
Dim File As String
For Row_Number = 3 To 2465
Branch_Code = Worksheets("WAN RFP").Cells(Row_Number, 2)
Folder_Name = Worksheets("WAN RFP").Cells(Row_Number, 5)
On Error Resume Next
File = Dir(SRC_PATH & "\*" & Branch_Code & "*")
Final_Path = Dir(DEST_PATH & "\" & Folder_Name & "\")
If (Len(File) > 0) Then
Call fso.CopyFile(File, Final_Path)
Else
Cells(Row_Number, 2).Interior.ColorIndex = 6
End If
On Error GoTo 0
DoEvents
Next Row_Number
End Sub
I think its unable to use the Branch Code variable as a wildcard, though I might as well have done something silly somewhere in the code. Can someone please help me out?
The problem is you are using the destination path instead of the source path:
File = Dir(DEST_PATH & "*" & Branch_Code & "*.*")
Change it to
File = Dir(SRC_PATH & "*" & Branch_Code & "*.*")

Is there a way to obtain the file path of an excel sheet through a fuzzy match with a cell in a Master Excel sheet? [duplicate]

I need to open a file whose full filename I do not know.
I know the file name is something like.
filename*esy
I know definitely that there's only one occurrence of this file in the given directory.
filename*esy is already a "shell ready" wildcard & if thats alway the case you can simply;
const SOME_PATH as string = "c:\rootdir\"
...
Dim file As String
file = Dir$(SOME_PATH & "filename*esy" & ".*")
If (Len(file) > 0) Then
MsgBox "found " & file
End If
Just call (or loop until empty) file = Dir$() to get the next match.
There is an Application.FileSearch you can use (see below). You could use that to search for the files that match your pattern. This information taken from here.
Sub App_FileSearch_Example()
With Application.FileSearch
.NewSearch
.LookIn = "c:\some_folder\"
.FileName = "filename*esy"
If .Execute(SortBy:=msoSortByLastModified, SortOrder:=msoSortOrderDescending) > 0 Then
For i1 = 1 To .FoundFiles.Count
' do something with matched file(s)
Next i1
End If
End With
End Sub
If InStr(sFilename, "filename") > 0 and InStr(sFilename, "esy") > 0 Then
'do somthing
end if
Or you can use RegEx
Dim RE As Object, REMatches As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.MultiLine = False
.Global = False
.IgnoreCase = True
.Pattern = "filename(.*)esy"
End With
Set REMatches = RE.Execute(sFilename)
REMatches(0) 'find match
I was trying this question as a function. This is the solution that ended up working for me.
Function fileName(path As String, sName As String, ext As String) As Variant
'path is Full path from root. Can also use path = ActiveWorkbook.path & "\"
'sName is the string to search. ? and * are wildcards. ? is for single char
'example sName = "book?" or sName ="March_*_2014*"
'ext is file extention ie .pdf .xlsm .xls? .j*
Dim file As Variant 'Store the next result of Dir
Dim fname() As String 'Dynamic Array for result set
ReDim fname(0 To 0)
Dim i As Integer ' Counter
i = 0
' Use dir to search and store first result
fname(i) = path & Dir(path & "\" & sName & ext)
i = i + 1
'Load next result
file = Dir
While file <> "" 'While a file is found store that file in the array
ReDim Preserve fname(0 To i) As String
fname(i) = path & file
file = Dir
Wend
fileName = Application.Transpose(fname) 'Print out array
End Function
This works for me as a single or array function.
If you know that no other file contains "filename" and "esy" in that order then you can simply use
Workbooks.Open Filename:= "Filepath\filename*esy.*"
Or if you know the number of missing characters then (assuming 4 characters unknown)
Workbooks.Open Filename:= "Filepath\filename????esy.*"
I use this method to run code on files which are date & timestamped to ignore the timestamp part.

remove files with VBA in Tortoise SVN

I need to delete (remove) files (and possibly folders) via Excel VBA in Tortoise SVN environment. However I change my command, it always deletes the folder where files reside.
Call obj.Run("TortoiseProc.exe /command:remove /pathfile:""C:\someSVNpath\123.txt"" /closeonend:1 ")
Call obj.Run("TortoiseProc.exe /command:remove /pathfile:""C:\someSVNpath\Folder"" /closeonend:1 ")
I was also trying to list files in the loop and delete, but then the error appears: Subversion reported an error: Previous operation has not finished; run 'cleanup' if it was interrupted. Please execute the 'Cleanup' command.
Also, even if I manage to list the files in the loop and delete, the commit operation does not find any files for committing.
Dim obj, FSO, folder, file As Object
Dim b, c, p(1 To 2) As String
Set obj = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
b = "C:\someSVNlocation\folder\"
With ThisWorkbook.Sheets("Equity")
p(1) = "loc1"
p(2) = "loc2"
For i = 1 To 2
If p(i) <> "" Then
c = b & "\" & p(i) & "\"
Set folder = FSO.GetFolder(c)
For Each file In folder.Files
d = c & file.Name
Call obj.Run("TortoiseProc.exe /command:remove /path:""" & d & """ /closeonend:1 ")
d = ""
Next file
End If
Next
Call obj.Run("TortoiseProc.exe /command:commit /path:""" & p(1) & """ * """ & p(2) & """ ")
End With
I think your main problem is that you aren't waiting for the shell to return. These operations are likely running asynchronously and running over each other. This is a sort of race condition.
I fix this by adding , 1, True to the end of the .Run command. The 1 is a intWindowStyle that "Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time."
The True at the end is bWaitOnReturn indicating whether the script should wait for the program to finish executing before continuing to the next statement in your script.
The way you declared your variables they are all variants. Dim needs a type on each variable. Also Call is deprecated.
Try building off of this:
Public Sub CallTortoise()
Dim wShell As Object
Set wShell = CreateObject("WScript.Shell")
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim svnPath As String
svnPath = "C:\someSVNlocation\folder\"
With ThisWorkbook.Sheets("Equity")
Dim p(1 To 2) As String
p(1) = "loc1"
p(2) = "loc2"
Dim i As Long
For i = 1 To 2
If p(i) <> "" Then
Dim thisPath As String
thisPath = FSO.BuildPath(svnPath, p(i))
Dim folder As Object
Set folder = FSO.GetFolder(thisPath)
Dim file As Object
For Each file In folder.Files
Dim deletePath As String
deletePath = FSO.BuildPath(thisPath, file.Name)
wShell.Run "TortoiseProc.exe /command:remove /path:""" & deletePath & """ /closeonend:1 ", 1, True
deletePath = ""
Next file
End If
Next i
wShell.Run "TortoiseProc.exe /command:commit /path:""" & svnPath & p(1) & "*" & svnPath & p(2) & """ ", 1, True
End With
End Sub

How to select the last part of a string with VBa?

I'm trying to name a text file created by my code.
the text file is a formated version of another text file.
Let's say i have file A: original file, and file B: formated file.
file B is created by my VBa code and i want to name file B : formate + "file A"
here's my code:
Dim order As Object
Dim Folder As Object
Dim Folder_path As String
Dim lastrow As Long
Dim fSo As Object
Dim myFile As Object
MsgBox InStrRev(Sheets(8).Cells(6, 12).Value, "\")
FolderName = "Formated Files"
Filename = "formated " & Right(Sheets(8).Cells(6, 12).Value, InStrRev(Sheets(8).Cells(6, 12).Value, "\")
[...]
Folder_path = FL + "\" + FolderName
Set fSo = CreateObject("Scripting.FileSystemObject")
If Not fSo.FolderExists(Folder_path) Then
fSo.CreateFolder (Folder_path)
If fSo.FolderExists(Folder_path) Then
Set fSo = CreateObject("Scripting.FileSystemObject")
Set myFile = fSo.CreateTextFile(Folder_path + "\" + Filename, True)
myFile.WriteLine "Error"
myFile.Close
Set fSo = Nothing
End If
Else
If fSo.FolderExists(Folder_path) Then
Set fSo = CreateObject("Scripting.FileSystemObject")
Set myFile = fSo.CreateTextFile(Folder_path + "\" + Filename, True)
for now i'm trying to get the name of the file B by using the path of the file A (so i need to get the last part of the path witch is the name of file A) and adding "formated" to it.
If you see a better way to get that name or if you find a way to simplify my code feel free to help.
If your filename looks something like this:
C:/documents/docs/filename.txt
And you want to append a word before the .txt:
C:/documents/docs/filename_suffix.txt
the easiest way is probably:
newfilename = Replace(filename,".txt","_suffix.txt",,,1)
However, if you wanted to append a word before the start of the file's name:
C:/documents/docs/prefix_filename.txt
then you could use FSO's GetBaseName in a replace
filebase=fso.getbasename(filename) & "."
newfilename = Replace(filename,filebase,"prefix_" & filebase,,,1)

Remove a line from a text file if that line contains some string

In VB6, I'm looking for a way to remove a line of text from a text file if that line contains some string. I work mostly with C# and I'm at a loss here. With .NET there are several ways to do this, but I'm the lucky one who has to maintain some old VB code.
Is there a way to do this?
Thanks
Assuming you have the filename in a variable sFileName:
Dim iFile as Integer
Dim sLine as String, sNewText as string
iFile = FreeFile
Open sFileName For Input As #iFile
Do While Not EOF(iFile)
Line Input #iFile, sLine
If sLine Like "*foo*" Then
' skip the line
Else
sNewText = sNewText & sLine & vbCrLf
End If
Loop
Close
iFile = FreeFile
Open sFileName For Output As #iFile
Print #iFile, sNewText
Close
You may want to output to a different file instead of overwriting the source file, but hopefully this gets you closer.
Well text files are a complicated beast from some point of view: you cannot remove a line and move the further text backward, it is a stream.
I suggest you instead about considering an input to output approach:
1) you open the input file as text
2) you open a second file for output, a temporary file.
3) you iterate through all lines in file A.
4) if current line contains our string, don't write it. If current line does not
contains our string, we write it in the file B.
5) you close file A, you close file B.
Now you can add some steps.
6) Delete file A
7) Move file B in previous file A location.
DeleteLine "C:\file.txt", "John Doe", 0,
Function DeleteLine(strFile, strKey, LineNumber, CheckCase)
'Use strFile = "c:\file.txt" (Full path to text file)
'Use strKey = "John Doe" (Lines containing this text string to be deleted)
Const ForReading = 1
Const ForWriting = 2
Dim objFSO, objFile, Count, strLine, strLineCase, strNewFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.Readline
If CheckCase = 0 Then strLineCase = UCase(strLine): strKey = UCase(strKey)
If LineNumber = objFile.Line - 1 Or LineNumber = 0 Then
If InStr(strLine, strKey) Or InStr(strLineCase, strKey) Or strKey = "" Then
strNewFile = strNewFile
Else
strNewFile = strNewFile & strLine & vbCrLf
End If
Else
strNewFile = strNewFile & strLine & vbCrLf
End If
Loop
objFile.Close
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, ForWriting)
objFile.Write strNewFile
objFile.Close
End Function

Resources