I have two .csv files: inputfile.csv and mainfile.csv
I need to write a script that:
1- will read one by one all the records in inputfile.csv
2- then find if there is a match in the mainfile.csv
3- if there is a match then do nothing and read the next record from inputfile.csv
4- else if there is not a match in the mainfile.csv write that record from the inputfile.csv to the mainfile.csv
This solution uses Scripting.Dictionary to record each line in mainfile.csv. Then, to see if a line in inputfile.csv is new, all it takes is to see if that line exists in the dictionary. For example:
mainfile.csv
exists,one
exists,two
exists,three
exists,four
exists,five
inputfile.csv
exists,two
new,one
exists,four
new,two
new,three
mainfile.csv (after running the program)
exists,one
exists,two
exists,three
exists,four
exists,five
new,one
new,two
new,three
Here's the code:
Option Explicit
Const ForReading = 1, ForWriting = 4, ForAppending = 8
Dim oFso : Set oFso = CreateObject("Scripting.FileSystemObject")
Dim oDict : Set oDict = CreateObject("Scripting.Dictionary")
'
' Read the contents of 'mainfile.csv'. Add each line to a dictionary
' to allow for a quick lookup.
'
Dim oFileMain : Set oFileMain = oFso.OpenTextFile("mainfile.csv", ForReading)
Dim sLine
While Not oFileMain.AtEndOfStream
sLine = oFileMain.ReadLine()
oDict.Add sLine, True
Wend
oFileMain.Close
Set oFileMain = Nothing
'
' Re-open 'mainfile.csv' in append mode.
'
Set oFileMain = oFso.OpenTextFile("mainfile.csv", ForAppending)
'
' Read the contents of 'inputfile.csv'. Write a line to 'mainfile.csv'
' only if that line does not exist in the dictionary.
'
Dim oFileInput : Set oFileInput = oFso.OpenTextFile("inputfile.csv", ForReading)
While Not oFileInput.AtEndOfStream
sLine = oFileInput.ReadLine()
If Not oDict.Exists(sLine) Then ' not a duplicate!
WScript.Echo "Found new line: [" & sLine & "]"
oFileMain.WriteLine sLine
End If
Wend
oFileInput.Close
Set oFileInput = Nothing
'
' Wrap it up.
'
oFileMain.Close
Set oFileMain = Nothing
Set oDict = Nothing
Set oFso = Nothing
' End
Here is my best attempt at doing it in python, not knowing the structure of the files:
with open("mainfile.csv", "r") as main:
records = [x.strip() for x in main.readlines()]
with open("inputfile.csv", "r") as input:
inputs = [x.strip() for x in input.readlines()]
for input in inputs:
if input not in records:
records.append(input)
with open("mainfile.csv", "w") as main:
for record in records:
main.write(record + "\n")
So for the following files you start with this:
inputfile.csv:
A quick brown fix
Two turtle doves
Feather boa
mainfile.csv:
Some other stuff
Two turtle doves
Friends in low places
Feather boa
Another Fairly boring thing
After you run the script mainfile.csv looks like this:
Some other stuff
Two turtle doves
Friends in low places
Feather boa
Another Fairly boring thing
A quick brown fix
Related
This is line 63 for me: Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
I was also getting an error for line 51, but adding the quotes solved my problem.. Well, It got rid of the error. I tried to do the same thing with line 63, but I get the error no matter what. I am also running this program on windows 10 and on a Windows Vista virtual computer.
And this is the Script I'm trying to debug:
' VBScript: IP_FileWrite.vbs
' Written by: Kathleen Williams
' Date: 2/7/18
' Class: COMP230
' Professor: Professor James Lewis
' ===================================
' This initializes a 2-dimension array
' of IP Address. The first index +100
' is the room# and the second index+1
' is the computer# in the room.
dim ipAddress(5,3)
ipAddress(0,0)="192.168.10.11"
ipAddress(0,1)="192.168.10.12"
ipAddress(0,2)="192.168.10.13"
ipAddress(0,3)="192.168.10.14"
ipAddress(1,0)="192.168.10.19"
ipAddress(1,1)="192.168.10.20"
ipAddress(1,2)="192.168.10.21"
ipAddress(1,3)="192.168.10.22"
ipAddress(2,0)="192.168.10.27"
ipAddress(2,1)="192.168.10.28"
ipAddress(2,2)="192.168.10.29"
ipAddress(2,3)="192.168.10.30"
ipAddress(3,0)="192.168.10.35"
ipAddress(3,1)="192.168.10.36"
ipAddress(3,2)="192.168.10.37"
ipAddress(3,3)="192.168.10.38"
ipAddress(4,0)="192.168.10.43"
ipAddress(4,1)="192.168.10.44"
ipAddress(4,2)="192.168.10.45"
ipAddress(4,3)="192.168.10.46"
ipAddress(5,0)="192.168.10.51"
ipAddress(5,1)="192.168.10.52"
ipAddress(5,2)="192.168.10.53"
ipAddress(5,3)="192.168.10.54"
' Define constants, variables and set object properties
CONST ForReading = 1
CONST ForWriting = 2
CONST ForAppending = 8
Const ASCII = 0
'Defining the Variables
fileName = "C:\VBScripts\IP_Addresses.csv"
ipAddrStr = ""
' Create New Folder
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(fileName) Then
fso.DeleteFile(fileName)
End If
Set ipAddrFile = fso.CreateTextFile("fileName,ForWriting,ASCII")
' Read from array and write a line of text.
For room = 0 to 5
For computer = 0 to 3
ipAddrStr = CStr(room+100) & "," & CStr(computer+1) & "," & _
ipAddress(room,computer) & vbCrLf
ipAddrFile.Write(ipAddrStr)
Next
Next
ipAddrFile.close
' Set object properties and close file object.
Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
WScript.Echo iPAddrFile.ReadAll
ipAddrFile.close
VBScript was designed by at least two people. A genius, who defined the properly named functions CreateTextFile() and OpenTextFile() and
their default arguments to make standard tasks - create an ASCII file, read from an ASCII file - easy:
Option Explicit
Const csFSpec = "48798232.txt"
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim sD : sD = "could be an array, but is just a string for show: " & Now()
' using *Create*TextFile + defaults to always create an ASCII File
Dim tsW : Set tsW = oFS.CreateTextFile(csFSPEC)
tsW.WriteLine sD
tsW.Close
' using OpenTextile + defaults to read from an ASCII File
' no need for a variable or .Close
WScript.Echo oFS.OpenTextFile(csFSPEC).ReadAll()
output:
cscript 48798232.vbs
could be an array, but is just a string for show: 15.02.2018 04:45:06
Then there came the idiot in residence and messed up OpenTextFile() with lots of optional parameters in arbitrary order to make it useable for file creation. From then on people mixed up those functions and their parameter lists.
Code 1: Set ipAddrFile = fso.CreateTextFile("fileName,ForWriting,ASCII")
Create: object.CreateTextFile(filename[, overwrite[, unicode]])
Open: object.OpenTextFile(filename[, iomode[, create[, format]]])
Code 2: Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
Never being sure of the arguments, their data types, or their order, they use desperate means like quoting the (wrong) argument list.
So: Check the docs carefully (e.g. be aware of the difference between a boolean ForWriting vs. a numerical iomode of the same name (<-- the idiot at work, obviously) and use the defaults for simple/standard tasks.
I'm attempting to convert PPT files to PPTX files using VBSCRIPT. I haven't used VB in a very long time & am pretty unfamiliar with the framework. I'm attempting to modify a script that converts PPTX/PPT to PDF, however without much luck. Here's an example of what I've got so far...
Option Explicit
Dim inputFile
Dim objPPT
Dim objPresentation
Dim objPrintOptions
Dim objFso
Dim pptf
If WScript.Arguments.Count <> 1 Then
WriteLine "You need to specify input and output files."
WScript.Quit
End If
inputFile = WScript.Arguments(0)
Set objFso = CreateObject("Scripting.FileSystemObject")
If Not objFso.FileExists( inputFile ) Then
WriteLine "Unable to find your input file " & inputFile
WScript.Quit
End If
WriteLine "Input File: " & inputFile
Set objPPT = CreateObject( "PowerPoint.Application" )
objPPT.Visible = True
objPPT.Presentations.Open inputFile
Set objPresentation = objPPT.ActivePresentation
objPresentation.SaveAs "out.pptx", Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsOpenXMLPresentation
objPresentation.Close
ObjPPT.Quit
Things turn pear shaped around the objPresentation.SaveAs line; obviously its illegal syntax - however I'm not sure of the best route here. Any help would be much appreciated. Also if there are other variables (or a link to api documentation) for converting doc->docx, and xls->xlsx.
Thanks in advance.
EDIT:
I found a solution to this myself; sorry I stopped checking in on this thread a few days after posted it. I found a documentation page for this code & noticed one function in particular (convert2): http://msdn.microsoft.com/en-us/library/office/ff743830.aspx
I'll mark the answer below as the answer; because it came first (although I haven't tested it). If you're interested - heres my code; AFAIK it only converts in between various PowerPoint formats (in either direction). Also FYI I modified this script from another popularly googlized script on the topic; the only line I changed was one of the last (the convert2 mehtod). Anyways... (also - this requires office 2010; per the documentation)
Usage:
CSCRIPT scriptName.vbs C:\inputfileName.ppt C:\outputFileName.pptx
Option Explicit
Sub WriteLine ( strLine )
WScript.Stdout.WriteLine strLine
End Sub
' http://msdn.microsoft.com/en-us/library/office/aa432714(v=office.12).aspx
Const msoFalse = 0 ' False.
Const msoTrue = -1 ' True.
' http://msdn.microsoft.com/en-us/library/office/bb265636(v=office.12).aspx
Const ppFixedFormatIntentScreen = 1 ' Intent is to view exported file on screen.
Const ppFixedFormatIntentPrint = 2 ' Intent is to print exported file.
' http://msdn.microsoft.com/en-us/library/office/ff746754.aspx
Const ppFixedFormatTypeXPS = 1 ' XPS format
Const ppFixedFormatTypePDF = 2 ' PDF format
' http://msdn.microsoft.com/en-us/library/office/ff744564.aspx
Const ppPrintHandoutVerticalFirst = 1 ' Slides are ordered vertically, with the first slide in the upper-left corner and the second slide below it.
Const ppPrintHandoutHorizontalFirst = 2 ' Slides are ordered horizontally, with the first slide in the upper-left corner and the second slide to the right of it.
' http://msdn.microsoft.com/en-us/library/office/ff744185.aspx
Const ppPrintOutputSlides = 1 ' Slides
Const ppPrintOutputTwoSlideHandouts = 2 ' Two Slide Handouts
Const ppPrintOutputThreeSlideHandouts = 3 ' Three Slide Handouts
Const ppPrintOutputSixSlideHandouts = 4 ' Six Slide Handouts
Const ppPrintOutputNotesPages = 5 ' Notes Pages
Const ppPrintOutputOutline = 6 ' Outline
Const ppPrintOutputBuildSlides = 7 ' Build Slides
Const ppPrintOutputFourSlideHandouts = 8 ' Four Slide Handouts
Const ppPrintOutputNineSlideHandouts = 9 ' Nine Slide Handouts
Const ppPrintOutputOneSlideHandouts = 10 ' Single Slide Handouts
' http://msdn.microsoft.com/en-us/library/office/ff745585.aspx
Const ppPrintAll = 1 ' Print all slides in the presentation.
Const ppPrintSelection = 2 ' Print a selection of slides.
Const ppPrintCurrent = 3 ' Print the current slide from the presentation.
Const ppPrintSlideRange = 4 ' Print a range of slides.
Const ppPrintNamedSlideShow = 5 ' Print a named slideshow.
' http://msdn.microsoft.com/en-us/library/office/ff744228.aspx
Const ppShowAll = 1 ' Show all.
Const ppShowNamedSlideShow = 3 ' Show named slideshow.
Const ppShowSlideRange = 2 ' Show slide range.
'
' This is the actual script
'
Dim inputFile
Dim outputFile
Dim objPPT
Dim objPresentation
Dim objPrintOptions
Dim objFso
If WScript.Arguments.Count <> 2 Then
WriteLine "You need to specify input and output files."
WScript.Quit
End If
inputFile = WScript.Arguments(0)
outputFile = WScript.Arguments(1)
Set objFso = CreateObject("Scripting.FileSystemObject")
If Not objFso.FileExists( inputFile ) Then
WriteLine "Unable to find your input file " & inputFile
WScript.Quit
End If
If objFso.FileExists( outputFile ) Then
WriteLine "Your output file (' & outputFile & ') already exists!"
WScript.Quit
End If
WriteLine "Input File: " & inputFile
WriteLine "Output File: " & outputFile
Set objPPT = CreateObject( "PowerPoint.Application" )
objPPT.Visible = True
objPPT.Presentations.Open inputFile
Set objPresentation = objPPT.ActivePresentation
Set objPrintOptions = objPresentation.PrintOptions
objPrintOptions.Ranges.Add 1,objPresentation.Slides.Count
objPrintOptions.RangeType = ppShowAll
' Reference for this at http://msdn.microsoft.com/en-us/library/office/ff746080.aspx
objPresentation.convert2(output)
objPresentation.Close
ObjPPT.Quit
Normally you would do this in PowerPoint with ExportAsFixedFormat(...). Since you chose VBS, you have to use SaveAs(...).
I assume you would also want to be able to batch convert ppt/pptx into pdf rather than specify a full file name one by one...
Option Explicit
'http://msdn.microsoft.com/en-us/library/office/bb251061(v=office.12).aspx
Const ppSaveAsPDF = 32
Dim oFSO ' Public reference to FileSystemObject
Dim oPPT ' Public reference to PowerPoint App
Main
Sub Main()
Dim sInput
If wscript.Arguments.Count <> 1 Then
Wscript.Echo "You need to specify input and output files."
wscript.Quit
End If
' PowerPoint version must be 12 or later (PowerPoint 2007 or later)
Set oPPT = CreateObject("PowerPoint.Application")
If CDbl(oPPT.Version) < 12 Then
Wscript.Echo "PowerPoint version must be 2007 or later!"
oPPT.Visible = True
oPPT.Quit
Set oPPT = Nothing
wscript.Quit
End If
' Store Input Argument and detect execute mode (single file / Folder batch mode)
sInput = wscript.Arguments(0)
Set oFSO = CreateObject("Scripting.FileSystemObject")
If IsPptFile(sInput) Then
PPT2PDF sInput
ElseIf oFSO.FolderExists(sInput) Then
Wscript.Echo "Batch Start: " & Now
Wscript.Echo "Root Folder: " & sInput
BatchPPT2PDF sInput
Else
Wscript.Echo """" & sInput & """ is not a PPT file or Folder!"
End If
' Close PowerPoint app if no other presentations are opened
If oPPT.Presentations.Count = 0 Then oPPT.Quit
Set oPPT = Nothing
Set oFSO = Nothing
End Sub
Private Sub BatchPPT2PDF(sFDR)
Dim oFDR, oFile
Wscript.Echo String(50, Chr(151))
Wscript.Echo "Processing Folder: " & sFDR
For Each oFile In oFSO.GetFolder(sFDR).Files
If IsPptFile(oFile.Name) Then
PPT2PDF(oFile)
End If
Next
For Each oFDR In oFSO.GetFolder(sFDR).SubFolders
BatchPPT2PDF oFDR
Next
End Sub
Private Function IsPptFile(sFile)
IsPptFile = (InStr(1, Right(sFile, InStrRev(sFile, ".")), "ppt") > 0)
End Function
Private Sub PPT2PDF(sFile)
On Error Resume Next
Dim sPDF, oPres
sPDF = Left(sFile,InstrRev(sFile,".")) & "pdf"
Set oPres = oPPT.Presentations.Open(sFile, True, False, False) ' Read Only, No Title, No Window
Err.Clear
oPres.SaveAs sPDF, ppSaveAsPDF
oPres.Close
Set oPres = Nothing
If Err.Number = 0 Then
Wscript.Echo "OK" & vbTab & sPDF
Else
Wscript.Echo "X" & vbTab & sPDF & " [ERR " & Err.Number & ": " & Err.Description & "]"
Err.Clear
End If
End Sub
I'm trying to edit one line in an ini file. DeviceName=APPLE to DeviceName="The User Input". I have it almost there from bits and pieces across the internet. It works except the end result is my file jwalk.ini with the correct entry after user input but the ini file has been renamed to just .ini, no jwalk before ini. I must be missing something. The file jwalk.ini already will exist I just need to edit it with the new user input and leave the file named the same.
My Script:
Const ForReading = 1
Const ForWriting = 2
Const OpenAsASCII = 0
Const CreateIfNotExist = True
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Open existing file for read access.
strInput = "c:\MyFolder\jwalk.ini"
Set objInput = objFSO.OpenTextFile(strInput, ForReading)
' Prompt for device name.
strDeviceName = InputBox("Enter devicename", "JWalk PC Name or Session Name")
' Specify the new file name.
strOutput = "c:\MyFolder\" & strComputer & ".ini"
' Create new file with write access.
Set objOutput = objFSO.OpenTextFile(strOutput, _
ForWriting, CreateIfNotExist, OpenAsASCII)
' Process input file.
Do Until objInput.AtEndOfStream
' Read next line of the input file.
strLine = objInput.ReadLine
' Search for line to be modified.
' Make search case insensitive.
If (InStr(LCase(strLine), "devicename=") > 0) Then
' Replace the line.
' You could also modify the line.
strLine = "devicename=" & strDeviceName
End If
' Write line to the output file.
objOutput.WriteLine strLine
Loop
' Clean up.
objInput.Close
objOutput.Close
' Delete the original file.
objFSO.DeleteFile(strInput)
Any ideas? Thanks.
If you'd have used Option Explicit, you'd have been told that
strOutput = "c:\MyFolder\" & strComputer & ".ini"
uses the undefined/uninitialized variable strComputer.
Here you are passing "strComputer" as a var, but never set it's value:
' Specify the new file name.
strOutput = "c:\MyFolder\" & strComputer & ".ini"
If you are trying to get the computer name you could consider this:
' Specify the new file name.
strOutput = "c:\MyFolder\" & GetComputerName() & ".ini"
Function GetComputerName()
Dim ob
Set ob = Wscript.CreateObject("Wscript.Network")
GetComputerName = ob.ComputerName
Set ob = nothing
End Function
I am trying to implement a find and replace for all files in a folder using a vbs script, here is what I have so far
Dim fso,folder,files,oldFileContents,newFileContents,FIND,REPLACE
FIND = "textToBeReplaced"
REPLACE = "localhost"
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder("HTML")
Set files = folder.Files
For each item In files
oldFileContents = GetFile(item.Path)
newFileContents = replace(oldFileContents,FIND,REPLACE,1,-1,1)
WriteFile FileName,newFileContents
Next
but when I try to run it I get and error, "Type Mismatch: 'GetFile'", what am I doing wrong?
The problem should be solved with code like:
' Constants Mr Gates forgot (but cf. vbTextCompare)
Const ForReading = 1
Const ForWriting = 2
' Configuration constants
Const csFind = "pdf"
Const csRepl = "puf"
' Dim & init for vars needed on *this* level
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim sTDir : sTDir = oFS.GetAbsolutePathName("..\data\test")
Dim oFile
For Each oFile In oFS.GetFolder(sTDir).Files
WScript.Echo "looking at", oFile.Name
' Dim & init for vars needed on *this* level
Dim sContent : sContent = goFS.GetFile(oFile.Path)
' For Skytunnels and other air-coders
WScript.Echo "content is not", sContent
' you got oFile, so use it; no need for .GetFile()
sContent = oFile.OpenAsTextStream(ForReading).ReadAll()
WScript.Echo "qed! content is", sContent
' Replace(expression, find, replacewith[, start[, count[, compare]]])
' don't use magic numbers; vbTextCompare is even pre-defined
sContent = Replace(sContent, csFind, csRepl, 1, -1, vbTextCompare)
WScript.Echo "new content", sContent
oFile.OpenAsTextStream(ForWriting).Write sContent
sContent = oFile.OpenAsTextStream(ForReading).ReadAll()
WScript.Echo "new content straight from file", sContent
WScript.Echo "------------------"
Next
output:
...
------------------
looking at 0000000000012345.20120302.pdf
content is not E:\trials\SoTrials\answers\9117277\data\test\0000000000012345.20120302.pdf
qed! content is This is the content of 0000000000012345.20120302.pdf
new content This is the content of 0000000000012345.20120302.puf
new content straight from file This is the content of 0000000000012345.20120302.puf
Important points:
Don't use a Dim-all-vars-ever-used-line at the top of your script
Avoid creation of unnecessary vars (folder, files, *contents), use
the vars you have properly (item==oFile)
.GetFile() returns a File object, not the file's content
You missed out the fso. on
oldFileContents = fso.GetFile(item.Path)
and
fso.WriteFile FileName,newFileContents
EDIT: as per discussion below, please note this answer was only meant to show where your error was occurring. It was assumed that your intent was to develop your code further once your got past this error, which if so, I’m sure you’ve already seen Ekkehard has provided some very helpful guidance on his answer.
how to read text file word by word in VB script? please give all possible functions.
This:
Dim sAll : sAll = readAllFromFile("..\data\wbw.txt")
WScript.Echo sAll
WScript.Echo "-----------------------"
Dim oRE : Set oRE = New RegExp
oRE.Global = True
oRE.Pattern = "\w+"
Dim oMTS : Set oMTS = oRE.Execute(sAll)
Dim oMT
For Each oMT In oMTS
WScript.Echo oMT.Value
Next
Output:
===============================================================================
How to read text file word by word in VB script?
Please give all possible functions.
First, read the file line-by-line into an array. Then, when you're reading
through the array, parse each line word-by-word. As such:
-----------------------
How
to
read
text
file
word
by
word
in
VB
script
Please
give
all
possible
functions
First
read
the
file
line
by
line
into
an
array
Then
when
you
re
reading
through
the
array
parse
each
line
word
by
word
As
such
===============================================================================
avoids all the atrocities of Zomgie's solution:
Not usable with Option Explicit
Useless Dim of fixed array of no size
Useless array of lines
Costly ReDim Preserve with extra counter
Useless variable inputText
Split on " " makes "First," a word
First, read the file line-by-line into an array. Then, when you're reading through the array, parse each line word-by-word. As such:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\file.txt", ForReading)
Const ForReading = 1
Dim arrFileLines()
i = 0
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(i)
arrFileLines(i) = objFile.ReadLine
i = i + 1
Loop
objFile.Close
For Each strLine in arrFileLines
inputText = strLine
outputArray = Split(inputText)
For Each x in outputArray
WScript.Echo "Word: " & x
Next
Next