Emailing preceded by text files consolidation into excel - vbscript

I have two text files with following content:
file1.txt:
Windows 1.36
Linux 2.78
MacOS 3.45
Ubuntu 4.12
FreePhysicalMemory 30.12
TotalVisibleMemorySize 48.00
file2.txt:
MacOS 6.39
Windows 4.42
Linux 5.76
Android 3.46
FreePhysicalMemory 31.65
TotalVisibleMemorySize 48.00
output.xls:
OPERATING SYSTEM SERVER1 SERVER2
Windows 1.36 4.42
Linux 2.78 5.76
MacOS 3.45 6.39
Ubuntu 4.12 0.00
Android 0.00 3.46
FreePhysicalMemory 30.12 31.65
TotalVisibleMemorySize 48.00 48.00
I want to achieve following two things in a VBScript program or in any, which is appropriate to run on windows server:
Insert the contents of both file1.txt and fil2.txt in a excel
sheet output.xls like above.
Mail the content of output.xls file as a body in email.
I think, Point2 is being achieved using below code but not getting how can i achieve Point1 in same program.
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const FileToBeUsed = "c:\output.xls"
Dim objCDO1
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(FileToBeUsed, ForReading)
Set objCDO1 = CreateObject("CDO.Message")
objCDO1.Textbody = f.ReadAll
f.Close
objCDO1.TO ="sunny#abc.com"
objCDO1.From = "dontreply#abc.com"
objCDO1.Subject = "Server Memory"
objCDO1.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration /sendusing") = 2
objCDO1.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtpb.intra.abc.com"
objCDO1.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration /smtpserverport") = 25
objCDO1.Configuration.Fields.Update
objCDO1.Send
Set f = Nothing
Set fso = Nothing
Any suggestion is highly appreciated.
Note:My purpose here is to send email with properly formatted and aligned data.
EDIT1:
This is all i could do regarding points 1,2,3.
Don't know how to consolidate all this in a HTML email Body format..:(
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim fso,f,objFSO,objFile,objRE, FileName
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
const strFileName1 = "D:\file1.txt"
const strFileName2 = "D:\file2.txt"
Set objFile = objFSO.OpenTextFile(strFileName1, fsoForReading) + objFSO.OpenTextFile(strFileName2, fsoForReading)
objobjFile.Close
Set objFile = Nothing
Set objFSO = Nothing
Set objRE = New RegExp
With objRE
.Pattern = "[A-Z][0-9]"
.IgnoreCase = False
.Global = False
End With
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
const strFileName1 = "D:\file1.txt"
const strFileName2 = "D:\file2.txt"
Set objFile = objFSO.OpenTextFile(strFileName1, fsoForReading) + objFSO.OpenTextFile(strFileName2, fsoForReading)
Do Until objFile.AtEndOfStream
strSearchString = objFile.ReadLine
Set colMatches = objRegEx.Execute(strSearchString)
If colMatches.Count > 0 Then
For Each strMatch in colMatches
Wscript.Echo strSearchString
Next
End If
Loop
objFile.Close
Class memory1class
Public operatingsystem, memory
End Class
Dim memory1dict: Set memory1 = CreateObject("Scripting.Dictionary")
Dim memory2dict: Set memory2 = CreateObject("Scripting.Dictionary")
Dim memory1: Set memory1 = new memory1class
With memory1
.operatingsystem = "?"
.memory = "?"
End With
memory1dict.Add "1", memory1
Dim memory1details: Set memory1details = memory1dict.Item("1")
WScript.StdOut.WriteLine("operatingsystem:" & memory1details.first & " " & memory1details.memory & " )

I don't want to directly give you code, because this is a good opportunity for you to learn more about the different options you have available for solving the problem yourself, but I can give you a rough outline of what I would do.
Open the two text files for reading. Windows provides a "Scripting" library which contains the FileSystemObject. You would declare an instance of it as below, and you can google for the specifics of how to use it to open a text file:
Set fso = CreateObject("Scripting.FileSystemObject")
Read each file in a line at a time. Parse each line to get the "name" part and the "number" part as distinct values. You can do this by combining the InStr, InStrRev, and Mid functions or you can use the more powerful RegExp library (VBScript's Regular Expression class).
Set re = New RegExp
Store each "name" and "value" into a data structure for later use - I recomment an associative array such as VBScript's Dictionary class. Using a separate one for each text file will allow you to cross-reference them later.
Set dictStats1 = CreateObject("Scripting.Dictionary")
To display the data formatted correctly in the email, I suggest using an HTML table. In addition to the TextBody, the CDO.Message object has an HTMLBody property to allow you to give the email structured formatting instead of just raw text. Extrapolating from the simple example on w3school.com, you can construct a function that will accept the two dictionaries and use them to construct the HTML table and return it as a string to be loaded into the email via the HTMLBody property.
I hope that helps! Let me know if you have any questions about the specifics.

Related

Overwrite value in vbscript

I have to update test.txt with new values i,e. delete value {"AAA":"777" , "BBB":"888"} and add {"ABC:"123","GHN:"246"} in tag
but my script append the value as {"AAA":"777" , "BBB":"888"} {"ABC:"123","GHN:"246"
strFile="test.txt"
Const ForAppending = 8
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile(strFile, ForAppending , True)
objFile.Write("{")
Dim dict
Set dict= CreateObject("Scripting.Dictionary")
dict.Add "ABC","123"
dict.Add "GHN","246"
k=dict.Keys
v=dict.Items
For j=0 to dict.Count-1
objFile.Write(chr(34)&k(j)&":"&chr(34)&v(j)&chr(34)&",")
Next
==============
Test.txt
[Valid]
api = https://test.com
Alpha = FALSE
tag = {"AAA":"777" , "BBB":"888"}
I've never used the dictionary object/don't know how, so this may not be a viable solution for you depending on whether you need certain things that the object provides... but without resorting to regex, could you not simply do something like this?
Dim fso, filecontent, file
Set fso = CreateObject("Scripting.FileSystemObject")
file = "C:\temp\test.txt"
filecontent = fso.OpenTextFile(file, 1, False).ReadAll
filecontent = Replace(filecontent, "{""AAA"":""777"" , ""BBB"":""888""}", "{""ABC:""123"",""GHN:""246""}")
fso.OpenTextFile(file, 2, True).Write filecontent

Search and divide numeric strings

I have an output.txt file which has following content:
Windows 6543765432
Linux 4534653463
MacOS 3564325
Ubuntu 8235646255
I want to create a VBScript which searches for all numeric values in output.txt and divide them by 1024 so that memory in KB can be changed into MB.
I have tried in batch here, but due to 2 GB limitation it's not working in above case.
Your top-level task is to modify a small file of structured text. The 'design pattern' for such a task is:
Get a FileSystemObject
Specify the full file path
Read the content
Modify the content
Write the modified content back
Your sub-task of modification involves computations on non-constant /varying parts; then a 'RegExp.Replace with Function' strategy should be used:
Define a RegExp (global, identify the parts to change)
.Replace(input, GetRef("function to do the computations on the parts"))
In your case, that function should convert the (string) parts to numbers, divide then, and return the result converted to strings.
In code:
Option Explicit
Const FSPEC = "..\testdata\txt\19556079.txt"
Dim oFS : Set oFS = CreateObject( "Scripting.FileSystemObject" )
Dim sAll : sAll = Modify(oFS.OpenTextFile(FSPEC).ReadAll())
oFS.CreateTextFile(FSPEC).Write sAll
WScript.Echo oFS.OpenTextFile(FSPEC).ReadAll()
Function Modify(s)
Dim re : Set re = New RegExp
re.Global = True
re.Pattern = "\d+"
Modify = re.Replace(s, GetRef("FiMoReFunc"))
End Function
Function FiMoReFunc(sM, sP, sS)
FiMoReFunc = CStr(CDbl(sM) / 1024)
End Function
For a more fancy output:
FiMoReFunc = Right(Space(20) & FormatNumber(CDbl(sM) / 1024, 1, True) & " Unit", 20)
output:
Windows 6,390,395.9 Unit
Linux 4,428,372.5 Unit
MacOS 3,480.8 Unit
Ubuntu 8,042,623.3 Unit
Try this
Option Explicit
Const FILE = "output.txt"
Dim fso
Dim ts,line
Dim match,matches
Dim os,mem
Set fso = CreateObject("Scripting.FilesystemObject")
Set ts = fso.OpenTextFile(FILE)
With New RegExp
.IgnoreCase = True
While Not ts.AtEndOfStream
line = ts.ReadLine
.Pattern = "[a-z]+"
Set matches = .Execute(line)
For Each match In matches
os = match.Value
Next
.Pattern = "\d+"
Set matches = .Execute(line)
For Each match In matches
mem = (CDbl(match.Value) / 1024)
Next
WScript.Echo os & vbTab & mem
Wend
End With
Set ts = Nothing
Set fso = Nothing
WScript.Quit

Extract text string from file

I am writing a utility to collect all system information from all devices on a network to an XML document, and one of the values is a certain software version number. Unfortunately the version number is only stored in a single text file on each machine (c:\master.txt) the even more fun part is, each text file is formatted differently depending on the image that was used.
One could say
Product Number: 11dsSt2 BRANDONII,STNS6.0.2.200
The next
Ver: 22335TS BOX2 S6.1.3.011,STN
and so on.
What I did, is create a VBS that looks for a number pattern that matches the version pattern, which is
[A-Z]#.#.#.###
This works, however I just want to output that pattern, not the entire line. Here is my code. Any Suggestions?
Const ForReading = 1
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Pattern = "[A-Z]{1}[0-9]{1}.[0-9]{1}.[0-9]{1}.[0-9]{3}"
objregex.global = true
objregex.ignorecase = true
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\master.txt", ForReading)
Do Until objFile.AtEndOfStream
strSearchString = objFile.ReadLine
set colMatches = objRegEx.Execute(strSearchString)
If colMatches.Count > 0 Then
Addmatch
End If
Loop
objFile.Close
Sub Addmatch 'Creates a text file with the part number
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile1 = objFSO.OpenTextFile("C:\test.txt", ForAppending, True)
objFile1.Writeline strSearchString
objFile1.Close
end sub
You're storing the entire line you read from the file (that you have in strSearchString) instead of just the matched text. Use something like this instead (untested!):
if ColMatches.Count > 0 then
AddMatch(ColMatches(0)) ' Just grab the matched text and pass to AddMatch
End If
Sub AddMatch(strMatchedText) ' Change to accept parameter of text to write out
' Other code
objFile1.Writeline strMatchedText
objFile1.Close
End Sub
Use the first/one and only match to obtain the value, and pass this to a slightly modified version of Addmatch:
If colMatches.Count > 0 Then
Addmatch colMatches(0).Value
End If
...
Sub Addmatch(sWhatToWriteLn) ' some truthful comment
Const ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile1 = objFSO.OpenTextFile("C:\test.txt", ForAppending, True)
objFile1.Writeline sWhatToWriteLn
...

Why does this VBScript throw an error when trying to create a file?

I have found this script and cant seem to figure out why it throws an error when trying to create the file C:\IPSecWeights.xls.
The line that I am having problems with so far is:
Set objWorkbook = objExcel.Workbooks.Open(FileLoc)
I get an error that the file could not be found. How can I rewrite my code to fix this?
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Dim objFSO,objFile
Dim arrLines
Dim strLine
Dim objExcel,objWorkbook
Dim FileLoc
Dim intRow
Dim objDictionary
FileLoc = "C:\IPSecWeights.xls"
Sub ExcelHeaders()
Set objRange = objExcel.Range("A1","G1")
objRange.Font.Size = 12
objRange.Interior.ColorIndex=15
objexcel.cells(1,1)="Filter Name"
objexcel.cells(1,2)="Source"
objexcel.cells(1,3)="Destination"
objexcel.cells(1,4)="Source Port"
objexcel.cells(1,5)="Destination Port"
objexcel.cells(1,6)="Protocol"
objexcel.cells(1,7)="Direction"
End Sub
Function RegExFind(strText,strPattern)
Dim regEx
Dim match, Matches
Dim arrMatches
Dim i : i = 0
Set regEx = New RegExp
regEx.IgnoreCase = True
regEx.Global = True
regEx.Pattern = strPattern
Set matches = regEx.Execute(strText)
ReDim arrMatches(Matches.Count)
For Each match In Matches
For Each SubMatch In match.Submatches
arrMatches(i) = Submatch
i = i + 1
Next
Next
RegExFind = arrMatches
End Function
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(WScript.Arguments(0),ForReading)
Set objExcel = CreateObject("excel.application")
Set objWorkbook = objExcel.Workbooks.Open(FileLoc)
objExcel.Visible = True
ExcelHeaders ' Create Excel Headers
rePolicy = "Policy Name\s+:\s(.+)"
reSRCAddr = "Source Address\s+:\s(.+)"
reDSTAddr = "Destination Address\s+:\s(.+)"
reProtocol = "Protocol\s+:\s(.+)"
reSRCPort = "Source Port\s+:\s(.+)"
reDSTPort = "Destination Port\s+:\s(.+)"
reDirection = "Direction\s+:\s(.+)"
strText = objFile.ReadAll
objFile.Close
Dim arrPolicy, arrSRCAddr, arrDSTAddr, arrProtocol, arrSRCPort, arrDSTPort, arrDirection
arrPolicy = RegExFind(strText, rePolicy)
arrSRCAddr = RegExFind(strText, reSRCAddr)
arrDSTAddr = RegExFind(strText, reDSTAddr)
arrProtocol = RegExFind(strText, reProtocol)
arrSRCPort = RegExFind(strText, reSRCPort)
arrDSTPort = RegExFind(strText, reDSTPort)
arrDirection = RegExFind(strText, reDirection)
intRow = 2
For i = 0 To UBound(arrPolicy)
objExcel.Cells(introw,1) = arrPolicy(i)
objExcel.Cells(introw,2) = arrSRCAddr(i)
objExcel.Cells(introw,3) = arrDSTAddr(i)
objExcel.Cells(introw,4) = arrSRCPort(i)
objExcel.Cells(introw,5) = arrDSTPort(i)
objExcel.Cells(introw,6) = arrProtocol(i)
objExcel.Cells(introw,7) = arrDirection(i)
intRow = intRow + 1
Next
objFile.Close
objWorkbook.save
'objExcel.Quit
I suspect that "File Not Found" is a somewhat misleading error message. That is to say, your actual problem is file system permissions, but VBScript is stubbornly reporting this as "File Not Found" instead of a more sensible error.
Presumably the script worked fine in earlier versions of Windows, but you're now trying it on a computer with Vista or later installed, which introduce a bunch of additional security features and write protection. User Account Control (UAC) will not let applications or scripts write to the root level of your hard disk.
This really shouldn't a problem, of course, as legitimate applications have no need to tamper with files at the root level of the hard drive or in shared system folders (like C:\Windows), but occasionally crops up during testing.
Change the file path in the script to something you're guaranteed to have read/write access to, like your "My Documents" folder. For deployment, you shouldn't be hardcoding a file system path anyway. Use the GetSpecialFolder function of the FileSystemObject to retrieve the path, instead.

Read and write into a file using VBScript

How can we read and write some string into a text file using VBScript? I mean I have a text file which is already present so when I use this code below:-
Set fso = CreateObject("Scripting.FileSystemObject" )
Set file = fso.OpenTextFile("C:\New\maddy.txt",1,1)
This opens the file only for reading but I am unable to write anything
and when I use this code:-
Set fso = CreateObject("Scripting.FileSystemObject" )
Set file = fso.OpenTextFile("C:\New\maddy.txt",2,1)
I can just use this file for writing but unable to read anything. Is there anyway by which we can open the file for reading and writing by just calling the OpenTextFile method only once.
I am really new to VBScript. I am only familiar with C concepts.
Is there any link to really get me started with VBScript?
I guess I need to have a good knowledge of the objects and properties concepts.
You can create a temp file, then rename it back to original file:
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\test\file.txt"
strTemp = "c:\test\temp.txt"
Set objFile = objFS.GetFile(strFile)
Set objOutFile = objFS.CreateTextFile(strTemp,True)
Set ts = objFile.OpenAsTextStream(1,-2)
Do Until ts.AtEndOfStream
strLine = ts.ReadLine
' do something with strLine
objOutFile.Write(strLine)
Loop
objOutFile.Close
ts.Close
objFS.DeleteFile(strFile)
objFS.MoveFile strTemp,strFile
Usage is almost the same using OpenTextFile:
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\test\file.txt"
strTemp = "c:\test\temp.txt"
Set objFile = objFS.OpenTextFile(strFile)
Set objOutFile = objFS.CreateTextFile(strTemp,True)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
' do something with strLine
objOutFile.Write(strLine & "kndfffffff")
Loop
objOutFile.Close
objFile.Close
objFS.DeleteFile(strFile)
objFS.MoveFile strTemp,strFile
Find more about the FileSystemObject object at http://msdn.microsoft.com/en-us/library/aa242706(v=vs.60).aspx. For good VBScript, I recommend:
Option Explicit to help detect typos in variables.
Function and Sub to improve readilbity and reuse
Const so that well known constants are given names
Here's some code to read and write text to a text file:
Option Explicit
Const fsoForReading = 1
Const fsoForWriting = 2
Function LoadStringFromFile(filename)
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(filename, fsoForReading)
LoadStringFromFile = f.ReadAll
f.Close
End Function
Sub SaveStringToFile(filename, text)
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(filename, fsoForWriting)
f.Write text
f.Close
End Sub
SaveStringToFile "f.txt", "Hello World" & vbCrLf
MsgBox LoadStringFromFile("f.txt")
You could open two textstreams, one for reading
Set filestreamIn = CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Test.txt,1)
and one for appending
Set filestreamOUT = CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Test.txt,8,true)
The filestreamIN can read from the begining of the file, and the filestreamOUT can write to the end of the file.
Don't think so...you can only use openTextFile for reading (1), writing (2), or appending (8). Reference here.
If you were using VB6 instead of VBScript, you could do:
Open "Filename" [For Mode] [AccessRestriction] [LockType] As #FileNumber
Using the Random mode. For example:
Open "C:\New\maddy.txt" For Random As #1
You could put it in an Excel sheet, idk if it'll be worth it for you if its needed for other things but storing info in excel sheets is a lot nicer because you can easily read and write at the same time with the
'this gives you an excel app
oExcel = CreateObject("Excel.Application")
'this opens a work book of your choice, just set "Target" to a filepath
oBook = oExcel.Workbooks.Open(Target)
'how to read
set readVar = oExcel.Cell(1,1).value
'how to write
oExcel.Cell(1,2).value = writeVar
'Saves & Closes Book then ends excel
oBook.Save
oBook.Close
oExcel.Quit
sorry if this answer isnt helpful, first time writing an answer and just thought this might be a nicer way for you
You could also read the entire file in, and store it in an array
Set filestreamIN = CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Test.txt",1)
file = Split(filestreamIN.ReadAll(), vbCrLf)
filestreamIN.Close()
Set filestreamIN = Nothing
Manipulate the array in any way you choose, and then write the array back to the file.
Set filestreamOUT = CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Test.txt",2,true)
for i = LBound(file) to UBound(file)
filestreamOUT.WriteLine(file(i))
Next
filestreamOUT.Close()
Set filestreamOUT = Nothing
Regardless of what you're trying to do there should be no need to read to and write to a file at the same time. It would also use more memory which should always be avoided. I'd suggest reading the entire file using the .ReadAll method and then close it and do whatever you need to do with the data (assuming you read the contents into a variable) and then do a write to the same file and overwrite the file. If you're concerned with having something go wrong when over-writing the current file you could always try to write it to a different file and throw an error if that doesn't work before trying to over-write the original.
Below is some simple code to execute this:
sLocation = "D:\Excel-Fso.xls"
sTxtLocation = "D:\Excel-Fso.txt"
Set ObjExl = CreateObject("Excel.Application")
Set ObjWrkBk = ObjExl.Workbooks.Open(sLocation)
Set ObjWrkSht = ObjWrkBk.workSheets("Sheet1")
ObjExl.Visible = True
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSOFile = FSO.CreateTextFile (sTxtLocation)
sRowCnt = ObjWrkSht.usedRange.Rows.Count
sColCnt = ObjWrkSht.usedRange.Columns.Count
For iLoop = 1 to sRowCnt
For jLoop = 1 to sColCnt
FSOFile.Write(ObjExl.Cells(iLoop,jLoop).value) & vbtab
Next
Next
Set ObjWrkBk = Nothing
Set ObjWrkSht = Nothing
Set ObjExl = Nothing
Set FSO = Nothing
Set FSOFile = Nothing
This is for create a text file
For i = 1 to 10
createFile( i )
Next
Public Sub createFile(a)
Dim fso,MyFile
filePath = "C:\file_name" & a & ".txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.CreateTextFile(filePath)
MyFile.WriteLine("This is a separate file")
MyFile.close
End Sub
And this for read a text file
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Set dict = CreateObject("Scripting.Dictionary")
Set file = fso.OpenTextFile ("test.txt", 1)
row = 0
Do Until file.AtEndOfStream
line = file.Readline
dict.Add row, line
row = row + 1
Loop
file.Close
For Each line in dict.Items
WScript.Echo line
WScript.Sleep 1000
Next

Resources