VBscript using variable from text file error - vbscript

Good day all.
What I am trying to do is ready a value from a text file and using it as a variable within the code. The text file holds a path directory, that i want to use to create another folder in with a datestamp.
This is what it looks like:
Set FSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Set objTextFile = FSO.OpenTextFile("C:\MyFolder\Settings.txt", ForReading)
For i = 0 to 0
objTextFile.ReadLine
Next
New_Path = objTextFile.ReadLine
FSO.CreateFolder New_Path & Year(Date) & Right("0" & Month(Date),2) & Right("0" & Day(Date),2)
objTextFile.Close
I get an error that says Bad file name or number
But when I use Wscript.Echo New_Path it shows me exactly the right path that I need. Why is it not using it if it comes back correctly?
The first line has comments so I read the second line that contains the path that looks like this: "C:\NewFolder\"

In the text file i took away the "" between the Directory and it worked

Related

Too many iterations in loop

This script collects all files in a folder and renames the files by appending the number of lines to the file name. All files are .txt files. The method (since fso.MoveFile and fso.DeleteFile are too particular, generating permissions errors) is to
create the text files,
then create a collection of the files in the folder,
then copy each file into the same folder with a new name, and
finally to delete the original file that was copied.
The script works ok, unless there are no empty text files in the collection. What happens is, the collection gets rebuilt with the new files and the script once again renames the files. I know I can prevent this by checking each file for the existence of certain repeating character strings, but I'd like to know what's happening? Why does the script rebuild the file collection and run through them again renaming each one? This continues on until I kill the process.
Another interesting factoid is, if I happen to trap an empty text file, my message is displayed and the script stops there, but has still reprocessed the first file in the collection a second time. Note that the empty file just happens to be the last one in the collection, but the first filed is once again processed.
So, by design a created text file named 'ab0.txt' gets renamed to 'ab0-15.txt' since it has 15 lines of text in it. What happens is this newly renamed file looks like 'ab0-15-15-15-15-15-15-15-15-15-15.txt'
Questions: What's going on? And is there a better and more efficient way to accomplish this objective?
Here's the code pertinent to the issue:
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFolder = fso.GetFolder(strSaveTo)
Set colFiles = oFolder.Files
' Call Sub to copy and rename
ChangeFileName colFiles
MsgBox("File renaming complete.")
' Exit code
Sub ChangeFileName(collectionSet)
Const ForReading = 1
Dim oFile
For Each oFile In collectionSet
Set LineCnt = fso.OpenTextFile(oFile, ForReading)
If oFile.Size = 0 then
'if this msg is not included, weird things happen
MsgBox("The file named " & oFile & _
" is empty.You may want to verify and manually delete it.")
'[I had some code in here to delete the empty file, but nothing worked]
Else
Do While LineCnt.AtEndOfStream <> True
LineCnt.SkipLine
Loop
lineVar = lineCnt.Line-1
strNewFile = strSaveTo & Left(oFile.name, Len(oFile.name)-4) & _
"-" & lineVar & ".txt"
fso.CopyFile oFile, strNewFile
LineCnt.Close
fso.DeleteFile oFile, True
End If
Next
End Sub
I've heard anecdotal evidence that the Files collection is "live", meaning that newly created files will be added to the collection and iterated over, but I can't find any documentation that says one way or the other. In any case, it's probably a good idea to copy the File objects in the collection to an array first before processing them:
Dim oFile
Dim fileArray()
Dim i
ReDim fileArray(collectionSet - 1)
i = 0
For Each oFile in collectionSet
Set fileArray(i) = oFile
i = i + 1
Next
For Each oFile In fileArray
' Count lines and rename
Next
It seems that collectionSet is the collection of files in the folder that you are trying to modify. The problem is that with each pass through the for-each loop you are adding files to this folder, some of which are fed back into the loop. What you need to do is the find a way to take a snapshot of the folder before you try to iterate over it. The way to do this would be to replace the folder collectionSet by a collection of strings which are the names of the files before you iterate over it, and modify your code to open the files by their name (instead of via a file object). That way the collection won't be expanding while you iterate over it.
You should create your vars in the scope they are used (e.g. your
file/folder objects are used in the sub.
Always explicit(ly) declare your vars.
You don't need to copy the file and rename it then do the delete.
Just rename it with the FileObject.Name property.
Here is an example:
Option Explicit 'always declare your vars!
Dim strFolder: strFolder = "c:\temp\Rename Test"
Dim strExtension: strExtension = "txt"
' Call Sub to rename the files in the folder
ChangeFileName strFolder, strExtension
Sub ChangeFileName(strFolder, strExtension)
Const ForReading = 1
Dim FSO: set FSO = CreateObject("Scripting.FileSystemObject")
Dim objFolder: set objFolder = FSO.GetFolder(strFolder)
Dim colFiles: set colFiles = objFolder.Files
Dim objFile
Dim intCount
Dim strFileName
Dim objTextStream
For Each objFile In colFiles
msgbox "File: " & objfile.path & vbcrlf & FSO.GetExtensionName(objFile.path)
if UCase(FSO.GetExtensionName(objFile.Path)) = UCase(strExtension) and _
objFile.Size > 0 then
'set LineCnt = FSO.OpenTextFile(objFile, ForReading)
set objTextStream = objFile.OpenAsTextStream(ForReading,-2)
intCount = 0
strFileName = objFile.Name
Do While objTextStream.AtEndOfStream <> True
intCount = intCount + 1
objTextStream.ReadLine
Loop
objTextStream.Close
objFile.Name = FSO.GetBaseName(objFile.Path) & "-" & _
intCount & "." & FSO.GetExtensionName(objFile.Path)
end if
Next
End Sub

Use a VBS to edit ini for users %appdata% folder

I have script that edits the a line in the ini file, which sits on users %Appdata% folder i.e C:\Users\<>\AppData\Roaming.
The current script which I have only edits a file pointing to proper file location, but I would like to have script which can edit the file on every logged on users folder
I have a vbs below which look like this , but I am not able to use a variable %appdata% to edit the file under folder when the user is logged on
Const ForReading = 1
Const ForWriting = 2
Dim strUserName, CurrDir
Set objFSO = CreateObject("Scripting.FileSystemObject")
strUserName = InputBox("Please enter your email address below in the following format:" & Vbnewline & "firstname_lastname#test.com" & Vbnewline & Vbnewline & "HINT - If you are unsure, you can look up your name", "Add internet email address")
If strUserName = "" Then
Wscript.Quit
End If
Set objTextFile = objFSO.OpenTextFile("H:\appdata\Linkpoint360\LinkPointConfig.ini", ForReading)
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
intLineFinder = InStr(strNextLine, "UserEMailAddress")
If intLineFinder <> 0 Then
strNextLine = "UserEMailAddress=" & strUserName
End If
strNewFile = strNewFile & strNextLine & VbCrLf
Loop
objTextFile.Close
Set objTextFile = objFSO.OpenTextFile("H:\appdata\Linkpoint360\LinkPointConfig.ini", ForWriting)
objTextFile.WriteLine strNewFile
objTextFile.Close
I am not scripting expert, but I have tried best to find a suitable solution over the internet and I have no luck
If someone can please edit this vbs and give a proper script, that will be really appreciated
# Ansgar Wiechers, can't post the image as i don't have 10 repuataion, but here is what I get in pop box:
Script: << Location of file >>
Line: 13
Char: 1
Error: Path not found
Code: 800A004C
Scource: Microsoft VBScript runtime error
the error I get when is use %appdata% in my script.
from the above code I have just edited file location "H:\appdata...." to "%appdata%....."
FileSystemObject methods don't expand environment variables. You need to do it yourself, e.g. like this:
...
Set sh = CreateObject("WScript.Shell")
config = sh.ExpandEnvironmentStrings("%APPDATA%\Linkpoint360\LinkPointConfig.ini")
Set objTextFile = objFSO.OpenTextFile(config, ForReading)
...
You can't reliabily do this in vbscript.
However you can make a safe assumption (disregarding network and profile updating issues that I don't think will matter) that profiles are under Users folder and each user will have the same relative path to AppFolder.
The normal way of handling this problem type is to use logon scripts.

How to Copy a file that was read from a list

Hello guys I have an issue or issues with my code above
I'm trying to get "sExtension" to be search in a different folder other that the one I'm using to save my script since this script will be use as a Startup Script on many computers
(It works only if I run the script in the same folder "sExtension", "ExtAssign.txt" and sComputername are otherwise it wont find the path)
This is what it should do
Read a file called "ExtAssign.txt" (There is a full list of computer names in that file) and if it find the computer name on that file then it should copy a file with the with the extension number assigned to that computer name from a file server to "C:\" Drive
For this example I'm trying to do this locally, If I can make it then I'll try it from my File Server
Set objFSO = CreateObject("Scripting.FileSystemObject")
set oFso = CreateObject("Scripting.FileSystemObject")
Set objFS = CreateObject("Scripting.FileSystemObject")
Set fso = CreateObject("Scripting.FileSystemObject")
set oShell = WScript.CreateObject("WScript.Shell")
set oShellEnv = oShell.Environment("Process")
Set folder = Fso.GetFolder("C:\Users\XXXXX\Desktop\Test\Extensions\")
Set wshshell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set ObjEnv = WshShell.Environment("Process")
Set objFso = WScript.CreateObject("Scripting.FileSystemObject")
Scomputername = ObjEnv("COMPUTERNAME")
Set objFSO = CreateObject("Scripting.FileSystemObject")
set objWShell = wScript.createObject("WScript.Shell")
Dim strFile
'File to scan
strFile = "C:\Users\XXXXX\Desktop\Test\Extensions\Extassign\ExtAssign.txt"
Dim strPattern
'Look for computer name in file
strPattern = scomputername
Set objFso = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
Dim strLine
'Read each line and store it in strLine
strLine = objFile.ReadLine
'If the line matches the computer name, save the line to ExtArray
If InStr(strLine,strPattern)>0 Then
Dim ExtArray
'Split the line and separate the extension
ExtArray = Split(strLine,"|", -1, 1)
Dim sExtension
'Save the extension to sExtension
sExtension=ExtArray(1)
End If
Loop
'If the sExtension is empty, computer was not found, send message and terminate script.
If sExtension="" Then
WScript.Echo "ERROR: Computer "& scomputername &" not found in Extension Assignment List, so no extension has been set. Avaya will not be launched. Please contact your IT department for assistance."
Else
'If the sExtension contains a number, Copy that file to C:\ and rename it to Config.xml
fso.CopyFile "C:\Users\XXXXX\Desktop\Test\Extensions\ "& sExtension &"", "C:\Config.xml", True
End If
at the end it if it finds the file sExtension it will rename it to Config.xml but it wont do it unless I run the script in the same folder sExtension and sComputername.
I get File not found error
Thank you in advance and Happy new year!
The culprit is most likely this line:
fso.CopyFile "C:\Users\XXXXX\Desktop\Test\Extensions\ "& sExtension &"", "C:\Config.xml", True
There is a trailing space after the last backslash in the path, so you're creating a path
C:\Users\XXXXX\Desktop\Test\Extensions\ 12345
^
when you actually want a path
C:\Users\XXXXX\Desktop\Test\Extensions\12345
On a more general note: why are you creating 7(!) FileSystemObject instances (replacing one of them three times on top of that)? And 3(!) WScript.Shell instances? You don't even use most of them, not to mention that you don't need the Shell object in the first place. You only use it for determining the computer name, which could be done just fine using the WScript.Network object (that you don't use at all).
Also, please don't ever use comments like this:
'Read each line and store it in strLine
strLine = objFile.ReadLine
It's quite obvious that you read each line and assign it to the variable strLine. Comments shouldn't rephrase what you're doing (the code already does that, at least when you're using speaking variable and function names), but why you're doing it, i.e. what the purpose of a particular code section is.
Your code could be reduced to something as simple as this:
Set fso = CreateObject("Scripting.FileSystemObject")
Set net = CreateObject("WScript.Network")
computername = net.ComputerName
foldername = "C:\Users\XXXXX\Desktop\Test\Extensions"
filename = fso.BuildPath(foldername, "Extassign\ExtAssign.txt")
Set f = fso.OpenTextFile(filename)
Do Until f.AtEndOfStream
line = f.ReadLine
If InStr(line, computername) > 0 Then
arr = Split(line, "|", -1, 1)
If UBound(arr) >= 1 Then extension = arr(1)
End If
Loop
f.Close
If IsEmpty(extension) Then
WScript.Echo "ERROR: Computer "& computername &" not found in ..."
Else
fso.CopyFile fso.BuildPath(foldername, extension), "C:\Config.xml", True
End If

Windows script host error 800A0046

I'm receiving the following error when I run my program:
Script: C: My Folder\Tracking Macro.vbs
Line: 70
Char: 1
Error: Permission denied
Code: 800A0046
Source: Microsoft VBScript runtime error
Here is the code.
' Set constants for reading, writing, and appending files
Const ForReading = 1, ForWriting = 2, ForAppending = 8
' Sets up the object variables.
Dim objExcel, objFSO, objTextFile, objCSVFile
' Sets up the string variables.
Dim strTextFile, strHeadLine, strTextLine, strCSVFile
' Sets up the all the string variables for the program.
Dim Desktop, todaysDate, usageDate, myDay, myMonth, myYear
'This creates the required Objects
Set objExcel = CreateObject("Excel.application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
Desktop = WshShell.ExpandEnvironmentStrings("%USERPROFILE%") & "\" & "Desktop"
' Set date for date stamp in file name and sheet name
todaysDate = Date()
myMonth = Month(todaysDate)
If Len(myMonth)=1 Then myMonth="0" & myMonth
myDay = Day(todaysDate)
If Len(myDay)=1 Then myDay="0" & myDay
myYear = Right(Year(todaysDate), 2)
usageDate = myMonth & myDay & myYear
' Set up the origin and destination files
strTextFile = (Desktop & "\MacroTracker.txt")
strCSVFile = "C: My Folder\TrackingTesting" & usageDate & ".csv"
strHeadLine = "Macro Name,User ID,Ran At,Contracted Rate,BHVN,Set Number,Provider TIN,Billed Charge,Service Code"
Set objTextFile = objFSO.OpenTextFile(strTextFile)
' Read the entire origin file
Do Until objTextFile.AtEndOfStream
strTextLine = objTextFile.ReadLine
Loop
If (objFSO.FileExists(strCSVFile)) Then
' Create object for appending current TXT file to CSV file
Set objCSVFile = objFSO.OpenTextFile(strCSVFile, ForAppending, True)
' Write an append line of data to the CSV file
objCSVFile.WriteLine strTextLine
Else
' Create CSV file to write to with today's date
Set objCSVFile = objFSO.CreateTextFile(strCSVFile, True)
' Create object for appending current TXT file to CSV file
Set objCSVFile = objFSO.OpenTextFile(strCSVFile, ForAppending, True)
' Write initial header for the CSV file
objCSVFile.WriteLine strHeadLine
' Write an append line of data to the CSV file
objCSVFile.WriteLine strTextLine
End If
' Wait for file to be written to
Wscript.Sleep 600
' Delete origin file to prevent user tampering
objFSO.DeleteFile(strTextFile)
Line 70 is the very last line where I'm deleting the text file. According to every help site I've seen, this is EXACTLY how it should be typed. I checked the permissions of the file...I have full control, so I should be able to delete it. It's only meant to be a temp file, not something that stores info for long periods of time.
I've checked Microsoft and all other help sites for the error code and have not found any solutions that can help me. I'm hoping someone may have ran into a similar instance and found a resolution.
Your file is still open. You need to add this:
objTextFile.Close
somewhere before you try to delete it. I would put it right after you're done using the file.

VBS replace and write

Start of that I'm not that good with VBS but trying to learn.
Right now I have some difficulties with writing replace to a text file.
What I want to do is to search for the text "VGML", when this is found check on same row if there is a "STML" if so, this should replaced with " " to not mess up the positions in the file. And finally, if "VGML" is found without the "STML", the "VGML" should be removed.
I got so far when using echo I can see that the code does what I want, but writing to file mostly get me a empty file where the code removed everything.
Could anyone put me in the correct direction?
Here is the code:
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Script\RemoveSTML\testFiles\test.txt", ForReading)
strEMTY = " "
strSTML = "STML"
strVGML = "VGML"
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If InStr(strLine,strVGML)>0 Then
If Instr(strLine,strSTML)>0 Then
strLine = Replace(strLine, strSTML, strEMTY)
wscript.Echo strLine
Else
strLine = Replace(strLine, strVGML, strEMTY)
wscript.Echo strLine
End If
End If
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile("C:\Script\RemoveSTML\testFiles\test.txt", ForWriting)
objFile.Write strLine
objFile.Close
Wscript.Echo "done"
Thanks for your help! For giving me a kick in the correct direction!
In the loop, you read each line of the file and you write it into the variable strLine.
After that, you replace "SMTL"/"VGML", but after that, you're doing nothing with the content of strLine - you just replace it with the next line from the source file in the next loop.
Only at the end, you write strLine to the file once - but in that moment, strLine contains only the last line from the source file.
Solution: you can either write into the destination file inside the Do...Loop (but I'm not familiar with VBScript, so I don't know if/how to do this) or you can use a second string variable where you append strLine inside the loop but after the replacing...like this:
strFinal = strFinal & strLine
At the end, you write strFinal to the file, not strLine.

Resources