How to replace double quotes to a space in VBScript? - regex

I need open the CSV file, replace the double quotes with space and save the new file with txt extension.
I have tried this VBScript code but the first file Output_D1.txt is empty, the Output_D2.txt file contains rows of the Output_D1.csv, the Output_D3.txt file contains rows of the Output_D2.csv... etc.
How to do resolve this ?
nArr = Array("D1", "D2", "D3", "D4", "D5", "D6")
Set reP = new RegExp
reP.Pattern = "\"""
For I = 0 To UBound(nArr)
InFilename = "Output_" & nArr(I) & ".csv"
Set FILE1 = CreateObject("scripting.FileSystemObject")
Set infile = FILE1.OpenTextFile(InFileName, 1, False)
strg = reP.Replace(strg, " ")
InFilenameNew = "Output_" & nArr(I) & ".txt"
Set Outfile = File1.CreateTextFile(inFileNameNew, 1, False)
Outfile.Write(strg)
strg = infile.ReadAll
infile.Close
Next

Try this:
You need to set the RegExp global option to replace all occurences of quotes
You need the full path to the CSV files (see rootFolder for a hard-coded example)
ReadAll is used in the wrong place (it needed to be before the RegExp replace!)
Option Explicit
dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
dim rootFolder : rootFolder = "C:\Temp\"
dim nArr : nArr = Array("D1", "D2", "D3", "D4", "D5", "D6")
dim i, inFilename, inFilenameNew, infile, outfile, filecontent
Const ForReading = 1, ForWriting = 2
dim reP : Set reP = new RegExp
reP.Global = true
reP.Pattern = "\"""
For i = 0 To UBound(nArr)
inFilename = rootFolder & "Output_" & nArr(i) & ".csv"
inFilenameNew = rootFolder & "Output_" & nArr(i) & ".txt"
if (fso.FileExists(inFilename)) Then
Set infile = fso.OpenTextFile(InFileName, ForReading)
filecontent = infile.ReadAll
filecontent = reP.Replace(filecontent, " ")
infile.Close
Set infile = Nothing
Set outfile = fso.CreateTextFile(inFileNameNew, True)
outfile.Write(filecontent)
outfile.Close
Set outfile = Nothing
End If
Next
Set reP = Nothing
Set fso = Nothing

Related

Regex Adding Unnecessary Spaces During Replace

I'm currently having difficulty with a VBScript I'm writing that contains several read and replaces from a text file. The expression I'm using finds the expression and replaces it, but adds three tab spaces afterwords, making the original line below it mess up the formatting. Here's a picture of what I'm talking about:
Here's a pastebin of the before and after, rather than an image:
https://pastebin.com/Uw3H59QK
Here's my RegExp code:
Set fso = CreateObject("Scripting.FileSystemObject")
Dim strPath
strPath = SelectFolder( "" )
If strPath = vbNull Then
WScript.Echo "Script Cancelled - No files have been modified" 'if the user cancels the open folder dialog
Else
WScript.Echo "Selected Folder: """ & strPath & """" 'prompt that tells you the folder you selected
End If
Function SelectFolder( myStartFolder )
Dim objFolder, objItem, objShell
Dim objFolderItems
On Error Resume Next
SelectFolder = vbNull
Set objShell = CreateObject( "Shell.Application" )
Set objFolder = objShell.BrowseForFolder( 0, "Please select the .dat file location folder", 0, myStartFolder)
set objFolderItems = objFolder.Items
If IsObject( objFolder ) Then SelectFolder = objFolder.Self.Path
Set objFolder = Nothing
Set objShell = Nothing
On Error Goto 0
End Function
Set re = New RegExp 'Replacing Position Lines
re.Pattern = "Pos = \((.*)\)"
re.Global = True
re.IgnoreCase = True
For Each f in fso.GetFolder(strPath).Files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll 'reading the text file
f.OpenAsTextStream(2).Write re.Replace(text, """Position"" : mathutils.Vector(($1)),")
count = count + 1
End If
Next
Set reAngles = New RegExp 'Replacing Angles
reAngles.Pattern = "Angles = \((.*)\)"
reAngles.Global = True
reAngles.IgnoreCase = True
For Each f in fso.GetFolder(strPath).files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll
f.OpenAsTextStream(2).Write reAngles.Replace(text, """Angles"" : mathutils.Vector(($1)),")
End If
Next
Set reNames = New RegExp 'Replacing Names
reNames.Pattern = "Name = (.*)"
reNames.Global = True
'reNames.Multiline = True
reNames.IgnoreCase = True
For Each f in fso.GetFolder(strPath).files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll
f.OpenAsTextStream(2).Write reNames.Replace(text, """Name"" : ""$1"",")
End If
Next
My best guess is that the wildcard is grabbing more info than needed...but I'm unsure how to fix that. I used a lot of these expressions in Notepad++ so I was hoping to translate them to a VBS easily!

Extract all lines of a file between 2 delimiters without them in VBScript Regex

I try to Extract all lines of a file between 2 strings in another file and without these delimiters.
Example:
[General]
Description=Description
[extractSection]
First Line extracted. It is not an ini section
Last Line extracted
[OthersSection]
blablabla
It seems to work with this script. One of my first vbs.
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
If objFS.FileExists(strTemp) Then objFS.DeleteFile(strTemp)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If isReading = True Then
If instr(strline,"[") Then
Set objOutFile = objFS.CreateTextFile(strTemp, True)
objOutFile.Write(strLine1)
objOutFile.Close
Exit Do
Else
strline1 = strline1 & strline & vbNewLine
End If
Else
If instr(LCase(strline),"[extractsection]") Then
isReading = True
End If
End If
Loop
objFile.Close
But it seems not very optimized, I have files up to 8Mb.
I would like to try the same thing using Regex. I never used, I have to learn.
I have this as beginning: \[extractsection\]([\s\S]*?)\[[\s\S]
But I would like without the delimiters.
Thank you Wiktor. It seems it is OK with (?<=\[extractSection\]\n)(.*(?:\n(?!\[).*)*) Just let me know what is best (Ram | speed) vs my ReadLine script on top, please
You can give a try for this vbscript without a Regex :
Option Explicit
Dim strFile,strTemp,Full_String,First_Delimiter,Second_Delimiter,Extracted_Data
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
Full_String = ReadFileText(strFile)
First_Delimiter = "[extractSection]"
Second_Delimiter = "[OthersSection]"
Extracted_Data = String_Between(Full_String,First_Delimiter,Second_Delimiter)
wscript.echo Extracted_Data
Write2File Extracted_Data,strTemp
'************************************************************************************************
Function String_Between(ByVal Full_String, ByVal First_Delimiter, ByVal Second_Delimiter)
Dim Pos,Pos2
Pos = InStr(Full_String, First_Delimiter)
Pos2 = InStr(Full_String, Second_Delimiter)
If Pos = 0 Or Pos2 = 0 Then
String_Between = "Missing Delimiter"
Exit Function
End If
String_Between = Mid(Full_String, Pos + Len(First_Delimiter), Pos2 - (Pos + Len(First_Delimiter)))
End Function
'***********************************************************************************************
Function ReadFileText(sFile)
Dim objFSO,oTS,sText
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(sFile) Then
MsgBox "CRITICAL ERROR " & VbCrLF & "The File "& DblQuote(sFile) &_
" dosen't exists !",VbCritical,"CRITICAL ERROR"
Wscript.Quit
Else
Set oTS = objFSO.OpenTextFile(sFile)
sText = oTS.ReadAll
oTS.close
set oTS = nothing
Set objFSO = nothing
ReadFileText = sText
End if
End Function
'*********************************************************************************************
Sub Write2File(strText,OutputFile)
Dim fs,ts
Const ForWriting = 2
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(OutputFile,ForWriting,True)
ts.WriteLine strText
ts.Close
End Sub
'*********************************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************************************
And this one with RegEx
Option Explicit
Dim strFile,strTemp,Full_String,First_Delimiter,Second_Delimiter,Extracted_Data
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
Full_String = ReadFileText(strFile)
First_Delimiter = "[extractSection]"
Second_Delimiter = "[OthersSection]"
Extracted_Data = ExtractData(Full_String,First_Delimiter,Second_Delimiter)
wscript.echo Extracted_Data
Write2File Extracted_Data,strTemp
'***********************************************************************************************
Function ExtractData(Full_String,Start_Delim,End_Delim)
Dim fso,f,r,Matches,Contents,Data
Start_Delim = Replace(Start_Delim,"[","\[")
Start_Delim = Replace(Start_Delim,"]","\]")
End_Delim = Replace(End_Delim,"[","\[")
End_Delim = Replace(End_Delim,"]","\]")
Set r=new regexp
r.pattern = "(?:^|(?:\r\n))(:?"& Start_Delim &"\r\n)([\s\S]*?)(?:\r\n)(?:"& End_Delim &")"
Set Matches = r.Execute(Full_String)
If Matches.Count > 0 Then Data = Matches(0).SubMatches(1)
ExtractData = Data
End Function
'***********************************************************************************************
Function ReadFileText(sFile)
Dim objFSO,oTS,sText
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(sFile) Then
MsgBox "CRITICAL ERROR " & VbCrLF & "The File "& DblQuote(sFile) &_
" dosen't exists !",VbCritical,"CRITICAL ERROR"
Wscript.Quit
Else
Set oTS = objFSO.OpenTextFile(sFile)
sText = oTS.ReadAll
oTS.close
set oTS = nothing
Set objFSO = nothing
ReadFileText = sText
End if
End Function
'*********************************************************************************************
Sub Write2File(strText,OutputFile)
Dim fs,ts
Const ForWriting = 2
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(OutputFile,ForWriting,True)
ts.WriteLine strText
ts.Close
End Sub
'*********************************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************************************

How to write output file after all regexp match?

I have text file containing line starts with mmrk.
I want to extract all lines and write output.
I am trying following code. (I know this is not correct method, Just to show what I want.)
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso, MyFile, FileName, Text
dim oFile, strPath
Set fso = CreateObject("Scripting.FileSystemObject")
FileName = "C:\Users\user\Desktop\2.rtf"
strPath = "C:\Users\user\Desktop\1.txt"
Set MyFile = fso.OpenTextFile(FileName, ForReading)
Do While MyFile.AtEndOfStream <> True
Text = MyFile.ReadAll
Loop
Set regEx_ = new regExp
With regEx_
.Global = True
.MultiLine = True
.IgnoreCase = True
'Do some regex find and replace(works perfectly)
.Pattern = "mmrk.*"
If regEx_.Test(Text) Then
Set oFile = fso.OpenTextFile(strPath, 2, True, -1)
oFile.Write Text
oFile.Close
End If
End With
MyFile.Close
Edit
I need to get lines from string.
I am currently first saving temp file from string and use Nefariis's answer to do the rest. Is there any direct method.
I think there are easier ways of doing this that do not involve a regex.
In VBScript:
FileName = "C:\Users\user\Desktop\2.rtf"
strPath = "C:\Users\user\Desktop\1.txt"
Set inFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(FileName)
Set outFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(strPath,True)
Do Until inFile.AtEndOfStream
Dim line : line = inFile.Readline
If inStr(line, "mmrk.") = 1 then outFile.writeLine(line)
Loop
inFile.Close
outFile.Close
In VB.Net
Dim inFile as String() = File.ReadAllLines("inFileName")
Dim sw As StreamWriter = New StreamWriter("OutFileName", True)
For Each line As String In inFile
If line.StartsWith("mmrk.") Then sw.WriteLine(line)
Next
sw.Close()
This reads the file in, then goes through it looking for lines the start with "mmrk.", and saves the line into a seperate text file that you specifiy.

Extract text from last line in log file using vbscript

I have a log file formatted as such:
AssetTag USERNAME Date Time Local
abc123456 Sam 10/15/2015 8:22:14am Local
abc87363 Joe 10/15/2015 8:55:59am Local
I need to extract the USERNAME from the last line of the log file using a batch file. IE: Extract 'Joe' from the last line.
I am thinking some sort regex to find the first space and select the text between the first space and the next space...that should be 'Joe'...
I am using this to extract the last line:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\logs\UserAudit.log", ForReading)
Do Until objFile.AtEndOfStream
strNextLine = objFile.ReadLine
If Len(strNextLine) > 0 Then
strLine = strNextLine
End If
Loop
objFile.Close
Wscript.Echo strLine
EDIT: it is actually 2 tabs that separate the assettag and the username and 1 tab that separate the username and the date
I figured it out with a little more google...
What the below script does..
1) Prompt for asset tag
2) reads last line from log file, extracts username
3)looks up username in AD to find the Staff Name
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
strAsset= INPUTBOX("Please enter the Asset Tag:")
strLog = "\\" & strAsset & "\C$\Logs\UserAudit.log"
'Set objFile = objFSO.OpenTextFile("C:\logs\UserAudit.log", ForReading)
Set objFile = objFSO.OpenTextFile(strLog, ForReading)
Do Until objFile.AtEndOfStream
strNextLine = objFile.ReadLine
If Len(strNextLine) > 0 Then
strLine = strNextLine
End If
Loop
objFile.Close
intStart = InStr(strLine, " ")
If intStart <> 0 Then
intStart = intStart + 2
strText = Mid(strLine, intStart, 250)
For i = 1 to Len(strText)
If Mid(strText, i, 1) = " " Then
Exit For
Else
strData = strData & Mid(strText, i, 1)
End If
Next
End If
'Username from Log file
Wscript.Echo strData
'Lookup Account for Staff Name
SET objSystemInfo = CREATEOBJECT("ADSystemInfo")
strDomain = objSystemInfo.DomainShortName
strUser = strData
wscript.echo GetUserDN(strUser,strDomain)
strAD = GetUserDN(strUser,strDomain)
intStart = InStr(strAD, "CN=")
If intStart <> 0 Then
intStart = intStart + 3
strText = Mid(strAD, intStart, 250)
For i = 1 to Len(strText)
If Mid(strText, i, 3) = ",OU" Then
Exit For
Else
strName = strName & Mid(strText, i, 1)
End If
Next
End If
wScript.echo strName
FUNCTION GetUserDN(BYVAL strUserName,BYVAL strDomain)
SET objTrans = CREATEOBJECT("NameTranslate")
objTrans.Init 1, strDomain
objTrans.SET 3, strDomain & "\" & strUserName
strUserDN = objTrans.GET(1)
GetUserDN = strUserDN
END FUNCTION
'Cleanup
intStart=""
strUser=""
strDomain=""
strName=""
strAD=""
strText=""
strLine=""
strNextLine=""

How do I Update only Sheet1 of a workbook template...?

I have this code to copy data from a range in one workbook to Sheet1 of a specific template. ( The data from Sheet1 then populates a second sheet in the template file.) Each file is created and named for the names in the range “names1”.
This seems to work perfectly, but I need it to do two other things:
Firstly, I need it to check and see if a file has already been created with the filename, and if so, not to overwrite it, or prompt for saving.
Secondly, and most importantly, I need to find a way to have it check for an existing file, and then ONLY overwrite Sheet1 with the info from above, WITHOUT changing anything on any of the other sheets in the file, and then save and close the file. And then continue checking all the other names in the file, and either creating a new file from the template (as my code already does) OR updating only sheet1 and saving/closing the file.
I have searched for help on this, but with my limited VBA knowledge, I’m not sure where to put the add-ins and what syntax to use. Any help would be greatly appreciated!!!
Here is my working code:
Sub Smart1()
Dim src As Workbook
Dim dst As Workbook
SavePath = ActiveWorkbook.Path
Set src = ActiveWorkbook
For Each C In Range("Names1")
i = C.Row
Name = Cells(i, 44).Value
PSFFAll = Cells(i, 45).Value
CLSFall = Cells(i, 46).Value
CLSWin = Cells(i, 47).Value
CLSEnd = Cells(i, 48).Value
WWRFall = Cells(i, 49).Value
WWRWin = Cells(i, 50).Value
WWREnd = Cells(i, 51).Value
DORFWin = Cells(i, 52).Value
DORFEnd = Cells(i, 53).Value
AccWin = Cells(i, 54).Value
AccEnd = Cells(i, 55).Value
fname = Cells(i, 44).Value & ".xlsx"
Workbooks.Open FileName:=ThisWorkbook.Path & "\Smart1.xlsx"
With Workbooks("Smart1.xlsx").Worksheets("Sheet1")
.Range("a2").Value = Name
.Range("B2").Value = PSFFAll
.Range("C2").Value = CLSFall
.Range("D2").Value = CLSWin
.Range("E2").Value = CLSEnd
.Range("F2").Value = WWRFall
.Range("G2").Value = WWRWin
.Range("H2").Value = WWREnd
.Range("I2").Value = DORFWin
.Range("J2").Value = DORFEnd
.Range("K2").Value = AccWin
.Range("L2").Value = AccEnd
End With
ActiveWorkbook.saveas FileName:=SavePath & "\" & fname
ActiveWorkbook.Close True
On Error Resume Next
Next C
End Sub
This is an answer only for your first question. Use this to check if a file exists.
Sub saveme()
SavePath = "D:\folder"
fname = "test.xls"
fullsavepath = SavePath & "\" & fname
On Error Resume Next
If Dir(fullsavepath) <> "" Then
Open fullsavepath For Binary Access Read Lock Read As #1: Close #1
End If
If Err.Number <> 0 Then
If MsgBox("A file with the name '" & fname & "' is already open." & vbCrLf & _
"Do you want to replace it?", vbYesNo + vbQuestion + vbDefaultButton2, _
"Microsoft Excel") = vbYes Then
Application.DisplayAlerts = False
Workbooks(fname).Close savechanges:=False
ActiveWorkbook.SaveAs Filename:=fullsavepath
Application.DisplayAlerts = True
End If
Else
ActiveWorkbook.SaveAs Filename:=fullsavepath
End If
Err.Clear
End Sub
The important part is:
If Dir(fullsavepath) <> "" Then
Open fullsavepath For Binary Access Read Lock Read As #1: Close #1
End If
Here is the answer!
Thanks to Tweedle!
Sub Smart1()
Dim src As Workbook
Dim dst As Workbook
SavePath = ActiveWorkbook.Path
Set src = ActiveWorkbook
For Each C In Range("Names1")
i = C.Row
Name = Cells(i, 44).Value
PSFFAll = Cells(i, 45).Value
CLSFall = Cells(i, 46).Value
CLSWin = Cells(i, 47).Value
CLSEnd = Cells(i, 48).Value
WWRFall = Cells(i, 49).Value
WWRWin = Cells(i, 50).Value
WWREnd = Cells(i, 51).Value
DORFWin = Cells(i, 52).Value
DORFEnd = Cells(i, 53).Value
AccWin = Cells(i, 54).Value
AccEnd = Cells(i, 55).Value
fname = Cells(i, 44).Value & ".xlsx"
If Dir(SavePath & "\" & fname) = "" Then
'Filename does not exist, then use template
Set dst = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Smart1.xlsx")
Else
'File already exists, then use existing & update
Set dst = Workbooks.Open(Filename:=SavePath & "\" & fname)
End If
With dst.Worksheets("Sheet1")
.Range("a2").Value = Name
.Range("B2").Value = PSFFAll
.Range("C2").Value = CLSFall
.Range("D2").Value = CLSWin
.Range("E2").Value = CLSEnd
.Range("F2").Value = WWRFall
.Range("G2").Value = WWRWin
.Range("H2").Value = WWREnd
.Range("I2").Value = DORFWin
.Range("J2").Value = DORFEnd
.Range("K2").Value = AccWin
.Range("L2").Value = AccEnd
End With
Application.DisplayAlerts = False
dst.Close True, SavePath & "\" & fname
Application.DisplayAlerts = True
On Error Resume Next
Next C
End Sub