Using textstream object to replace tab with spaces and delete characters - vba

I have over a thousand .s2p files (a delimited text file used by electrical testing equipment) that were edited by a VBA macro, which opened each raw file in Excel as a tab-and-space delimited text file, and replaced a few of the columns with data columns from another file, then saved them in original format (.s2p) and closed them. This is the call I used to open the each file:
Call Application.Workbooks.OpenText(Filename:=(path & filename & ".s2p"), Origin:="437", DataType:=xlDelimited, ConsecutiveDelimiter:=True, Tab:=True, Space:=True, TextQualifier:=xlTextQualifierNone)
Now, when I open the .s2p files in Notepad to view them, the original single space separating the columns is now a full tab, and some double quote (") characters were added to some of the file header lines (despite setting TextQualifier parameter to xlTextQualifierNone...)
Because of this I want to write another macro that can open all of these .s2p files again, loop through the lines, and replace any double quotes with blanks, and any tabs with single spaces. I was planning to use .OpenAsTextStream on each file, but it seems like the TextStream object doesn't support overwriting lines, but can only write new lines...
Is there a better way to achieve what I am trying to do than just reading lines from the original file, and writing them to a newly created file? It is imperative that I save the final file as ".s2p" and not ".txt".

You don't need the text streams, just the basic input output actions available in VBA.
Option Explicit
Sub test()
FixFile "c:\temp\mytestfile.s2p"
End Sub
Sub FixFile(filename As String)
Dim fnum As Integer
Dim fileText As String
Dim finalText As String
fnum = FreeFile
On Error Resume Next
Open filename For Input As #fnum
If Err.Number <> 0 Then
Debug.Print "Critical error attempting to open " & filename & _
". Error #" & Err.Number & ": " & Err.Description
Exit Sub
End If
finalText = ""
Do Until EOF(fnum)
Line Input #fnum, fileText
fileText = Replace(fileText, """", " ", , , vbTextCompare)
fileText = Replace(fileText, vbTab, " ", , , vbTextCompare)
finalText = finalText & fileText & vbCrLf
Loop
Close fnum
fnum = FreeFile
Open filename For Output As #fnum
Print #fnum, finalText
Close fnum
End Sub
Edited to show line by line read with a final write.

Related

Find and replace characters in strings in all .xlsx files in folder VBA

I am trying to replace characters such as "/" and "ó", and also a line break (alt + ENTER, manually replaced in excel with find and replace with CTRL + J) in excel files (.xlsx). The characters can be found all over the excel sheets (not one particular range). The reason that I would like to replace these values is that these characters are giving me errors in another application.
I have 20 excel files in one folder, with multiple sheets. I would like to make a script (vba macro) to loop through the excel files and all its sheets and do the replacements.
I am very new with vba/macros.
Sub ReplaceStringInFile()
Dim sBuf As String
Dim sTemp As String
Dim sFileName As String
Dim FileExt(2) As String
ChDir = "C:\mydirectory\"
FileExt(1) = "xlsx"
For i = 1 To 1
sFileName = Dir("*." & FileExt(i))
Do
If sFileName = "" Then Exit Do
sTemp = ""
Open sFileName For Input As #1
Do Until EOF(1)
Line Input #1, sBuf
sTemp = sTemp & sBuf & vbCrLf
Loop
Close #1
sTemp = Replace(sTemp, "ó", "o")
sTemp = Replace(sTemp, "/", "")
Open sFileName For Output As #1
Print #1, sTemp
Close #1
sFileName = Dir()
Loop
Next i
End Sub
I have tried to combine code from scripts mentioned here:
Find and replace string in all excel files in folder and here
Excel macro to find and replace multiple strings in any text file
Loop through files in a folder using VBA?
But I didn't get it to work.
Help would be very appreciated!

Attaching additional lines on top of a Access CSV export

I have a process in MS Access where I am exporting the result of a query into a csv format using the DoCmd TransferText method, and using an export specification to contain the field names.
However, I need to attach to the beginning of this file several lines- all of a fixed value- I'm naming this in my code with vbCrLf to separate the several lines I need. How can I append this to the top of the file after it is created. So my file needs to look like this, with the three extra lines for example at the top, with the csv export contents directly below. How can I achieve this? Thanks!
***(need this line 1)
(need this line 2)
(need this line 3)***
field1,field2,field3
x, y, z
As #TimWilliams has suggested, you will need to use VBA to do this. Below is some code that exports the query to a text file using .TransferText, then opens it and imports the data as one chunk, before writing back out the three header lines and the original data:
Sub sExportCSV()
On Error GoTo E_Handle
Dim strFile As String
Dim strLine1 As String
Dim strLine2 As String
Dim strLine3 As String
Dim strData As String
Dim intFile As Integer
strLine1 = "This is line 1"
strLine2 = "This is the second line"
strLine3 = "And this is the last line"
strFile = "J:\test-data\csv.txt"
DoCmd.TransferText acExportDelim, , "qdfExport", strFile, False
intFile = FreeFile
Open strFile For Input As intFile
strData = Input(LOF(intFile), intFile)
Close #intFile
intFile = FreeFile
Open strFile For Output As intFile
Print #intFile, strLine1 & vbCrLf & strLine2 & vbCrLf & strLine3 & vbCrLf & strData
Close #intFile
sExit:
On Error Resume Next
Close #intFile
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sExportCSV", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,

How to make an SRT file into a dataset?

Is it possible to turn an SRT file, which is used for subtitles in videos into a dataset?
When imported into Excel, the SRT file format looks like this:
1
00:00:03,000 --> 00:00:04,000
OVERLAPS PURE COINCIDENCE THAT
...
This pattern continues as time in the "video"/transcript goes on. I'd like to format the SRT file this way:
number ; start ; end ; text
1 ; 00:00:03,000 ; 00:00:04,000 ; OVERLAPS PURE COINCIDENCE THAT
The VBA procedure below loads a standard .srt (SubRip Movie Subtitle File) from a local file and splits it into rows/columns on the active Excel worksheet.
Import SRT subtitles from Local File:
Sub importSRTfromFile(fName As String)
'Loads SRT from local file and converts to columns in Active Worksheet
Dim sIn As String, sOut As String, sArr() As String, x As Long
'load file
Open fName For Input As #1
While Not EOF(1)
Line Input #1, sIn
sOut = sOut & sIn & vbLf
Wend
Close #1
'convert LFs to delimiters & split into array
sOut = Replace(sOut, vbLf & vbLf, vbCr)
sOut = Replace(Replace(sOut, vbLf, "|"), " --> ", "|")
sArr = Split(sOut, vbCr)
'check if activesheet is blank
If ActiveSheet.UsedRange.Cells.Count > 1 Then
If MsgBox(UBound(sArr) & " rows found." & vbLf & vbLf & _
"Okay to clear worksheet '" & ActiveSheet.Name & "'?", _
vbOKCancel, "Delete Existing Data?") <> vbOK Then Exit Sub
ActiveSheet.Cells.ClearContents
End If
'breakout into rows
For x = 1 To UBound(sArr)
Range("A" & x) = sArr(x)
Next x
'split into columns
Columns("A:A").TextToColumns Destination:=Range("A1"), _
DataType:=xlDelimited, Other:=True, OtherChar:="|"
MsgBox "Imported " & UBound(sArr) & " rows from:" & vbLf & fName
End Sub
Example Usage:
Sub test_FileImport()
importSRTfromFile "c:\yourPath\yourFilename.srt"
End Sub
Import SRT subtitles from Website URL:
Alternatively, you can import an .srt (or other similar text files) from a Website URL such as https://subtitle-index.org/ with this:
Sub importSRTfromWeb(url As String)
'Loads SRT from URL and converts to columns in Active Worksheet
Dim sIn As String, sOut As String, sArr() As String, rw As Long
Dim httpData() As Byte, XMLHTTP As Object
'load file from URL
Set XMLHTTP = CreateObject("MSXML2.XMLHTTP")
XMLHTTP.Open "GET", url, False
XMLHTTP.send
httpData = XMLHTTP.responseBody
Set XMLHTTP = Nothing
sOut = StrConv(httpData, vbUnicode)
'convert LFs to delimiters & split into array
sOut = Replace(sOut, vbLf & vbLf, vbCr)
sOut = Replace(Replace(sOut, vbLf, "|"), " --> ", "|")
sArr = Split(sOut, vbCr)
'check if activesheet is blank
If ActiveSheet.UsedRange.Cells.Count > 1 Then
If MsgBox(UBound(sArr) & " rows found." & vbLf & vbLf & _
"Okay to clear worksheet '" & ActiveSheet.Name & "'?", _
vbOKCancel, "Delete Existing Data?") <> vbOK Then Exit Sub
ActiveSheet.Cells.ClearContents
End If
'breakout into rows
For rw = 1 To UBound(sArr)
Range("A" & rw) = sArr(rw)
Next rw
'split into columns
Columns("A:A").TextToColumns Destination:=Range("A1"), _
DataType:=xlDelimited, Other:=True, OtherChar:="|"
MsgBox "Imported " & UBound(sArr) & " rows from:" & vbLf & url
End Sub
Example Usage:
Sub testImport()
importSRTfromWeb _
"https://subtitle-index.org/download/4670541854528212663953859964/SRT/Pulp+Fiction"
End Sub
Many sites host free .srt's; you may have to right-click the download button to copy the link (which may have an .srt extension or might be a pointer, like the example above). The procedure won't work on .zip'd files.
More Information:
Wikipedia : SubRip & SRT
MSDN : Split Function (VBA)
Wikipedia : Newline characters
MSDN : UBound Function
MSDN : Range.TextToColumns Method (Excel)
SubRip Official Website
in the above code :
'breakout into rows
For rw = 1 To UBound(sArr)
Range("A" & rw) = sArr(rw)
Next rw
should be replaced with:
'breakout into rows
For rw = 0 To UBound(sArr)
Range("A" & rw+1) = sArr(rw)
Next rw
else the output will start from line 2
I used Vim and wrote a quick regex to convert a .srt into a .csv file for a translator friend who needed a similar conversion. The csv file can then be opened in Excel / LibreOffice and saved as .xls, .ods or whatever.
My friend didn't need the subtitle numbers to appear in the first column so the regex code looks like this :
set fileencoding=utf-8
%s/"/""/g
g/^\d\+$/d
%s#^\(.*\) --> \(.*\)\n#"\1","\2","#g
%s/\n^$/"/g
Variant to keep the sub numbering :
set fileencoding=utf-8
%s/"/""/g
%s#\(^\d\+\)$\n^\(.*\) --> \(.*\)\n#"\1","\2","\3","#g
%s/\n^$/"/g
Save this code into a text file with the .vim extension, then source this file when editing your .srt in Vim / Gvim. Save the result as a .csv. Enjoy the magic of Regexes !
NB : my code uses commas as field separators. Change the commas into semi-colons in the above code to use semi-colons. I've also added double-quotes as string delimitors in case double-quotes and commas occur in the subtitle text. Much more error proof !

Phantom characters in strings when converting from Sharepoint > Excel > PDF

My organization uses a SP 2010 form to fill information. I didn't build this form, but I've noticed if you try to copy from some of the fields into anywhere else (notepad, etc.) it puts a question mark or euro symbol often directly in front of a string (sometimes in the middle.)
Dim objMyList As ListObject
Dim objWksheet As Worksheet
Dim strSPServer As String
Const SERVER As String = "xxx"
Const LISTNAME As String = "{xxx}"
Const VIEWNAME As String = "{xxx}"
strSPServer = "https://" & SERVER & "/_vti_bin"
Set objWksheet = Sheets("Sheet1")
Set objMyList = objWksheet.ListObjects.Add(xlSrcExternal, _
Array(strSPServer, LISTNAME, VIEWNAME), False, , Range("A1"))
This part of the script pulls the list of the forms that have already been entered into my worksheet, the equivalent of just using the Export to Excel button on the SP website.
The rest of the sub maps each row to a new PDF by way of using a Replace function on an FDF file. These phantom symbols are nowhere to be found on the Excel sheet. There are no blank spaces or characters of any kind.
For i = 2 To lastRow
oldPDF = "C:\~\Auto.pdf"
oldFDF = "C:\~\Auto_data.fdf"
newPDF = "C:\~\" & i & ".pdf"
iFileNum = FreeFile
Open oldFDF For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & sBuf & vbCrLf
Loop
Close iFileNum
Next i
sTemp = Replace(sTemp, "<</T(myFormField)/V( )>>", "<</T(myFormField)/V(" & sht.Range("B" & i) & ")>>")
I open up the PDF to find that the phantom characters are back. So what we have so far:
SharePoint form & Excel sheet:
The quick brown fox jumps over the lazy dog
Text from the SP form copied/pasted and on my PDF:
?The quick brown fox jumps over the lazy dog
I've tried
sTemp = Replace(sTemp, "~?", "")
sTemp = Replace(sTemp, "?", "")
But the symbols still show up on the PDF...and it's useless to do a Replace on the Excel sheet itself because the symbols aren't there.
How do I automatically remove these symbols from the PDF/FDF if the above has not worked?
Edit:
sTemp = Replace(sTemp, Chr(160), "")
Solved the euro symbol issue, but the questions marks remain and I've tried Chr/Chrw(63)

How to find length of all .csv files in directory?

I have multiple .csv files that I need to find the length of in my directory. (The number of rows that have data in them.) I'm running the following code from a .xlsx file in the same directory. (I intend to copy data from the .csv files to the .xlsx file eventually.)
i = 1
FilePath = Application.ActiveWorkbook.Path & "\"
file = Dir(FilePath & "*.csv")
Do While Len(file) > 0
Open FilePath & file For Input As #1
length(i) = Cells(Rows.Count, 1).End(xlUp).Row
i = i + 1
Close #1
file = Dir
Loop
All the values of the length array end up being 1, even though the .csv files are probably 15-20 rows long.
You're not actually opening the file in Excel so you can't count how many cells there are. Try reading how many lines instead:
Open FilePath & file For Input As #1
While Not EOF(1): Line Input #1, trashLine: Wend
i = i + 1
Close #1
Alternatively, open the file in Excel - test - then close afterwards:
Set tempWB = Workbooks.Open(FilePath & file)
i = i + tempWB.Sheets(1).Cells(tempWB.Sheets(1).Rows.Count, 1).End(xlUp).Row
tempWB.Close False
Or an even quicker way is to use Windows Script:
Dim i As Long
For Each varFile In _
Filter(Split(CreateObject("WScript.Shell").Exec("cmd /c find /v /c """" """ _
& ThisWorkbook.Path & "\*.csv""").StdOut.ReadAll, vbCrLf), ":")
i = i + CLng(Split(varFile, ":")(2))
Next
Debug.Print i
That way, if you've got 10 files the code is only working with 10 strings rather than opening/closing a file or reading thousands of lines...
As #SOofWXLS stated, your code is not opening the files in Excel, you are opening them for direct i/o.
Here is a complete code sample that will fill your array with the file lengths as you were trying to do.
Dim fPath As String
Dim fName As String
Dim hFile As Long
Dim i As Long
Dim NumLines As Long
Dim length() As Long
Dim strLine As String
ReDim length(1 To 1)
fPath = Application.ActiveWorkbook.Path & "\"
fName = Dir(fPath & "*.csv")
Do While Len(fName) > 0
i = i + 1
NumLines = 0
ReDim Preserve length(1 To i)
hFile = FreeFile
Open fPath & fName For Input As hFile
Do While Not EOF(hFile)
Line Input #hFile, strLine
NumLines = NumLines + 1
Loop
Close hFile
length(i) = NumLines
fName = Dir
Loop
This will also dynamically expand your array to accommodate as many files as are found.