I have a text file which is as below
"asdf","dfgv","asd","sdgs"
"sfgf","xcbvcvb","gsfgf","sdvxc"
"asfdfg","fbgdfg","sdfsd","fdg"
"bdg","sdf","fgfdg","fcg"
"sdf","fbcx","ckvknm","fklf"
"xv","asds","r","cxv"
But I want the output which looks like this
asdf,dfgv,asd,sdgs
sfgf,xcbvcvb,gsfgf,sdvxc
asfdfg,fbgdfg,sdfsd,fdg
bdg,sdf,fgfdg,fcg
sdf,fbcx,ckvknm,fklf
xv,asds,r,cxv
I have gone through the below link and changed the code from Write #1 to Print #1. But the problem is, I want this file to be bulk inserted to sql server. Hence, using a print doesn't help me.
Remove double quotation from write statement in vba
You can use the Replace function to strip out all the quote characters:
result = Replace(original_string, string_you_want_to_remove, replace_with )
example = Replace(original_string , CHR(34), "")
Thanks everyone, but I have found another way of removing double quotes by using the batch script which is as below.
set objRe = new RegExp
objRE.Pattern = "\"""
objRE.Global = True
strFileName = "Source.txt"
set objFS = CreateObject("Scripting.FileSystemObject")
set objTS = objFS.OpenTextFile(strFileName)
strFileContents = objTS.ReadAll
objTS.Close
strNewContents = objRE.replace(strFileContents,"")
set objWS = objFS.CreateTextFile("Results.txt")
objWS.Write StrNewContents
objWS.close
Just do a REPLACE()
Replace(<SourceString>, """, "")
Try this code:
Sub CleanFile()
Dim fileName, FSO, rfile, wfile As Variant
Dim line As String, dotAt As Integer, newFileName As String
fileName = Application.GetOpenFilename(, , "Load Excel File", , False)
If fileName = "False" Then
MsgBox "No file chosen"
Exit Sub
End If
dotAt = InStrRev(fileName, ".")
newFileName = Left(fileName, dotAt - 1) + " - CLEAN.txt"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set rfile = FSO.OpenTextFile(fileName, 1) 'connection for reading
Set wfile = FSO.OpenTextFile(newFileName, 8, True, -1) 'connection for writing
Do Until rfile.AtEndOfStream
line = rfile.ReadLine
wfile.WriteLine Replace(line, """", "")
Loop
End Sub
Related
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.
I want to write a code that will open the file path and within this folder the user can select his own folder. I only seem able to find a "general" code to open a folder.
With wbtarget.Sheets("Data")
strPathName = Application.GetOpenFilename()
If strPathName = "False" Then
Exit Sub
End If
Set wbsource = Workbooks.Open(strPathName, 0)
.Range("A1:AL10000").Value = wbsource.Sheets(1).Range("A1:AL10000").Value
wbsource.Close (False)
End With
or open a specific file.
folder_path = CStr("C:\Users\peter\Documents\me")
file_name = CStr("report.xlsm")
StrResource = folder_path & "\" & file_name
thank you for your help.
I use this function to let the user browse for a folder instead of a file. I don't remember where I found it.
It uses the Shell.BrowseForFolder method.
Set InitPath to a string <> "", e.g. "D:\Files", to limit the folder tree the user can choose from.
Public Function GetFolderName(Caption As String, InitPath As String) As String
Dim AppShell As Object
Dim BrowseDir As Variant
Dim sPath As String
Set AppShell = CreateObject("Shell.Application")
If InitPath <> "" Then
Set BrowseDir = AppShell.BrowseForFolder(0, Caption, &H11, (InitPath))
Else
' 17 = root folder is "My Computer"
Set BrowseDir = AppShell.BrowseForFolder(0, Caption, &H11, 17)
End If
sPath = ""
On Error Resume Next
sPath = BrowseDir.Items().Item().Path
GetFolderName = sPath
End Function
I read an Excel spreadsheet row by row and for each row create a textfile including information from the columns.
From time to time there is foreign text in some of the spreadsheet cells. In the debugger the foreign text appears as '?' question marks. It fails when trying to write these question marks to the text file.
This is a snippet of the code that reads the values from a row to a string array
Set oFS = CreateObject("Scripting.Filesystemobject")
For Each rID In oSh.UsedRange.Columns("A").Cells
For Each rValue In oSh.UsedRange.Rows(rowCount).Cells
ReDim Preserve columnValues(columnCount)
columnValues(columnCount) = rValue
columnCount = columnCount + 1
Next
Next
This is the code which writes to a text file
sFNText = sMakeFolder & "\" & rID.Value & ".txt"
Set oTxt = oFS.OpenTextFile(sFNText, 2, True)
For i = 0 To UBound(columnTitles)
oTxt.Write columnTitles(i) & ": " & columnValues(i) & vbNewLine
Next i
oTxt.Close
I have experimented with changing the format of opentextfile and also using AscW and ChrW to convert to and from ansi.
EDIT: In particular I am trying to read in Greek symbols (pi, omega etc.) and write them back out to a textfile. I have used the
StrConv(Cells(1, 1), vbUnicode)
method that was detailed in How can I create text files with special characters in their filenames and have got that example working. It seems now a problem with writing this to a textfile. nixda's example seems to work in isolation when using his Print command, however when I try
otxt.Write
to write my stored variable to a textfile it writes out garbage, as opposed to the print method which produces the correct result. Looking at the debugger both variables are stored identically (print method + write), so I believe it is now down to the output method (otxt.Write) which is converting the stored variable into garbage. I have tried using the -1 & -2 options for OpenTextFile - both producing garbage results.
I have the following sheet:
and the following code:
Sub writeUnicodeText()
Dim arr_Strings() As String
i = 0
For Each oCell In ActiveSheet.Range("A1:A4")
ReDim Preserve arr_Strings(i)
arr_Strings(i) = oCell.Value
i = i + 1
Next
Set oFS = CreateObject("Scripting.Filesystemobject")
Set oTxt = oFS.OpenTextFile("C:\users\axel\documents\test.txt", 2, True, -1)
For i = 0 To UBound(arr_Strings)
oTxt.Write arr_Strings(i) & vbNewLine
Next i
oTxt.Close
End Sub
This produces the following file:
This is the code I use to write to a text. I've tried many methods and this has worked the best.
Sub ProcessX()
FName1 = "Location of File"
txtStrngX = OpenTextFileToString2(FName1)
end sub
Public Function OpenTextFileToString2(ByVal strFile As String) As String
Dim hFile As Long
hFile = FreeFile
Open strFile For Input As #hFile
OpenTextFileToString2 = Input$(LOF(hFile), hFile)
Close #hFile
End Function
As for reading in from rows just be sure to set your variable to a string when compiling and any method should work fine.
sorry. That's reading from a text. Here is writing.
Public Function RecordsetToText(rs As Object, Optional FullPath _
As String, Optional ValueDelimiter As String = " ") As Boolean
'PURPOSE: EXPORTS DATA FROM AN ADO RECORDSET TO A TEXT FILE
'PARAMETERS:
'RS: Recordset to Export. Open the recordset before
'passing it to this function
'FullPath (Optional): FullPath of text file.
'if not specified, the function uses app.path +
'rs.txt
'ValueDelmiter (Optional): String to delimiter
'values within a row. If not specified, an tab
'is used
'RETURNS: True if successful, false if an error occurs
'COMMENTS: Rows are delimited by a carriage return
Dim sFullPath As String
Dim sDelimiter As String
Dim iFileNum As Integer
Dim lFieldCount As Long
Dim lCtr As Long
Dim oField As ADODB.Field
On Error GoTo ErrorHandler:
If RecordSetReady(rs) = False Then Exit Function
sDelimiter = ValueDelimiter
If FullPath = "" Then
sFullPath = App.Path
If Right(sFullPath, 1) <> "\" Then sFullPath = _
sFullPath & "\"
sFullPath = sFullPath & "rs.txt"
Else
sFullPath = FullPath
End If
iFileNum = FreeFile
Open sFullPath For Output As #iFileNum
With rs
lFieldCount = .Fields.Count - 1
On Error Resume Next
.MoveFirst
On Error GoTo ErrorHandler
For lCtr = 0 To lFieldCount
Set oField = .Fields(lCtr)
If lCtr < lFieldCount Then
Print #iFileNum, oField.Name & sDelimiter;
Else
Print #iFileNum, oField.Name
End If
Next
Do While Not .EOF
For lCtr = 0 To lFieldCount
Set oField = .Fields(lCtr)
If lCtr < lFieldCount Then
Print #iFileNum, oField.Value & sDelimiter;
Else
Print #iFileNum, oField.Value
End If
Next
.MoveNext
Loop
End With
RecordsetToText = True
ErrorHandler:
On Error Resume Next
Close #iFileNum
End Function
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
I'm working on this code
Dim strFirm,soNumber,strValues,arrStr,strCitrix,NewText,text
strFirm = "Gray"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",1,True)
Do while not objTextFile.AtEndOfStream
arrStr = Split(objTextFile.ReadLine, ",")
If arrStr(0) = strFirm Then
soNumber = arrStr(1)
Exit Do
End If
Loop
objTextFile.Close
strCitrix = soNumber + 1
MsgBox "Cloud Client " & strFirm & " is now using " & strCitrix & " Citrix licenses."
NewText = Replace(soNumber, soNumber, strCitrix)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",2,True)
objTextFile.Writeline NewText
objTextFile.Close
However when I run the code the replacement wipes out all the text on my file with the exception of the number I'm writing.
What I want it to do is to leave all the other text in place and only change the one specified variable.
Example
Client1,5
Client2,7
Client3,12
Gray,6
Client4,9
Client5,17
Client6,8
And after running the script
Client1,5
Client2,7
Client3,12
Gray,7
Client4,9
Client5,17
Client6,8
Can anyone point out what I'm doing wrong?
Thank you in advance for your help.
Your output file contains only the number you're changing, because you extract just that number from the text you read from the file:
soNumber = arrStr(1)
increment it by one:
strCitrix = soNumber + 1
replace the number in soNumber (which contains only the number anyway) with the incremented number:
NewText = Replace(soNumber, soNumber, strCitrix)
and then write only that new number back to the file:
objTextFile.Writeline NewText
To preserve those parts of the original content that you want to keep you need to write them back to the file as well, not just the modified content.
If you read the source file line-by-line (which is a good idea when processing large files, as it avoids memory exhaustion), you should write the output to a temporary file as you go:
Set inFile = objFSO.OpenTextFile("cloud.csv")
Set outFile = objFSO.OpenTextFile("cloud.csv.tmp", 2, True)
Do while not objTextFile.AtEndOfStream
line = inFile.ReadLine
arrStr = Split(line, ",")
If arrStr(0) = strFirm Then
soNumber = CInt(arrStr(1))
outFile.WriteLine arrStr(0) & "," & (soNumber + 1)
Else
outFile.WriteLine line
End If
Loop
inFile.Close
outFile.Close
and then replace the original file with the modified one:
objFSO.DeleteFile "cloud.csv", True
objFSO.MoveFile "cloud.csv.tmp", "cloud.csv"
However, if your input file is small, it's easier to just read the entire file, process it, and overwrite the file with the modified content:
text = Split(objFSO.OpenTextFile("cloud.csv").ReadAll, vbNewLine)
For i = 0 To UBound(text)
If Len(text(i)) > 0 Then
arrStr = Split(text(i), ",")
If arrStr(0) = strFirm Then
soNumber = CInt(arrStr(1))
text(i) = arrStr(0) & "," & (soNumber + 1)
End If
End If
Next
objFSO.OpenTextFile("cloud.csv", 2, True).Write Join(text, vbNewLine)
The Len(text(i)) > 0 check is for skipping over empty lines (including a trailing newline at the end of the file), because empty strings are split into empty arrays, which would in turn make the check arrStr(0) = strFirm fail with an index out of bounds error.
For short file, I'd prefer a .ReadAll()/RegExp strategy:
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim sFirma : sFirma = "Gray"
Dim sFSpec : sFSpec = "..\data\cloud.csv"
Dim sAll : sAll = oFS.OpenTextFile(sFSpec).ReadAll()
Dim reCut : Set reCut = New RegExp
reCut.Global = True
reCut.Multiline = True
reCut.Pattern = "^(" & sFirma & ",)(\d+)"
Dim oMTS : Set oMTS = reCut.Execute(sAll)
If 1 = oMTS.Count Then
oFS.CreateTextFile(sFSpec).Write reCut.Replace(sAll, "$1" & (CLng(oMTS(0).SubMatches(1)) + 1))
Else
' handle error
End If
WScript.Echo oFS.OpenTextFile(sFSpec).ReadAll()
output:
Client1,5
Client2,7
Client3,12
Gray,7
Client4,9
Client5,17
Client6,8