INI file - retrieve a section name by key name in VBS - vbscript

I would like to retrieve a section name from an INI file with only a unique key name
My ini file :
...
[Area.104]
Title=Central North America
Local=Scenery\NAMC
Layer=104
Active=TRUE
Required=FALSE
[Area.105]
Title=Eastern North America
Local=Scenery\NAME
Layer=105
Active=TRUE
Required=FALSE
[Area.106]
Title=Western North America
Local=Scenery\NAMW
Layer=106
Active=TRUE
Required=FALSE
...
How can I get section name [Area.105] from unique key Title=Eastern North America ???
Thank you

I have two ways of finding the required Area code:
METHOD 1
Option Explicit
Dim strFilePath, ofso, ofile, strFileData, strKey, strPrev, strCurr
strFilePath="" '<-- Enter the absolute path of your .ini file in this variable
Set ofso = CreateObject("scripting.FileSystemObject")
Set ofile = ofso.OpenTextFile(strFilePath,1,False)
strKey = "Eastern North America" '<-- Enter Unique title for which you want the Area code
strPrev=""
strCurr=""
Do
strCurr = ofile.ReadLine
If InStr(1,strCurr,strKey)<>0 Then
Exit Do
End If
strPrev = strCurr
Loop Until ofile.AtEndOfStream
MsgBox strPrev
Set ofile = Nothing
Set ofso = Nothing
METHOD 2(Using Regular Expression)
Option Explicit
Dim strFilePath, ofso, ofile, strFileData, strKey, re, objMatches
strFilePath="" '<-- Enter the absolute path of your .ini file in this variable
Set ofso = CreateObject("scripting.FileSystemObject")
Set ofile = ofso.OpenTextFile(strFilePath,1,False)
strFileData = ofile.ReadAll()
ofile.Close
strKey = "Eastern North America" '<-- Enter Unique title for which you want the Area code
Set re = New RegExp
re.Global=True
re.Pattern="\[([^]]+)]\s*Title="&strKey
Set objMatches = re.Execute(strFileData)
If objMatches.Count>0 Then
MsgBox objMatches.Item(0).Submatches.Item(0)
End If
Set re = Nothing
Set ofile = Nothing
Set ofso = Nothing
>>>Click here for Regex Demo<<<
Regex Explanation:
\[ - matches literal [
([^]]+) - capture 1+ occurrence of any character which is not ] in a group
] - matches literal ]
\s* - matches 0+ white-spaces(which include the newline characters)
Title= - matches the text Title=. This is then concatenated with the variable strKey containing the value of unique title.

Related

VBScript to copy/move file by lowest value in filename

I'm fairly new to scripting and am in need of some help. I have come across a unique situation for a Non-Profit client of ours that requires us to compare two or more files in a specific folder and move the file with the lowest numerical value in the filename.
This organization runs a non-profit radio station which has content submitted from hundreds of volunteers that name their files (when they record more than one) with various numbers at the end that either represent the date or the order in which the files are to be aired.
Essentially I am looking to create a vbscript (because I think it can be done this way) that will run with windows task scheduler 30 minutes prior to the first air date of the content and move the file with the lowest value (if more than one file exists) to a folder where it will be automatically processed by the radio automation software.
Examples of files in a folder might look something like these:
Folder1: (in this instance, "news.mp3" is the lowest value)
news.mp3
news1.mp3
news2.mp3
Folder2:
entertainment24.mp3
entertainment26.mp3
Folder3:
localnews081420.mp3
localnews081520.mp3
Honestly, on this one, I'm not even sure where to start. I've found several scripts that can look at file date or a specific numerical or date format in the filename, but none that can parse numbers from a filename and move/copy a file based on the numerical value. I'm hoping there is someone out there smarter than me that can point me in the right direction. Thanks for looking at my problem!
One script I've been playing with (from the scripting guy) looks at specific years in a filename:
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colFiles = objWMIService.ExecQuery _
(“ASSOCIATORS OF {Win32_Directory.Name=’C:\Test’} Where ” _
& “ResultClass = CIM_DataFile”)
Set objRegEx = CreateObject(“VBScript.RegExp”)
For Each objFile in colFiles
objRegEx.Global = True
objRegEx.Pattern = “\d{4}”
strSearchString = objFile.FileName
Set colMatches = objRegEx.Execute(strSearchString)
strYear = colMatches(0).Value
strNewFile = “C:\Test\” & strYear & “\” & objFile.FileName & _
“.” & objFile.Extension
objFile.Copy(strNewFile)
objFile.Delete
Next
...but I can't seem to make the leap to regular numbers and then take a lowest value...
You can use FileSystemObject to Work with Drives, Folders and Files.
Also i used GETNUM function to get number.
Try my way :
sFolder = "C:\Test\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
For Each objFile in oFSO.GetFolder(sFolder).Files
Number=GETNUM(objFile.Name)
strNewFile = sFolder & Number & "\" & objFile.Name
If NOT (oFSO.FolderExists(sFolder & Number)) Then
oFSO.CreateFolder(sFolder & Number)
End If
oFSO.MoveFile objFile, strNewFile
Next
Function GETNUM(Str)
For i=1 To Len(Str)
if IsNumeric(Mid(Str,i,1)) Then
Num=Num&Mid(Str,i,1)
End if
Next
GETNUM=Num
End Function
For understanding the used code and how they work, open these sites and read all pages very carefully.
MoveFile method
Vbs Script to check if a folder exist

Using Find Method in Vbscript for search Word file. Can find character but not replace

I am trying to search through Word documents and try to find a certain character. The ± character to be precise. The code can find the character because I have it print to screen if it found it. But it is unable to replace the character.
I have even tried searching for a random string I knew was in the files such as "3" and replacing it with something random such as "dog". But nothing works. It still finds the characters but does not replace.
Option Explicit
Dim objWord, objDoc, objSelection, oFSO, folder, jj, file
Set objWord = CreateObject("Word.Application")
objWord.Visible = False: objWord.DisplayAlerts = False
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set folder = oFSO.GetFolder("C:\Users\Desktop\myFolder")
For Each file In folder.Files
objWord.Documents.Open file.path, False, True ' path, confirmconversions, readonly
Set objDoc = objWord.ActiveDocument
Set objSelection = objWord.Selection
objSelection.Find.Forward = True
objSelection.Find.MatchWholeWord = False
objSelection.Find.Text = ChrW(177)
objSelection.Find.Replacement.Text = "ChrW(177)"
objSelection.Find.Execute
If objSelection.Find.Found = True then
Wscript.echo "Character Found"
End If
objDoc.close
Next
objWord.Quit
The problem is that the code in the question doesn't specify that a replacement should take place. This is set in the Execute method, as a parameter.
Since this is VBScript rather than VBA it's not possible to use the enumerations (such as wdReplaceAll). Instead, it's necessary to specify the numeric equivalent of an enumeration. VBA without enumerations...
objSelection.Find.Execute Replace:=2, Forward:=True, Wrap:=0
However, VBScript doesn't accept named arguments, so all the arguments need to be specified by position, with "empty commas" if nothing should be specified.
objSelection.Find.Execute , , , , , , , 0, , , 2
To discover the numeric equivalent consult either the VBA Object Library (F2 in the VBA Editor), the Language Reference or use the Immediate Window (Ctrl+G) in the VBA Editor like this: ?wdReplaceAll then press Enter.
objSelection.Find.Execute
should be
objSelection.Find.Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
(assuming you want to replace all occurrences
This code running inside a word module will replace all "cat" with "dog"
Sub test()
Dim objdoc As Document
Dim objSelection As Range
Set objdoc = ActiveDocument
Set objSelection = Selection.Range
With objSelection.Find
.Forward = True
.MatchWholeWord = False
.Text = "Cat"
.Replacement.Text = "Dog"
.Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
If .Found Then
Debug.Print "Found"
End If
End With
End Sub
However you're running in vbscript using late binding, so possibly there's a type issue - you're selection object may not be a range but a variant?

How can I add a line between output text?

The next title will replace the previous title on the same line. As a result, only the last one of the titles will finally remain in the text file.
My following VBScript will find a number of update titles (="Title" in the script). Each "Title" will be shown in the output file "c:\Testing\testing.txt". One title will be shown on the first line at a time. The command "Next" will bring up the next title, which will be shown on the same line when the previous title disappears. Simply put, the next title will replace the previous title on the first line. As a result, only the last one of the titles will finally remain in the file. Is it possible to add an empty line between two titles, so that all titles will be shown in the file?
Set Job = CreateObject("Microsoft.Update.Session")
Set Tool = Job.CreateupdateSearcher()
Set Result = Tool.Search("IsInstalled=0 and IsHidden=0")
For Number = 0 To Result.Updates.Count-1
Set Title = Result.Updates.Item(Number)
Set objFSO = CreateObject("Scripting.FileSystemObject")
outFile = "c:\Testing\testing.txt"
Set objFile = objFSO.CreateTextFile(outFile, True)
objFile.Write Title & vbCrLf
objFile.Close
Next
I want the titles shown on different lines rather than on the same line.
I just found that both OpenTextFile and 8, True are not necessary in the following script, which works at my end.
Set Job = CreateObject("Microsoft.Update.Session")
Set Tool = Job.CreateupdateSearcher()
Set Result = Tool.Search("IsInstalled=0 and IsHidden=0")
Set X = CreateObject("Scripting.FileSystemObject")
Set Z = X.CreateTextFile("Updates_found.txt")
For Number = 0 To Result.Updates.Count-1
Set Title = Result.Updates.Item(Number)
Z.Writeline Title
Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("c:\Testing\testing.txt", True) 'True = overwrite existing file
objFile.Close
Set objFile = objFSO.OpenTextFile("c:\Testing\testing.txt", 8) '8 = For Appending
objFile.WriteLine ("Title")
objFile.WriteLine ("Title2")
objFile.Close
Hope this helps!

VBS Readline - using instr(), to match data whilst ignoring extra spaces

I'm trying to find a way to enhance the reliability of my script. It already works but can be thrown off with a simple extra space in the imported text file.
So I'd like to change my script to Readline if I can find a way to do something like:
Example of text in the .txt file:
FLIGHTS OVER TUSKY PLEASE FILE:
AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT
FLIGHTS OVER EBONY PLEASE FILE:
AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT
I know the following doesn't work but if there was a simple modification this would be good.
set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run("C:\Downloads\software\putty.exe -load "testing")
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
strLine = objFile.ReadAll
If InStr(strLine1, "OVER TUSKY PLEASE") and InStr(strLine2, "BAYYS..PUT..DIRECT") Then
trans307="TUSKY"
ind306="4"
WHAT I'M USING NOW:
I edit the text file in notepad++ to FIND & REPLACE "\n" with "" and "\r" with " " and then it's all one text string and I search for strings within that string.
If InStr(strLine, "FLIGHTS OVER TUSKY PLEASE FILE: AT OR WEST OF A LINE ..RBV..LLUND..BAYYS..PUT..DIRECT") _
or InStr(strLine, "FLIGHTS OVER TUSKY PLEASE FILE: AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT...DIRECT") Then
trans308C="TUSKY"
ind308C="4"
Problem: If the creators of the text file put another space " " anywhere in this line "AT OR WEST OF A LINE RBV..LLUND..BAYYS..PUT..DIRECT" the script will not identify the string. In the above example I have had to create another or InStr(strLine, "") statement with an extra space or with a couple of dots.
UPDATE:
I will try something like:
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
strLine1 = objFile.Readline(1)
strLine2 = objFile.Readline(2)
If InStr(strLine1, "FLIGHTS OVER TUSKY") and InStr(strLine2, "RBV..LLUND..BAYYS..PUT..DIRECT") Then
trans1="TUSKY"
ind1="4"
and see if I can get that to read 2 lines at a time, and loop through the text file.
If you're scared of regex and looking for an alternative, you could create a clunky function to add to your script. Based on your samples, it would seem that fullstops are also never normally used for normal purposes and tend to represent spaces. (I would recommend using Regex instead!)
Using these presumptions, you could create a clunky function like this, that looks for fullstops, and converts them to spaces, removing extra spaces.. Obviously, this relies heavily on your input source files not changing too much - you really should be using a regex to work this stuff out properly.
You could test for the basic expected results using something like the function below.
For example say you had a line of text set in firLine with multiple spaces or fullstops, the function would recognize this:
firLine = "THIS.IS.A.TEST..YOU...SEE MULTIPLE SPACES"
if instr(sanitize(firLine),"THIS IS A TEST YOU SEE MULTIPLE SPACES") then
wscript.echo "Found it"
End If
Here's the clunky function that you could just paste at the end of your script:
Function sanitize(srStr)
Dim preSanitize, srC, spaceMarker
preSanitize = ""
for srC = 1 to len(srStr)
if mid(srStr, srC, 1) = "." then
preSanitize = preSanitize & " "
else
preSanitize = preSanitize & mid(srStr, srC, 1)
End If
spaceMarker = false
sanitize = ""
for srC = 1 to len(preSanitize)
If mid(preSanitize, srC, 1) = " " then
if spaceMarker = false then
sanitize = sanitize & mid(preSanitize, srC, 1)
spaceMarker = true
End If
else
sanitize = sanitize & mid(preSanitize, srC, 1)
spaceMarker = false
End If
Next
End Function
InStr() is a good tool for checking whether a strings contains a fixed/literal string or not. To allow for variation, you should use Regular Expressions (see this or that).
First of all, however, you should work on your specs. Describe in plain words and with some samples what you consider (not) to be a match.
E.g.: A string containing the words "FLIGHTS", "OVER", and "TUSKY" in that order with at least one space in between is a match - "FLIGHTS OVER TUSKY", "FLIGHTS OVER TUSKY"; "FLIGHTS OVER TUSKANY" is a 'near miss' - what about "AIRFLIGHTS OVER TUSKY"?
GREAT NEWS! I finally figured out how to do this.
Here is a snippet from "Entries1.txt"
FLIGHTS OVER BRADD KANNI PLEASE FILE:
VIA J174.RIFLE..ACK..DIRECT
OR RBV.J62.ACK..DIRECT
FLIGHTS OVER KANNI WHALE PLEASE FILE:
VIA J174.RIFLE..ACK..DIRECT OR
FLIGHTS OVER WHALE PLEASE FILE:"
ETC, ETC
set WshShell = WScript.CreateObject("WScript.Shell")
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("C:\Users\AW\Desktop\Entries1.txt")
Do until objFile.AtEndOfStream
firLine = objFile.ReadLine
If InStr(firLine, "FLIGHTS OVER KANNI WHALE PLEASE") Then
secLine = objFile.ReadLine
If InStr(secLine, "J174.RIFLE..ACK..DIRECT") Then
'I'm going to change the below once I piece it all together.
WScript.Echo "works"
Else WScript.Echo "Not found"
'cut, paste and modify all my "IF" statements below
End If
End If
loop

Creating a table in "MSWord" document out of a text in a .txt file

In the following file "E:\my_folder\my_future_table.txt" I have this text:
# animal country
1 rabbit Germany
2 wolf France
3 koala USA
(please note that all the words in each line of that text are separated by tabs)
What VBS script do I need to use in order to create a "Word" file (.doc) with a table created on the basis of that text? (In this example, the table should have 3 columns and 4 rows)
Something like this with a healthy degree of credit to the Scripting Guy
The vbs reads the test file (pls change your path), and then splits it by line break into an array ArrVar
Each line in this array is split further by VbTab into a second array, ArrVar2
The vbs creates a word table equal in size to the length of ArrVar and width of ArrVar2
Each item is written to the table cell by cell, row by row
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Add()
Set objRange = objDoc.Range()
strFilePath = "c:\temp\my_future_table.txt"
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.opentextfile(strFilePath)
strAll = objTF.readall
arrVar = Split(strAll, vbNewLine)
numcols = UBound(Split(arrVar(0), vbTab)) + 1
objDoc.Tables.Add objRange, UBound(arrVar) - LBound(arrVar) + 1, numcols
Set objTable = objDoc.Tables(1)
For lngrow = LBound(arrVar) To UBound(arrVar)
arrVar2 = Split(arrVar(lngrow), vbTab)
For lngcol = LBound(arrVar2) To UBound(arrVar2)
objTable.Cell(lngrow + 1, lngcol + 1).Range.Text = arrVar2(lngcol)
Next
Next
objTF.Close
set objFSO = Nothing
objTable.AutoFormat (9)
objWord.Visible = True

Resources