VB Script to count the number of rows - csv

I have written a VB script to count the number of rows from several CSV files and save in a File in FileRecordCount.csv file with the filename and number of rows. The code does not show any errors at all.
But the script is not working at all. I don't know what is the problem. Any help Any help would be greatly appreciated!????
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
vbsFile = Wscript.ScriptName
vbsFilePath = Wscript.ScriptFullName
sFolder = left(vbsFilePath,len(vbsFilePath)-(len(vbsFile)+1))
ResultsFile = sFolder & "\FileRecordCount.csv"
For Each objFile In objFSO.GetFolder(sFolder).Files
If UCase(objFSO.GetExtensionName(objFile.Name)) = "CSV" Then
oFile = objFile.path
Set objFile = objFSO.OpenTextFile(oFile, ForReading)
RowCount = 0
Do Until objFile.AtEndOfStream
WScript.Echo objFile.ReadLine
RowCount = RowCount + 1
Loop
'need to make a new file to write the results to
FileName = objFSO.GetFileName(ResultsFile)
strText = FileName & "," & RowCount
Set objFile = objFSO.OpenTextFile(ResultsFile, ForWriting)
objFile.WriteLine strText
objFile.Close
End if
Next
MsgBox "FileRowCount Complete"

The script has multiple issues. First, as #Flakes stated, the same objFile variable is used for the files being processed and the results file. Second, the results filename is being written to the results file instead of each processed file name. Additionally, the variable "oFile" is a string, so would be better named "strFile" and the script path directory can be derived a bit more elegantly. Also, as per #Flakes, I moved the results file open before the loop and the results file close after the loop and I named the results file with a .txt extension so it doesn't get processed as one of the CSV files. Also added a Create = True flag to the results file open, so it doesn't have to pre-exist.
Here is the edited script:
Const ForReading = 1
Const ForWriting = 2
Const Create = True
Set objFSO = CreateObject("Scripting.FileSystemObject")
sFolder = objFSO.GetParentFolderName(WScript.ScriptFullName)
ResultsFile = sFolder & "\FileRecordCount.txt"
Set objResultsFile = objFSO.OpenTextFile(ResultsFile, ForWriting, Create)
For Each objFile In objFSO.GetFolder(sFolder).Files
If UCase(objFSO.GetExtensionName(objFile.Name)) = "CSV" Then
strFile = objFile.path
Set objReadFile = objFSO.OpenTextFile(strFile, ForReading)
RowCount = 0
FirstLine = True
Do Until objReadFile.AtEndOfStream
Line = objReadFile.ReadLine
RowCount = RowCount + 1
If FirstLine Then ColumnCount = UBound(Split(Line,",")) + 1
FirstLine = False
Loop
objReadFile.Close
strText = strFile & "," & RowCount & "," & ColumnCount
objResultsFile.WriteLine strText
End if
Next
objResultsFile.Close
WScript.Echo "File row/column count complete"

Related

Rename some files present in the folder with other filename that is present in other folder in VBscript

I have a folder 1 where there are two CSV files present with name "Head.csv" & "Col.csv". I want to rename all those CSV files that are present in folder 1. The suffix that I wanted to add to each CSV file is another filename that exists in the folder2.
Filename 1 = Actual CSV File that I want to rename
Filename 2 = wanted to add this filename as Suffix. This file is present in the other folder.
Output of Filename: Filename1 + _ + FileName2 + .csv
Take for example in folder 1 "Head.csv" & "Col.csv" exist while in folder 2, the file exist with name general.txt. The filename in folder 2 can be any name.
Ex:- Head_general.csv
Option Explicit
Dim ofso, ofolder1,ofolder2,objFile, folderName1,folderName2
Dim File,sNewFile,a
folderName1 = "C:\Users\ShantanuGupta\Desktop\DRUM\Folder1" ' .csv file
folderName2 = "C:\Users\ShantanuGupta\Desktop\DRUM\Folder2" ' .txt file with different filename
Set ofso = CreateObject("Scripting.FileSystemObject")
Set ofolder1 = ofso.GetFolder(folderName1)
Set ofolder2 = ofso.GetFolder(folderName2)
Set objFile = oFolder2.Files
filesuffix = ofso.GetBaseName(oFolder2.Files)
For Each File In oFolder1.Files
sNewFile = File.Name
If instr(sNewfile, "Head.csv") > 0 THEN
File.Name = Replace(File.Name, "Head.csv", "Head_" & filesuffix & ".csv")
End If
If instr(sNewfile, "Col.csv") > 0 THEN
File.Name = Replace(File.Name, "Col.csv", "Col_" & filesuffix & ".csv")
End If
Next
Error Coming with Type Mismatch 'GetBaseName'.
Any help???
Files attached Here
This might work, although I'm not entirely sure how many files will be in 'folder2' but you get the idea:
Option Explicit
Dim objFile, sNewFile, filesuffix
Dim folderName1 : folderName1 = "C:\Users\ShantanuGupta\Desktop\DRUM\Folder1"
Dim folderName2 : folderName2 = "C:\Users\ShantanuGupta\Desktop\DRUM\Folder2"
Dim ofso : Set ofso = CreateObject("Scripting.FileSystemObject")
Dim ofolder1 : Set ofolder1 = ofso.GetFolder(folderName1)
Dim ofolder2 : Set ofolder2 = ofso.GetFolder(folderName2)
For Each objFile in ofolder2.Files
filesuffix = ofso.GetBaseName(objFile)
Next
For Each objFile In oFolder1.Files
sNewFile = ofso.GetBaseName(objFile.Name)
If StrComp(sNewfile,"Head",1) = 0 THEN
objFile.Name = Replace(sNewFile, sNewFile, sNewFile & "_" & filesuffix & ".csv")
End If
If StrComp(sNewfile,"Col",1) = 0 THEN
objFile.Name = Replace(sNewFile, sNewFile, sNewFile & "_" & filesuffix & ".csv")
End If
Next
Set ofolder1 = Nothing
Set ofolder2 = Nothing
Set ofso = Nothing

Combining multiple files in to one text using ms access

I have 6 text files in one folder.
I want combine selected files in to one text using access.
I have tried this code without success, because the one text file is created but is empty
Can any one help me on this?
Thanks in advance, my code below.
Lines in the text file:
xN;xDate;xNode;xCO;
100;2017-09-26 00:00:00;Valley;D6;
101;2017-09-25 00:00:00;Valley;D3;
...
...
Code:
Dim xPath
Function xExtract()
Dim xArray() As Variant
Dim I As Integer
Dim StrFileName As String
xPath = CurrentProject.Path
PDS:
xArray = Array("D1", "D2", "D3", "D4", "D5", "D6")
new_file = "" & xPath & "\PDS.txt"
fn = FreeFile
Open new_file For Output As fn
Close
For I = 0 To UBound(xArray)
StrFileName = "\\myserver\inetpub\ftproot\PDS_" & xArray(I) & ".txt"
fn = FreeFile
Open StrFileName For Input As fn
Open new_file For Append As fn + 1
Line Input #fn, dato
Do While Not EOF(fn)
Line Input #fn, dato
dati = Split(dato, Chr(9))
For d = 0 To UBound(dati)
If d = 0 Then
dato = Trim(dati(d))
Else
dato = dato & ";" & Trim(dati(d))
End If
Next
Print #fn + 1, dato
Loop
Close
Next I
Application.Quit
End Function
Here's code that works for concatenating comma delimited text files (probably would work for any text files). Pretty crude. Needs error handler and would benefit from common dialog to select output folder and file name. Also I don't like using non-typed variables, but I don't know what type of object some of them are and can't figure it out from Microsoft help. Warning, don't put output in same folder - might result in endless loop - trust me I tried it
Public Function CFiles(Filepath As String) As String
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Folder
Dim Filein As Object
Dim fileout As Object
Dim strText As String
Dim TheInputfile As Object
Dim filename As String
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(Filepath)
Set fileout = FSO.CreateTextFile("c:\InvestmentsPersonal\files\backup\output.txt", ForAppending, False)
For Each Filein In SourceFolder.Files
filename = Filein.Name
Set TheInputfile = FSO.OpenTextFile(Filepath & filename, ForReading)
strText = TheInputfile.ReadAll
TheInputfile.Close
fileout.WriteLine strText
Next
fileout.Close
Set fileout = Nothing
Set Filein = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
CFiles = "c:\InvestmentsPersonal\files\backup\output.txt"
End Function
As your code works for files with windows EOL format (CR (Carriage Return) + LF (Line Feed)), I guess your files are UNIX EOL format (just LF, no CR), check this with a texteditor like e.g. Notepad++ (View->Show Symbol->Show End of Line). This causesLine Inputto read the whole file in one line as it breaks on CR. Then you skip the first line and nothing is inserted, because all text is in this line.
You can useFileSystemObjectto avoid this as it breaks on LF.
Function xExtract()
Const ForReading = 1, ForWriting = 2, ForAppending = 8 'iomode constants
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0 'format constants
Dim xArray As Variant, dati As Variant
Dim i As Long, d As Long
Dim xPath As String, new_file As String, dato As String, StrFileName As String
Dim FSO As Object, TextStreamIn As Object, TextStreamOut As Object
xPath = CurrentProject.Path
new_file = xPath & "\PDS.txt"
xArray = Array("D1", "D2", "D3", "D4", "D5", "D6")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set TextStreamOut = FSO.OpenTextFile(new_file, ForWriting, True, TristateUseDefault) 'open textstream to write
For i = 0 To UBound(xArray) 'loop through files
StrFileName = "\\myserver\inetpub\ftproot\PDS_" & xArray(i) & ".txt"
Set TextStreamIn = FSO.OpenTextFile(StrFileName, ForReading) ' open textstream to read
TextStreamIn.SkipLine 'skip first line with headers
Do Until TextStreamIn.AtEndOfStream 'loop through lines
dati = Split(TextStreamIn.Readline, Chr(9))
For d = 0 To UBound(dati)
If d = 0 Then
dato = Trim(dati(d))
Else
dato = dato & ";" & Trim(dati(d))
End If
Next
TextStreamOut.WriteLine dato 'write line to file
Loop
TextStreamIn.Close 'close textstream
Next i 'next file
TextStreamOut.Close
Set TextStreamOut = Nothing
Set TextStreamIn = Nothing
Set FSO = Nothing
Application.Quit
End Function
If you want to stay withOpen fileyou can split the first (and only) line on LF (Split(dato,vbLf) and ignore the first element, but you have to check the file is UNIX EOL format, FSO covers both.

Recordset writing ÿþ to CSV file instead of query results

I have a VBS file that queries an access database and writes the results to a .CSV file. The only thing being written to the .CSV file is ÿþ.
I am using the same VBS file with a more complex query and it runs fine. Both queries return 2 fields of the same type. The only change between the 2 files is the SQL query. Also if I paste the query I'm trying to use into Access, it runs the query as expected.
Here is the VBS file:
Dim connStr, objConn, getNames, objFSO, rs
Const ForWriting = 2
'Make and open progress window
On Error Resume Next
Set objExplorer = CreateObject("InternetExplorer.Application")
objExplorer.Navigate "about:blank"
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width = 400
objExplorer.Height = 200
objExplorer.Visible = 1
objExplorer.Silent = 1
objExplorer.Document.Title = "Script in progress"
objExplorer.Document.Body.InnerHTML = "Your Script is being processed. " & "This might take several minutes to complete. Closing this window will stop the script. So don't close this window ^_^"
'Create csv file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile("\\192.168.100.4\data\IT\Scripts\testData.csv", ForWriting, True)
'Define Db String
connStr = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\\192.168.100.16\Sage\2016\Connex\Sage100Shadow_CHRIS.mdb"
'Define object type
Set objConn = CreateObject("ADODB.Connection")
'Open Connection
objConn.Open connStr
'Define recordset and SQL query
Set rs = objConn.Execute("SELECT [BillNo],[InStock] FROM qryKitInvNums;")
MsgBox(rs.Fields(0).Type & ", " & rs.Fields(1).Type)
'While loop, loops through all available results
Do While Not rs.EOF
'add values seperated by comma to getNames
getNames = rs.Fields(0) & "," & rs.Fields(1)
'Write current record to LogFile
objLogFile.Write getNames
'Line return for next record in LogFile
objLogFile.Writeline
'move to next result before looping again
rs.MoveNext
'continue loop
Loop
MsgBox(getNames)
'Close connection and release objects
objLogFile.Close
objConn.Close
Set rs = Nothing
Set objConn = Nothing
'Closes progress window
objExplorer.Document.Body.InnerHTML = "Your Script is now complete."
WScript.Sleep 2000
objExplorer.Quit
Here is a copy of the working VBS file. The only difference is the SQL query which still returns 2 fields of same type as the first VBS file.
Dim connStr, objConn, getNames, objFSO
Const ForWriting = 2
'Make and open progress window
On Error Resume Next
Set objExplorer = CreateObject("InternetExplorer.Application")
objExplorer.Navigate "about:blank"
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width = 400
objExplorer.Height = 200
objExplorer.Visible = 1
objExplorer.Silent = 1
objExplorer.Document.Title = "Script in progress"
objExplorer.Document.Body.InnerHTML = "Your Script is being processed. " & "This might take several minutes to complete. Closing this window will stop the script. So don't close this window ^_^"
'Create csv file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile("\\192.168.100.4\data\IT\Scripts\testData.csv", ForWriting, True)
'Define Db String
connStr = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\\192.168.100.16\Sage\2016\Connex\Sage100Shadow_CHRIS.mdb"
'Define object type
Set objConn = CreateObject("ADODB.Connection")
'Open Connection
objConn.Open connStr
'Define recordset and SQL query
Set rs = objConn.Execute("SELECT IM_ItemWarehouse.ItemCode, IIf([InStock] Is Null Or [InStock]="""",[IM_ItemWarehouse].[QuantityOnHand],[InStock]) AS EvalInstock FROM IM_ItemWarehouse LEFT JOIN qryInStockNum4ItemsWPO ON IM_ItemWarehouse.ItemCode = qryInStockNum4ItemsWPO.ItemCode WHERE (((IM_ItemWarehouse.ItemCode) Is Not Null) AND ((IM_ItemWarehouse.WarehouseCode)=""000""));")
'While loop, loops through all available results
Do While Not rs.EOF
'add values seperated by comma to getNames
getNames = rs.Fields(0) & "," & rs.Fields(1)
'Write current record to LogFile
objLogFile.Write getNames
'Line return for next record in LogFile
objLogFile.Writeline
'move to next result before looping again
rs.MoveNext
'continue loop
Loop
'Close connection and release objects
objLogFile.Close
objConn.Close
Set rs = Nothing
Set objConn = Nothing
'Closes progress window
objExplorer.Document.Body.InnerHTML = "Your Script is now complete."
WScript.Sleep 2000
objExplorer.Quit

read attachment field from accdb with classic asp3/vbscript

I have an attachment field in my accdb database file,
i'm trying to read it to extract the attachments but it keep return empty values
recording to this post Using Attachment field with Classic ASP
there is no way to do it with adodb, is true? and if yes, what other ways i have to do that ?
this is the code that i'm running:
qid = request.querystring("qid")
wikiDbAddress="database/my.accdb"
set cnWiki=server.CreateObject("adodb.connection")
cnWiki.open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=" & Server.MapPath(root&wikiDbAddress)
SQL = "select * from [Knowledge Base] where id="&qid
RS.Open SQL, cnWiki
do while not RS.eof
response.write RS("attachments")
RS.movenext
loop
For now, i did some workaround that helped me, it's not efficient but does the work.
qid = request.querystring("qid")
name = request.querystring("name")
SQL = "select Attachments.FileName as fname, Attachments.FileData as data, Attachments.FileType as FileType from [Knowledge Base] where Attachments.FileName='"&name&"' and id="&qid
RS.Open SQL, cnWiki
do while not RS.eof
if rs("fname")= name then
filename = Server.MapPath("/KB_"&qid&"_"&rs("fname"))
set fs=Server.CreateObject("Scripting.FileSystemObject")
if not fs.FileExists(filename) then
SaveBinaryData filename, rs("data")
data = readBinary(filename)
' CHR(255) = FF, CHR(170) = AA
data = Mid(data, 21, Len(data) - 20)
writeBinary data,filename
end if
set fs=nothing
downloadFromFile(filename )
exit do
else
RS.movenext
end if
loop
rs.close
cnWiki.close
function downloadFromFile(strFile )
Dim objConn
Dim intCampaignRecipientID
If strFile <> "" Then
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1 'adTypeBinary
objStream.Open
objStream.LoadFromFile(strFile)
Response.Clear
'Response.ContentType = "image/jpeg"
Response.Addheader "Content-Disposition", "attachment; filename=" & strFile
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
End If
End Function
Function SaveBinaryData(FileName, ByteArray)
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
'Create Stream object
Dim BinaryStream
Set BinaryStream = CreateObject("ADODB.Stream")
'Specify stream type - we want To save binary data.
BinaryStream.Type = adTypeBinary
'Open the stream And write binary data To the object
BinaryStream.Open
BinaryStream.Write ByteArray
'Save binary data To disk
BinaryStream.SaveToFile FileName, adSaveCreateOverWrite
End Function
Function readBinary(path)
Dim a, fso, file, i, ts
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.getFile(path)
If isNull(file) Then
wscript.echo "File not found: " & path
Exit Function
End If
Set ts = file.OpenAsTextStream()
a = makeArray(file.size)
i = 0
While Not ts.atEndOfStream
a(i) = ts.read(1)
i = i + 1
Wend
ts.close
readBinary = Join(a,"")
End Function
Sub writeBinary(bstr, path)
Dim fso, ts
Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set ts = fso.createTextFile(path)
If Err.number <> 0 Then
wscript.echo Err.message
Exit Sub
End If
On Error GoTo 0
ts.Write(bstr)
ts.Close
End Sub
Function makeArray(n)
Dim s
s = Space(n)
makeArray = Split(s," ")
End Function

How do I insert commas into text?

I have to insert commas at certain points in lines of text, using VBScript. I need it to check the first four charcters of each line with an if statement and if it matches it inserts the commas required for that line this is what I have so far:
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("H:\Letter Display\Letters\LTRPRT__00000008720000000001NI-K-RMND.txt", ForReading)
strNIK = "1000"
strLine = objFile.ReadLine
If Left(strLine,4) = strNIK then
arrCommas = Array(16,31,46,56,66,79,94,99)
Do Until objFile.AtEndOfStream
intLength = Len(strLine)
For Each strComma in arrCommas
strLine = Left(strLine, strComma - 1) + "," + Mid(strLine, strComma, intLength)
Next
strText = strText & strLine & vbCrLf
Loop
end if
objFile.Close
Set objFile = objFSO.OpenTextFile("H:\Letter Display\Letters\LTRPRT__00000008720000000001NI-K-RMND.txt", ForWriting)
objFile.Write strText
objFile.Close
If anyone could help with making this an IF statement it would be much appreciated.
You need to move the ReadLine and the conditional inside the Do..Loop:
strNIK = "1000"
arrCommas = Array(16,31,46,56,66,79,94,99)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If Left(strLine, 4) = strNIK then
intLength = Len(strLine)
For Each strComma in arrCommas
strLine = Left(strLine, strComma - 1) + "," _
+ Mid(strLine, strComma, intLength)
Next
End If
strText = strText & strLine & vbCrLf
Loop
If you want the output to consist only of the modified lines, move the line strText = strText & strLine & vbCrLf inside the conditional:
If Left(strLine, 4) = strNIK then
'...
strText = strText & strLine & vbCrLf
End If
Do the comma indexes in your array already account for the positional shift that is caused by the character insertion?
Also, it might be a good idea to write the output line by line to a temporary file and then replace the input file with that temporary file after you finished processing all input:
Set inFile = objFSO.OpenTextFile(inputFilename, ForReading)
Set outFile = objFSO.OpenTextFile(outputFilename, ForWriting)
Do Until inFile.AtEndOfStream
strLine = inFile.ReadLine
'do stuff with strLine
outFile.WritLine
Loop
inFile.Close
outFile.Close
objFSO.DeleteFile inputFilename, True
objFSO.MoveFile outputFilename, inputFilename
That way you can avoid memory exhaustion when processing large files.
You can process all files with a specific extension in a given directory like this:
folderName = "C:\some\folder"
For Each objFile In objFSO.GetFolder(folderName).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "ltr" Then
'processing takes place here
End If
Next
If you want to use the inputfile/outputfile approach I suggested above, you can either use the same temporary outputfile name for each input file, or you can derive the outputfile name from the inputfile name, e.g. like this:
inputFilename = objFile.Name
outputFilename = inputFilename & ".tmp"