Trying to do a find/replace with wildcard - excel

I am trying to loop through all text files in a folder, open each, do a find/replace, save each, and close each. My code looks like this.
Sub FindAndReplaceText()
Dim FileName As String
Dim FolderPath As String
Dim FSO As Object
Dim I As Integer
Dim SearchForWords As Variant
Dim SubstituteWords As Variant
Dim Text As String
Dim TextFile As Object
'Change these arrays to word you want to find and replace
SearchForWords = Array(" steps:" & "*" & " fields:")
SubstituteWords = Array(" global" & vbCrLf & " global:" & vbCrLf & " schema_def:" & vbCrLf & " fields:")
'Change the folder path to where your text files are.
' look for all lines with: ' - .*Pricing_RealEstate' & '*'
FolderPath = "C:\path_here\"
Set FSO = CreateObject("Scripting.FileSystemObject")
FolderPath = IIf(Right(FolderPath, 1) <> "\", FolderPath & "\", FolderPath)
FileName = Dir(FolderPath & "\*.txt")
Do While FileName <> ""
FileSpec = FolderPath & FileName
'Read all the file's text into a string variable.
Set TextFile = FSO.OpenTextFile(FileSpec, 1, False)
Text = TextFile.ReadAll
TextFile.Close
'Scan the string for words to replace and write the string back to the file.
Set TextFile = FSO.OpenTextFile(FileSpec, 2, False)
For I = 0 To UBound(SearchForWords)
Debug.Print Text
Replace Text, SearchForWords(I), SubstituteWords(I)
Debug.Print Text
Next I
TextFile.Write Text
TextFile.Close
FileName = Dir()
Loop
End Sub

This is tried and working with the sample data:
Sub FindAndReplaceText2()
Dim FileName, FileName2 As String
Dim FolderPath, FolderPath2 As String
Dim FileSpec, FileSpec2 As String
Dim FSO As Object
Dim SearchForWords As String
Dim SubstituteWords As String
Dim Text As String
Dim TextFile As Object
'Change these arrays to word you want to find and replace
SearchForWords = " steps:" & "*" & " fields:"
SubstituteWords = " global" & vbCrLf & " global:" & vbCrLf & " schema_def:" & vbCrLf & " fields:"
'Change the folder path to where your text files are.
' look for all lines with: ' - .*Pricing_RealEstate' & '*'
FolderPath = "C:\users\user\Desktop\New Folder\"
FolderPath2 = "C:\users\user\Desktop\New Folder2\"
Set FSO = CreateObject("Scripting.FileSystemObject")
FileName = Dir(FolderPath & "\*.txt")
Do While FileName <> ""
FileSpec = FolderPath & FileName
FileSpec2 = FolderPath2 & FileName
'Read all the file's text into a string variable.
Set TextFile = FSO.OpenTextFile(FileSpec, 1, False)
Text = TextFile.ReadAll
TextFile.Close
'SrchReplText Now work for single wildcard only
Text = SrchReplText(Text, SearchForWords, SubstituteWords)
'Scan the string for words to replace and write the string back to the file.
Set TextFile = FSO.CreateTextFile(FileSpec2, 2, False)
TextFile.Write Text
TextFile.Close
FileName = Dir()
Loop
End Sub
Private Function SrchReplText(Txt As String, SrcTxt As String, RplTxt As String) As Variant
'Now for single wildcard only using single loop
Dim Wordx, Word3 As Variant
Dim I, I2 As Long
SrchReplText = Txt
Wordx = Split(SrcTxt, "*")
If UBound(Wordx) > 1 Then Exit Function
If UBound(Wordx) = 1 Then
Do
Found = False
I = InStr(1, SrchReplText, Wordx(0))
If I > 0 Then I2 = InStr(I, SrchReplText, Wordx(1))
If I > 0 And I2 > 0 Then
Found = True
Word3 = Mid(SrchReplText, I, I2 - I + Len(Wordx(1)))
SrchReplText = Replace(SrchReplText, Word3, RplTxt, 1, 1)
End If
Loop While Found
Else
SrchReplText = Replace(SrchReplText, SrcTxt, RplTxt, 1, 1)
End If
End Function

Related

I have multiple xlsx file(which are not opened). I want to copy selected range value of each Workbook to the single row

I have multiple workbooks each having the same sheet. I want to Copy the sheet's value to the master book.
I want to copy the selected range value of each Workbook to the single row of the new workbook.
Also, how can I retrieve the options button caption from the source workbook? Where Option buttons are ActiveX and linked cells.
If the options button is checked, copy the options button caption value to the destination cell.
Also I wish to add yyyy , mm,dd values in Date format (yyyy/mm/dd)
Sub test1()
Dim Wsh As New IWshRuntimeLibrary.WshShell
Dim result As WshExec
Dim fileData() As String
Dim path As String
Dim cmd As String
path = ThisWorkbook.path & "\Book1"
cmd = "dir" & path & "/Test"
Set result = Wsh.Exec("%ComSpec% /c" & cmd)
Do While result.Status = 0
DoEvents
Loop
fileData = Split(result.StdOut.ReadAll, vbCrLf)
Dim i As Long
i = 4
For Each strData In fileData
Cells(i, 2).Value = strData
If Cells(i, 2).Value <> "" Then
Cells(i, 3).Value = "='" & path & "\[" & strData & "]sheet1'!F1" '
Cells(i, 4).Value = "='" & path & "\[" & strData & "]sheet1'!C4" '
End If
i = i + 1
Next
End Sub
Retrieve Data From Closed Workbooks 2
Sub RetrieveDataFromClosedWorkbooks2()
Const SOURCE_SUBFOLDER_NAME As String = "Book1"
Const SOURCE_FILE_PATTERN As String = "*.xlsx"
Const SOURCE_WORKSHEET_NAME As String = "Sheet1"
Const SOURCE_CELL_ADDRESSES_LIST As String = "F1,C4"
Const DESTINATION_WORKSHEET_NAME As String = "Sheet1"
Const DESTINATION_FIRST_CELL_ADDRESS As String = "B4"
Dim dwb As Workbook: Set dwb = ThisWorkbook
Dim dws As Worksheet: Set dws = dwb.Worksheets(DESTINATION_WORKSHEET_NAME)
Dim dCell As Range: Set dCell = dws.Range(DESTINATION_FIRST_CELL_ADDRESS)
Dim pSep As String: pSep = Application.PathSeparator
Dim sFolderPath As String
sFolderPath = dwb.Path & pSep & SOURCE_SUBFOLDER_NAME
If Right(sFolderPath, 1) <> pSep Then sFolderPath = sFolderPath & pSep
Dim sFileNames() As String
sFileNames = FileNamesToArray(sFolderPath, SOURCE_FILE_PATTERN)
If UBound(sFileNames) = -1 Then
MsgBox "No files found.", vbExclamation
Exit Sub
End If
Dim sAddresses() As String
sAddresses = Split(SOURCE_CELL_ADDRESSES_LIST, ",")
Dim sf As Long
Dim sa As Long
Dim dFormula As String
For sf = 0 To UBound(sFileNames)
dCell.Offset(sf).Value = sFileNames(sf) ' source file name
For sa = 0 To UBound(sAddresses)
dFormula = "='" & sFolderPath & "[" & sFileNames(sf) _
& "]" & SOURCE_WORKSHEET_NAME & "'!" & sAddresses(sa)
'Debug.Print dFormula
With dCell.Offset(sf, sa + 1)
'Debug.Print .Address, sf, sFileNames(sf), sa, sAddresses(sa)
.Formula = dFormula
'.Value = .Value ' to keep only values
End With
Next sa
Next sf
MsgBox "Data retrieved.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the names of all files of a folder in an array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FileNamesToArray( _
ByVal FolderPath As String, _
Optional ByVal FilePattern As String = "*.*") _
As String()
Const DirSwitches As String = "/b/a-d"
Dim pSep As String: pSep = Application.PathSeparator
If Right(FolderPath, 1) <> pSep Then FolderPath = FolderPath & pSep
Dim ExecString As String ' '%comspec%' or 'cmd.exe' ?
ExecString = "%comspec% /c Dir """ _
& FolderPath & FilePattern & """ " & DirSwitches
Dim pString As String
pString = CreateObject("WScript.Shell").Exec(ExecString).StdOut.ReadAll
If Len(pString) = 0 Then ' multiple issues: no file, invalid input(s)
FileNamesToArray = Split("") ' ensure string array: 'LB = 0, UB = -1'
Else
pString = Left(pString, Len(pString) - 2) ' remove trailing 'vbCrLf'
FileNamesToArray = Split(pString, vbCrLf)
End If
End Function

find and replace string in text file (powershell script) with cell value with VBA

I am trying to create button in Excel which will call VBA script which will change text file.
I have text file which looks like:
String 1
String2
...
String 123
Invoke-WebRequest -Uri https://www.example.com/publicdocs/files/iceu/2022/07/IPE0729F.CSV.zip
-OutFile C:\folder\files\IPE0802F.CSV.zip
String 125
....
String 999
What I need is to change string:
Invoke-WebRequest -Uri
https://www.example.com/publicdocs/files/iceu/2022/07/ABB0729F.CSV.zip
-OutFile C:\folder\files\ABB0802F.CSV.zip
and replace dates with values from cells, i.e.:
replace 2022 with
Range("A1").Value
Replace 07
with
Range("A2").Value
Replace 0729
with Range("A3").Value
Replace 0802
With Range("A4").Value
So I need to find this string in text file, modify it and save file.
Maybe someone can help with that since looks like I have no enough knowledge to achieve it (
Ok, here I can find needed string, but I dont know how to replace whole string with updated one:
Sub updatePS()
Const ForReading = 1, ForWriting = 2
Dim FSO, FileIn, FileOut, strTmp
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FileIn = FSO.OpenTextFile("C:\powershell.ps1", ForReading)
Set FileOut = FSO.OpenTextFile("C:\powershell2.ps1", ForWriting, True)
Do Until FileIn.AtEndOfStream
strTmp = FileIn.ReadLine
If Len(strTmp) > 0 Then
If InStr(1, strTmp, "Invoke-WebRequest", vbTextCompare) > 0 Then
' Here I should add code to replace updated string
End If
End If
Loop
FileIn.Close
FileOut.Close
End Sub
You did not answer all my clarification questions...
The the next solution assumes that "2022" and "07" are both between "/" two such characters and "0729" / "0802" have a following suffix of "F.C" string. Otherwise, the code could strictly replace the strings you asked for, but the possibility to also replace in different locations exists:
Sub ModifScript()
Dim sh As Worksheet, fso As Object, ts As Object, sPath As String, sFile As String, strText As String
Set sh = ActiveSheet
sPath = ThisWorkbook.Path & "\" 'use here your real path, please!
sFile = "powershell.ps1"
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.getFile(sPath & sFile).OpenAsTextStream(1, -2)
strText = ts.ReadAll
ts.Close
Dim chngTxt As String, chngText As String, frstChar As Long, frstChar2 As Long, endChar As Long
frstChar = 1 'first character, where from InStr start evaluation
frstChar = InStr(frstChar, strText, "Invoke-WebRequest") 'the digit number where the necessary string (to be changed) starts
frstChar2 = InStr(frstChar + Len("Invoke-WebRequest"), strText, "OutFile C:\") 'this returns the real ending of the necessary string...
endChar = InStr(frstChar2 + Len("Invoke-WebRequest"), strText, "F.CSV.zip") 'the digit number where the necessary string ends
'string to be processed:
chngTxt = Mid(strText, frstChar, endChar + Len("F.CSV.zip") - frstChar)
Debug.Print chngTxt 'just to visually check that the correct string to be changed has been returned
chngText = Replace(Replace(chngTxt, "/2022/", "/" & sh.Range("A1").value & "/"), "/07/", "/" & sh.Range("A2").value & "/")
chngText = Replace(Replace(chngText, "0729F.C", sh.Range("A3").value & "F.C"), "0802F.C", sh.Range("A4").value & "F.C")
Debug.Print chngText 'just to visually check that the string to be changed has been correctly changed
'replace the changed string in the original file text:
strText = Replace(strText, chngTxt, chngText) 'the changed whole string!
Debug.Print strText
Dim scriptFold As String, pathToFile As String
If Dir(sPath & "Scripts", vbDirectory) = "" Then MkDir sPath & "Scripts" 'create "Scripts" folder if it does not exist
pathToFile = sPath & "Scripts\" & sFile
Open pathToFile For Output As #1
Print #1, strText
Close #1
End Sub
The above code saves the processed file content in a new folder ("Scripts), created by the code, if not exists...
Basically, you should use the same script file, but always update the column B:B of the active sheet with the changed string (taken from A:A). It is necessary to only replace in code "/2022/" with "/" & Sh.Range("B1").value & "/", "/07/" with "/" & Sh.Range("B2").value & "/", "0729F.C" with Sh.Range("B2").value & "S.C" and so on...
Edited:
Please, test the next variant. It does not need the existing strings to be replaced, anymore. This code is able to firstly identify/extract the strings to be replaced and then replaces them with the one from the Excel sheet:
Sub ModifScript_Next()
Dim sh As Worksheet, fso As Object, ts As Object, sPath As String, sFile As String, strText As String
Set sh = ActiveSheet
sPath = ThisWorkbook.Path & "\"
sFile = "powershell.ps1"
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.getFile(sPath & sFile).OpenAsTextStream(1, -2)
strText = ts.ReadAll
ts.Close
Dim chngTxt As String, chngText As String, frstChar As Long, frstChar2, endChar As Long
frstChar = 1 'first character, where from InStr start evaluation
frstChar = InStr(frstChar, strText, "Invoke-WebRequest") 'the digit number where the necessary string (to be changed) starts
frstChar2 = InStr(frstChar + Len("Invoke-WebRequest"), strText, "OutFile C:\") 'this returns the real ending of the necessary string...
endChar = InStr(frstChar2 + Len("Invoke-WebRequest"), strText, "F.CSV.zip") 'the digit number where the necessary string ends
'string to be processed:
chngTxt = Mid(strText, frstChar, endChar + Len("F.CSV.zip") - frstChar)
Debug.Print chngTxt 'just to visually check that the correct string to be changed has been returned
Dim frstStr As String, secStr As String, thrdStr As String, fourStr As String, frstC As Long, secCh As Long
'extract first string:
frstC = InStr(1, chngTxt, "docs/files/iceu/")
secCh = InStr(frstC + Len("docs/files/iceu/"), chngTxt, "/")
frstStr = Mid(chngTxt, frstC + Len("docs/files/iceu/"), secCh - (frstC + Len("docs/files/iceu/")))
'Debug.Print "_" & frstStr & "_" 'OK
'extract second string:
frstC = secCh + 1
secCh = InStr(frstC, chngTxt, "/IPE")
secStr = Mid(chngTxt, frstC, secCh - frstC)
'Debug.Print "_" & secStr & "_" 'OK
'extract third string:
frstC = secCh + Len("/IPE")
secCh = InStr(frstC, chngTxt, "F.CSV")
thrdStr = Mid(chngTxt, frstC, secCh - frstC)
'Debug.Print "_" & thrdStr & "_": 'Stop 'OK
'extract fourth string:
frstC = InStr(secCh + Len("F.CSV"), chngTxt, "files\IPE")
secCh = InStr(frstC + Len("files\IPE"), chngTxt, "F.CSV")
fourStr = Mid(chngTxt, frstC + Len("files\IPE"), secCh - (frstC + Len("files\IPE")))
'Debug.Print "_" & fourStr & "_": Stop 'OK
chngText = Replace(Replace(chngTxt, "/" & frstStr & "/", "/" & sh.Range("A1").value & "/"), "/" & secStr & "/", "/" & sh.Range("A2").value & "/")
chngText = Replace(Replace(chngText, thrdStr & "F.C", sh.Range("A3").value & "F.C"), fourStr & "F.C", sh.Range("A4").value & "F.C")
Debug.Print chngText 'just to visually check that the string to be changed has been correctly changed
'replace the changed string in the original file text:
strText = Replace(strText, chngTxt, chngText) 'the changed whole string!
'Debug.Print strText
Dim scriptFold As String, pathToFile As String
If Dir(sPath & "Scripts", vbDirectory) = "" Then MkDir sPath & "Scripts" 'create "Scripts" folder if it does not exist
pathToFile = sPath & "Scripts\" & sFile
Open pathToFile For Output As #1
Print #1, strText
Close #1
End Sub
After testing it and concluding that it fits what you want, you can overwrite the existing file in the last lines. I mean, pathToFile must be sPath & sFile. And, of course, in such a case the sequence using a different folder should be eliminated.
Check out the vba Replace() function, You can set multiple replaces by:
Replace(Replace(Replace(put here 3 replace conditions)))
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/replace-function

Macro error when running script with project or library

I am trying to rename my folder files. However, every time I try to run the below script, I see an error:
can’t find project or library on Sub and set FSO
How can I fix it?
Sub renameFiles()
'
' renamefiles Macro
'
Dim folderpath As String
Dim file_name As String
Dim target_folder As String
Dim trim_file_name As String
Set fso = CreateObject("Scripting.FileSystemObject")
folderpath = ThisWorkbook.Sheets("File Converter").Range("C7").Value & "\"
newFileName = Range("").Value
fileCount = 0
filePath = Dir$(folderpath & "*.*")
Do While filePath <> ""
fileCount = fileCount + 1
fileNames = fileNames & filePath & "," & newFileName & CStr(fileCount) & "." &
fso.GetExtensionName(filePath) & ","
filePath = Dir$
Loop
Dim renameFiles() As String
renameFiles = Split(fileNames, ",")
For fileCount = 0 To UBound(renameFiles) - 2 Step 2
Name folderpath & renameFiles(fileCount) As folderpath & renameFiles(fileCount + 1)
Next
End Sub

How do you use MATCH in a loop?

I keep getting an error in the below code and its likely incorrect syntax.
I have tried replacing this line
IsInArray(pdfname, arNames(i)) = True
with this
Application.worksheetfunction.match(pdfname, arNames(i)) = True
but its not working.
Sub OpenPdf()
On Error GoTo OpenPdf_Error
Dim pdfname As String
Dim pdf
Const sPath = "S:\RA QUOTES 2019"
Dim FName As String
Dim arNames() As String
Dim myCount As Integer
Dim i As Integer
FName = Dir("S:\RA QUOTES 2019\*.pdf*")
Do Until FName = ""
myCount = myCount + 1
ReDim Preserve arNames(1 To myCount)
arNames(myCount) = FName
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = "PLQ" & pdfname
For i = 1 To UBound(arNames)
If IsInArray(pdfname, arNames(i)) = True Then
ThisWorkbook.FollowHyperlink sPath & arNames(i)
End If
Next i
On Error GoTo 0
Exit Sub
OpenPdf_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure OpenPdf"
End Sub
This will work for an exact match using a dictionary (a collection data type which has the .Exists property which allows you to check if a key within the dictionary exists without looping through everytime).
Option Explicit
Sub OpenPdf()
Dim pdfname As String
Dim DictPDF As New Scripting.Dictionary 'Needs Microsoft Scripting Runtime
Const sPath = "S:\RA QUOTES 2019\"
Dim FName As String
Dim i As Integer
FName = Dir(sPath & "*.pdf*")
Do While FName <> vbNullString
'add the name into the dictionary
DictPDF.Add Left(LCase(pdfname), 7), 1 'Left will get the first 7 characters from the left to the name
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = LCase("PLQ" & pdfname)
'Check if the name is in the dictionary I used LCase because dictionaries are case sensitive,
'so everything in low case to avoid problems.
If DictPDF.Exists(pdfname) Then
ThisWorkbook.FollowHyperlink sPath & DictPDF(pdfname)
Else
MsgBox pdfname & " was not found."
End If
End Sub
Sub OpenPdf()
On Error GoTo OpenPdf_Error
Dim pdfname As String
Dim pdf
Const sPath = "S:\RA QUOTES 2019\"
Dim FName As String
Dim arNames() As String
Dim myCount As Integer
Dim i As Integer
FName = Dir("S:\RA QUOTES 2019\*.pdf*")
Do Until FName = ""
myCount = myCount + 1
ReDim Preserve arNames(1 To myCount)
arNames(myCount) = FName
FName = Dir
Loop
pdfname = Application.InputBox("Enter the pdf you are looking for")
pdfname = "PLQ" & pdfname
For i = 1 To UBound(arNames)
If InStr(1, arNames(i), pdfname, vbTextCompare) Then
MsgBox (arNames(i))
ThisWorkbook.FollowHyperlink sPath & arNames(i)
End If
Next i
On Error GoTo 0
Exit Sub
OpenPdf_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure
OpenPdf"
End Sub

Rename files in folder with various extensions according to worksheet list

I need to rename 300+ files of various extensions in 1 folder. I have a list of file names without extension in column B, and final names in column A of my Excel worksheet. My code works, but renames files in wrong order. Filenames contain dots, like
А1.14.12.2016
Here is the code:
Option Explicit
Sub test2()
Dim x As String
Dim fName As String
Dim oldPath As String
Dim newPath As String
Dim i As Long
oldPath = "\\Plu20\dfs01\USMiKAR\docs\"
newPath = oldPath & "New\"
On Error Resume Next
x = GetAttr(newPath) And 0
If Err.Number <> 0 Then MkDir newPath
fName = Dir(oldPath & "*.*")
With ActiveSheet
Do While Len(fName) > 0
i = i + 1
FileCopy oldPath & fName, newPath & .Cells(i, 1) & Mid$(fName, InStrRev(fName, "."))
'.Cells(i, 2) = oldPath & fName 'ïðîâåðêà
'Kill oldPath & fName 'óäàëåíèå ñòàðûõ
fName = Dir
Loop
End With
End Sub
Untested, but you can do something like this:
Sub test2()
Dim x As String
Dim fName As String
Dim oldPath As String
Dim newPath As String
Dim i As Long
Dim fso As Object, f As Range
Set fso = CreateObject("scripting.filesystemobject")
oldPath = "\\Plu20\dfs01\USMiKAR\docs\"
newPath = oldPath & "New\"
If Dir(newPath, vbDirectory) = "" Then MkDir newPath
fName = Dir(oldPath & "*.*")
With ActiveSheet
Do While Len(fName) > 0
'find the current filename
Set f = .Columns(2).Find(fso.getbasename(fName), lookat:=xlWhole)
If Not f Is Nothing Then
'got a match
FileCopy oldPath & fName, _
newPath & f.Offset(0, -1).Value & "." & fso.getextensionname(fName)
'.Cells(i, 2) = oldPath & fName 'ïðîâåðêà
'Kill oldPath & fName 'óäàëåíèå ñòàðûõ
Else
'no match...
Debug.Print "filename:" & fName & " was not matched"
End If
fName = Dir
Loop
End With
End Sub

Resources