Getting error "Array is Fixed or Locked" when splitting string - arrays

I have this issue with my vbscript file. It actually read data from first file and use it to compare with values in second file. If there is a match necessary things are done. This code is working fine for the first value from the first file. But for second input error appears as that this array is fixed or temporary locked. I searched in internet and found the issue is with the fixed size of array and can be solved by redim function. I don't know it is the correct solution or not. Here is the complete code. Thanks in advance.
set fs = CreateObject("Scripting.FileSystemObject")
set shell = CreateObject("Wscript.Shell")
set file =fs.OpenTextFile("C:\wamp\www\order.csv",1,false)'Read from orders.csv (Current Orders)
set output =fs.OpenTextFile("C:\wamp\www\completed-orders.csv",8)'Output file. All Completed Order's Number are placed here
Set tempfile = fs.CreateTextFile("C:\wamp\www\temp-order.csv",true) 'Create temporary text files to store the line numbers to be deleted
set p=fs.OpenTextFile("C:\wamp\www\current.csv",1,false)'Read the path to the current Stock Data File
path=p.ReadLine
p.close()
path = Trim(path)
set n=fs.OpenTextFile(path,1,false)'Read the data from it and check for name match and then whether current price is >= order price.
line=0
'format of line in order.csv written from php 'fwrite($file,$company."||".$price."||".$oid."||".$type."||".$email
do while file.AtEndOfStream<>true
lin=file.ReadLine
Wscript.Echo line
Wscript.Echo lin
if lin="" Then
noerr=false
else
noerr=true
end if
Wscript.Echo noerr & " error variable"
if noerr Then
temp=Split(lin,"||") 'Read the first order (id,price)
i=0
for each data in temp
If i=0 Then
namestock=data
ElseIf i=1 Then
target=CDbl(data)
ElseIf i=2 Then
orderid=data
ElseIf i=3 Then
buysell=data
ElseIf i=4 Then
transtype=data
ElseIf i=5 Then
emailto=data
ElseIf i=6 Then 'Bharti Airtel ||300.90||100000004||BUY||INTR||email#hotmail.com||5||1506.45585 format of lin
nos=CInt(data)
Else
totalprice=CDbl(data)
End If
i=i+1
next
do while n.AtEndOfStream <>true 'Compare against current data
stock=Split(n.ReadLIne,"||")
j=0
for each name in stock
If j=0 Then
If StrComp(namestock,name,1)=0 Then
Wscript.Echo namestock & " name matched"
check = true
j=j+1
Else
Exit For
End If
Else If j=1 Then
If buysell="BUY" Then
If CDbl(name) <=target Then
tempfile.WriteLine(line) 'Add the line to temporary file if condition is satisfied.
output.WriteLine(orderid) 'Write orderno to complete-orders
shell.run "send.vbs 1 "& emailto &" "& target &" "& buysell &" "& transtype &" "& nos &" "&totalprice &" "& namestock & " Order Completed"
Wscript.Echo "sended"
End If
ElseIf buysell="SELL" Then
If CDbl(name) >=target Then
tempfile.WriteLine(line) 'Add the line to temporary file if condition is satisfied.
output.WriteLine(orderid) 'Write orderno to complete-orders
shell.run "send.vbs 1 "& emailto &" "& target &" "& buysell &" "& transtype &" "& nos &" "&totalprice &" "& namestock & " Order Completed"
End If
End If
Exit Do
End If
End If
next
loop
end if
line=line+1
loop
n.close()
tempfile.close()
file.close()
output.close()
This is part of my miniproject. A simple stock market system. This piece of code is to be used for order is to be accepted or not by the system. It does the intended works fine for the first line, but for second line from the order.csv, but it will not work due to the error occurring on the stock variable.

Your whole approach is flawed. You try to read all lines from n for each line from file. That won't work without opening (and closing) n each time.
You should edit your question to disclose your real world problem/what you want to achieve with some sample data. Then it may be possible to give you useful advice.

Related

Repeat loop with if conditions for first and last time

I have a script that I made that works fine but I have to make some very minor edits to the output. Instead I'd like to just do it correctly.
on run {input, parameters}
set the formatted to {}
set listContents to get the clipboard
set delimitedList to paragraphs of listContents
repeat with listitem in delimitedList
set myVar to "#\"" & listitem & "\"," & (ASCII character 10)
copy myVar to the end of formatted
end repeat
display dialog formatted as string
return formatted as string
end run
I'd like prepend the first item slightly differently and append the last a little different.
I tried the following but the script is not right.
repeat with n from 1 to count of delimitedList
-- not sure how to if/else n == 0 or delimitedList.count
end repeat
There is a more efficient way, text item delimiters. It can insert the comma and the linefeed character between the list items
on run {input, parameters}
set the formatted to {}
set listContents to get the clipboard
set delimitedList to paragraphs of listContents
repeat with listitem in delimitedList
copy "#" & quote & listitem & quote to the end of formatted
end repeat
set {saveTID, text item delimiters} to {text item delimiters, {"," & linefeed}}
set formatted to formatted as text
set text item delimiters to saveTID
display dialog formatted
return formatted
end run
Side note: ASCII character 10 is deprecated since macOS 10.5 Leopard, there is linefeed, tab (9), return (13), space (32) and quote (34).
In addition to an index or range, the various items of a list can also be accessed by using location parameters such as first, last, beginning, etc (note that AppleScript lists start at index 1). To deal with the first and last items separately, you can do something like:
on run {input, parameters} -- example
set formatted to {}
set delimitedList to paragraphs of (the clipboard)
if delimitedList is not {} then
if (count delimitedList) > 2 then repeat with anItem in items 2 thru -2 of delimitedList
set the end of formatted to "#" & quote & anItem & quote
end repeat
set the beginning of formatted to "#" & quote & "First: " & first item of delimitedList & quote -- or whatever
if rest of delimitedList is not {} then set the end of formatted to "#" & quote & "Last: " & last item of delimitedList & quote -- or whatever
set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "," & linefeed}
set {formatted, AppleScript's text item delimiters} to {formatted as text, tempTID}
end if
display dialog formatted as text
return formatted as text
end run

Applescript / Photoshop - Some sort of "wait if busy" command?

I have some code that constantly checks for any open documents and adds a comment in finder when it is closed.
I'm having an issue though that if anything like the "Do you wish to save?" or "Loading..." comes up, it's some weird limbo between 0 and 1 and can't seem to count properly. It then crashes with the generic "General Photoshop Error" message.
Is there some sort of "Pause/Wait if busy" command, or some other way around this?
repeat
tell application "Adobe Photoshop CS6"
set D1 to count documents
local mainDocList
set mainDocList to {}
if ((count mainDocList) ≠ D1) then
log "Main Ran"
if (D1 > 0) then
set c to 1
repeat while (c ≤ D1)
set mainDocList to mainDocList & (file path of document c)
set c to c + 1
end repeat
end if
end if
delay 3
set D1 to count documents
local currentDocList
set currentDocList to {}
if ((count currentDocList) ≠ D1) then
log "Current Ran"
if (D1 > 0) then
set c to 1
repeat while (c ≤ D1)
set currentDocList to currentDocList & (file path of document c)
set c to c + 1
end repeat
end if
end if
end tell
local closedList, a
set closedList to {}
if ((count mainDocList) ≠ (count currentDocList)) then
repeat with a in mainDocList
set a to contents of a
if {a} is not in currentDocList then set end of closedList to a
end repeat
end if
log "∆: " & (count closedList)
log "- - - - -"
if ((count closedList) > 0 and ((count mainDocList) > (count currentDocList))) then
tell application "Finder"
set c to 1
repeat while (c ≤ (count closedList))
tell application "System Events"
set modDate to modification date of (item c of closedList)
end tell
set theDate to current date
set Y to text -2 thru -1 of ("00" & (year of theDate))
set M to text -2 thru -1 of ("00" & ((month of theDate) as integer))
set D to text -2 thru -1 of ("00" & (day of theDate))
set spartanDate to Y & M & D
set theTime to (time string of theDate)
set theTime to text -11 thru -7 of ("00" & (time string of theDate))
set currentComments to (get comment of (item c of closedList))
set comment of (item c of closedList) to currentComments & (" | USER-" & spartanDate & "-" & theTime)
log "******************COMMENTED"
set c to c + 1
end repeat
end tell
end if
end repeat
Well, it would help if you indicated WHERE in the code it seems to hang. In my opinion, any Applescript code that is dealing with files should be liberally sprinkled with try...on error...end blocks.
try
...
on error errMsg
display dialog "ERROR: " & errMsg
end try
Once you've identified where the problem is triggered, and see the error message, you and we would be better able to fix the problem.
Also, if you suspect that a modal dialog popping up is part of the problem, encircle that code with a timeout block:
with timeout of 60000 seconds
... could that could otherwise timeout
end
Every script statement is subject to a timeout, and bad things usually happen if you do not either catch the timeout in a TRY block or think ahead and guard against it with a TIMEOUT block.

Displaying full array in Liberty BASIC

Going through a tutorial but I cannot figure out how to do this. It wants me to have the program display all 10 names previously entered after the quit sub. I've experimented with some stuff but cannot figure out how to do this.
'ARRAYS.BAS
'List handling with arrays
dim names$(10) 'set up our array to contain 10 items
[askForName] 'ask for a name
input "Please give me your name ?"; yourName$
if yourName$ = "" then print "No name entered." : goto [quit]
index = 0
[insertLoop]
'check to see if index points to an unused item in the array
if names$(index) = "" then names$(index) = yourName$ : goto [nameAdded]
index = index + 1 'add 1 to index
if index < 10 then [insertLoop] 'loop back until we have counted to 10
'There weren't any available slots, inform user
print "All ten name slots already used!"
goto [quit]
[nameAdded] 'Notify the name add was successful
print yourName$; " has been added to the list."
goto [askForName]
[quit]
end
Insert this code between [quit] and end:
for I = 0 TO 10
print names$(I)
next I
That'll work ;)

Remove lines in text files that have "." Batch File

I have a text file that looks like this.
/var/www/xxx/html/TEST/VIDEOS/video3.mp4
/var/www/xxx/html/TEST/video_folder_1/cideo.mp4
/var/www/xxx/TEST/video_folder_1/sadasd
/var/www/xxx/html/TEST/video_folder_2/asdsadasdasdsadsadsadsadas
/var/www/xxx/html/TEST/video_folder_2/cideo2.mp4
/var/www/xxx/html/TEST/video_folder_2/sadsada
I would like it to look like this:
/var/www/xxx/TEST/video_folder_1/sadasd
/var/www/xxx/html/TEST/video_folder_2/asdsadasdasdsadsadsadsadas
/var/www/xxx/html/TEST/video_folder_2/sadsada
The idea would be to remove any line that have an extension. I.E mp4 in this case.
So I guess it would look for 4 character in at the end of the line and see if it has a "."
If it does, remove the line.
In batch you should be able to do this in many ways:
findstr /V /L "." theFile.txt
As Aacini suggests, which checks if the line contains a . and works fine when tested.
If you want to user regular expression
findstr /V /R "\....$" theFile.txt
Which does exactly what you asked for by checking if a line ends with a .***
Lastly what I would recommend is using this:
findstr /V /R "\.[a-z0-9]*$" theFile.txt
which checks if the line ends with any sort of extension, thus including possible 4-letter extensions.
I have tested each of these and they all work fine.
I really don't know why Serenity insists you use VBscript which is no doubt a great language but for a simple thing like this batch is so much more simpler.
This is a vbs regex replace program. Far more powerful than FindStr. It works globably so you can target line endings.
This is help from a similar line based, not global, program of mine. The point is to show sample RegEx expressions.
To extract all section headers, ie, lines without an equal sign
filter filter iv "=" < "%systemroot%\win.ini"
To extract all section headers starting with a lower case letter
filter filter n "\[[a-z].+" < "%systemroot%\win.ini"
This shows the caret escaping an opening bracket for CMD.EXE and the backslash escaping the opening bracket for the RegEx engine
filter filter n "\^(" < "%systemroot%\win.ini"
This shows searching for a quote character
filter filter n "\x22" < "%systemroot%\win.ini"
Use $1, $2, $..., $n to specify sub matches in the replace string
filter replace i "=" "No equal sign" < "%systemroot%\win.ini"
This searches for text within square brackets and replaces the line with cat followed by the text within brackets
Filter replace i "^\[^(.*^)\]" "cat$1" < %windir%\win.ini
This searches for any text and prints from the 11th character to the end of the line.
Filter replace i "^.{10}^(.*^)$" "$1" < %windir%\win.ini
This searches a CSV file and prints the second and fourth field
Filter replace i "^.+,^(.+^),.+,^(.+^)$" "$1,$2" < csv.txt
The script.
On Error Resume Next
Set ShellApp = CreateObject("Shell.Application")
ReportErrors "Creating Shell.App"
set WshShell = WScript.CreateObject("WScript.Shell")
ReportErrors "Creating Wscript.Shell"
Set objArgs = WScript.Arguments
ReportErrors "Creating Wscript.Arg"
Set regEx = New RegExp
ReportErrors "Creating RegEx"
Set fso = CreateObject("Scripting.FileSystemObject")
ReportErrors "Creating FSO"
If objArgs.Count = 0 then
wscript.echo "No parameters", 16, "Serenity's ReplaceRegExp"
ReportErrors "Help"
ElseIf objArgs.Count = 1 then
wscript.echo "Only one parameter", 16, "Serenity's ReplaceRegExp"
ReportErrors "Help"
ElseIf objArgs.Count = 2 then
Set srcfile = fso.GetFile(objArgs(0))
ReportErrors "srcFile"
If err.number = 0 then Set TS = srcFile.OpenAsTextStream(1, 0)
If err.number <> 0 then
wscript.echo err.description & " " & srcFile.path, 48, "Serenity's Search"
err.clear
else
ReportErrors "TS" & " " & srcFile.path
Src=ts.readall
If err.number = 62 then
err.clear
else
ReportErrors "ReadTS" & " " & srcFile.path
regEx.Pattern = objArgs(1)
regEx.IgnoreCase = True
regEx.Global = True
If regEx.Test(Src) = True then
wscript.echo "Found in " & srcfile.path, 64, "Serenity's Search"
End If
End If
End If
ReportErrors "Check OK" & " " & srcFile.path
Elseif objArgs.count = 3 then
Set srcfile = fso.GetFile(objArgs(0))
ReportErrors "srcFile"
If err.number = 0 then Set TS = srcFile.OpenAsTextStream(1, 0)
If err.number <> 0 then
wscript.echo err.description & " " & srcFile.path, 48, "Serenity's Search"
err.clear
else
ReportErrors "TS" & " " & srcFile.path
Src=ts.readall
If err.number = 62 then
err.clear
else
ReportErrors "ReadTS" & " " & srcFile.path
regEx.Pattern = objArgs(1)
regEx.IgnoreCase = True
regEx.Global = True
NewSrc= regEx.Replace(Src, objArgs(2))
If NewSrc<>Src then
wscript.echo "Replacement made in " & srcfile.path, 64, "Serenity's Search"
TS.close
Set TS = srcFile.OpenAsTextStream(2, 0)
ts.write newsrc
ReportErrors "Writing file"
End If
End If
End If
ReportErrors "Check OK" & " " & srcFile.path
Else
wscript.echo "Too many parameters", 16, "Serenity's ReplaceRegExp"
ReportErrors "Help"
ReportErrors "All Others"
End If
Sub ReportErrors(strModuleName)
If err.number<>0 then wscript.echo "An unexpected error occurred. This dialog provides details on the error." & vbCRLF & vbCRLF & "Error Details " & vbCRLF & vbCRLF & "Script Name" & vbTab & Wscript.ScriptFullName & vbCRLF & "Module" & vbtab & vbTab & strModuleName & vbCRLF & "Error Number" & vbTab & err.number & vbCRLF & "Description" & vbTab & err.description, vbCritical + vbOKOnly, "Something unexpected"
Err.clear
End Sub
RegEx Reference
Regular Expressions Reference
From the Windows Vista SDK, VBScript Language Reference © Microsoft Corp 2006
Character Description
\ Marks the next character as either a special character or a literal. For example, "n" matches the character "n". "\n" matches a newline character. The sequence "\\" matches "\" and "\(" matches "(".
^ Matches the beginning of input.
$ Matches the end of input.
* Matches the preceding character zero or more times. For example, "zo*" matches either "z" or "zoo".
+ Matches the preceding character one or more times. For example, "zo+" matches "zoo" but not "z".
? Matches the preceding character zero or one time. For example, "a?ve?" matches the "ve" in "never".
. Matches any single character except a newline character.
(pattern) Matches pattern and remembers the match. The matched substring can be retrieved from the resulting Matches collection, using Item [0]...[n]. To match parentheses characters ( ), use "\(" or "\)".
x|y Matches either x or y. For example, "z|wood" matches "z" or "wood". "(z|w)oo" matches "zoo" or "wood".
{n} n is a nonnegative integer. Matches exactly n times. For example, "o{2}" does not match the "o" in "Bob," but matches the first two o's in "foooood".
{n,} n is a nonnegative integer. Matches at least n times. For example, "o{2,}" does not match the "o" in "Bob" and matches all the o's in "foooood." "o{1,}" is equivalent to "o+". "o{0,}" is equivalent to "o*".
{ n , m } m and n are nonnegative integers. Matches at least n and at most m times. For example, "o{1,3}" matches the first three o's in "fooooood." "o{0,1}" is equivalent to "o?".
[ xyz ] A character set. Matches any one of the enclosed characters. For example, "[abc]" matches the "a" in "plain".
[^ xyz ] A negative character set. Matches any character not enclosed. For example, "[^abc]" matches the "p" in "plain".
[ a-z ] A range of characters. Matches any character in the specified range. For example, "[a-z]" matches any lowercase alphabetic character in the range "a" through "z".
[^ m-z ] A negative range characters. Matches any character not in the specified range. For example, "[m-z]" matches any character not in the range "m" through "z".
\b Matches a word boundary, that is, the position between a word and a space. For example, "er\b" matches the "er" in "never" but not the "er" in "verb".
\B Matches a non-word boundary. "ea*r\B" matches the "ear" in "never early".
\d Matches a digit character. Equivalent to [0-9].
\D Matches a non-digit character. Equivalent to [^0-9].
\f Matches a form-feed character.
\n Matches a newline character.
\r Matches a carriage return character.
\s Matches any white space including space, tab, form-feed, etc. Equivalent to "[ \f\n\r\t\v]".
\S Matches any nonwhite space character. Equivalent to "[^ \f\n\r\t\v]".
\t Matches a tab character.
\v Matches a vertical tab character.
\w Matches any word character including underscore. Equivalent to "[A-Za-z0-9_]".
\W Matches any non-word character. Equivalent to "[^A-Za-z0-9_]".
\num Matches num, where num is a positive integer. A reference back to remembered matches. For example, "(.)\1" matches two consecutive identical characters.
\ n Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. For example, "\11" and "\011" both match a tab character. "\0011" is the equivalent of "\001" & "1". Octal escape values must not exceed 256. If they do, only the first two digits comprise the expression. Allows ASCII codes to be used in regular expressions.
\xn Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be exactly two digits long. For example, "\x41" matches "A". "\x041" is equivalent to "\x04" & "1". Allows ASCII codes to be used in regular expressions.
Go to top of page
If you want to eliminate lines with "." from the output created in your previous question, then a much simpler solution is to insert a test in that code:
#echo off
setlocal EnableDelayedExpansion
(for /F "delims=" %%a in (test.txt) do (
set "line=%%a"
if "!line:~0,1!" equ "/" (
set "header=%%a"
) else (
if "!line:.=!" equ "!line!" echo !header:~0,-1!/%%a
)
)) > testnew.txt

Deleting last line of every text file in drive using Batch or VBScript

I need to create either a batch file or vbscript to delete every last line of a text file in a drive. So, a text file
Hello.
Blah blah blah.
Goodbye.
will become
Hello.
Blah blah blah.
TIA.
PS: I'm creating projects to learn batch and vbscript. My ultimate goal is to learn the scripting language. So, I would like to request for explanation alongside the code so that I can understand. Thanks.
Here's a commented solution for you.
Be warned that doing something like this is potentially a dangerous operation to run across an entire drive - VBScript does not handle Unicode files very well, so if you run this against a whole drive, be sure you know what you are changing.
I have set it only to work against a sub-directoy (C:\Somedirectory) in my example you would need to change that to where ever you want to go. Also, whilst I have tested this, I can't guarantee it's not going to misbehave: Consider this - if you ran this multiple times, you would end up with a whole bunch of 0 byte (empty) files eventually!
WARNING: This will permanently delete data that you cannot get back. I would not recommend using this blindly against an entire drive!!
DISCLAIMER: Use at your own risk.
Option Explicit
' Option Explicit forces all variables to be declared good way to sanity check some times.
Const ForWriting = 2
Const ForReading = 1
' Set our Contsants for manipulating files read/writes
' Dimension our variables (in our case, the main loop only has one.. objFSO
Dim objFSO
' Load up the FileSystemObject for our file operations later
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Call our routine to recursively scan folders for txt files.
Call Recurse("C:\SomeFolder\")
Sub Recurse(strFolderPath)
' This routine recursively searches a folder/drive for txt files
Dim objFolder, objFile, objSubFolder
' Load up the Folder path into objFolder
Set objFolder = objFSO.GetFolder(strFolderPath)
On Error Resume Next
' Instruct VBScript to continue if an error occurs.
For Each objFile In objFolder.Files
If Err Then
' If there's an error accessing the file, likely to be access denied for files in use, etc. Let's ignore and continue
Err.clear
Else
If (InStr(objFile.Name, ".") > 0) Then
'If the file's extension is "txt", chomp it! (This calls the Function FileChomp with the path\filename.txt)
If LCase(objFso.GetExtensionName(objFile.name)) = "txt" Then FileChomp (objFile.Path )
End If
End If
Next
For Each objSubFolder In objFolder.SubFolders
Call Recurse(objSubFolder.Path)
Next
End Sub
Function FileChomp (FCName)
' This function chomps the last line of a text file.
Dim strdata, objFile, arrlines, strlines, filesize
' This section gets our text file size.
filesize = 0
Set objFile = objFSO.GetFile(FCName)
FileSize = objFile.Size
Set objFile = Nothing
'This resets our array for lines, incase there's something in there already from last time?
ReDim arrlines(0)
' Open the file for reading
Set objFile = objFSO.OpenTextFile(FCName, ForReading)
' If the filesize we retrieved earlier is greater than 0, go do this
If FileSize > 0 then
strLines = 0
Do While objFile.atendofstream = false
' This loop reads in the file we're going to chomp and stores it line by line into arrLines as an array
ReDim Preserve arrLines(strLines)
arrLines(strlines) = objFile.Readline
strLines = strLines + 1
Loop
' This sets the file as we are going to write back to it (less the last line) - BE WARNED This may not work for unicode text files.
Set objFile = objFSO.OpenTextFile(FCName, ForWriting)
For strLines = 0 to UBound(arrLines) - 1
' This For Loop writes out the file (less the last line)
objFile.WriteLine arrLines(strLines)
Next
End If
objFile.Close
End Function
What have you tried?
Start by looking at these commands.
Commands
for,
for /f,
for /r
Use the /? argument for help.
Batch References
SS64,
DosTips,
Rob van der Woude,
Computer Hope
Technet
Bookmark These!
This script for removing last N line, works for you:
count the total line
set Line = Line - N , remain just processing lines number
#echo OFF
setlocal EnableDelayedExpansion
set LINES=0
for /f "delims==" %%I in (input.txt) do (
set /a LINES=LINES+1
)
echo Total Lines : %LINES%
echo.
:: n = 1 , last 1 line will be ignored
set /a LINES=LINES-1
call:PrintFirstNLine > output.txt
goto EOF
:PrintFirstNLine
set cur=0
for /f "delims==" %%I in (input.txt) do (
echo %%I
::echo !cur! : %%I
set /a cur=cur+1
if "!cur!"=="%LINES%" goto EOF
)
:EOF
exit /b
Here call:PrintFirstNLine > output.txt will give the output in an external file name as output.txt .

Resources