I\'m a VBScript novice, writing a script that will be parsing large input file(s) and will likely take several minutes run time to complete processing. I need a way to aler
In such cases I'd like to use WshShell.Popup method to provide information about the current progress.
Here an example:
Dim WshShell, i
Set WshShell = CreateObject("WScript.Shell")
For i = 1 To 500
'Do Something
If i Mod 100 = 0 Then 'inform for every 100 process
WshShell.Popup i & " items processed", 1, "Progress" ' show message box for a second and close
End If
Next
I found a better way to display progress while running a long script in VbScript.
I found some code in this url took it and modified it to make it look better. The problem with the other code is we can't change the size of the progress bar. I fixed it in my code. Just change m_ProgressBar.width and height. Also change margin in the html body. That's it.
Class ProgressBar
Private m_PercentComplete
Private m_CurrentStep
Private m_ProgressBar
Private m_Title
Private m_Text
Private m_Top
Private m_Left
'Initialize defaults
Private Sub Class_Initialize()
m_PercentComplete = 1
m_CurrentStep = 0
m_Title = "Progress"
m_Text = ""
m_Top = 100
m_Left = 150
End Sub
Public Function SetTitle(pTitle)
m_Title = pTitle
if IsObject(m_ProgressBar) then
m_ProgressBar.Document.title = m_PercentComplete & "% Complete : " & m_Title
m_ProgressBar.Document.GetElementById("pc").InnerHtml = m_PercentComplete & "% Complete : " & m_Title
end if
End Function
Public Function SetText(pText)
m_Text = pText
if IsObject(m_ProgressBar) then m_ProgressBar.Document.GetElementById("text").InnerHtml = m_Text
End Function
Public Function SetTop(pTop)
m_Top = pTop
End Function
Public Function SetLeft(pLeft)
m_Left = pLeft
End Function
Public Function GetTop()
GetTop = m_ProgressBar.top
End Function
Public Function GetLeft()
GetLeft = m_ProgressBar.left
End Function
Public Function Update(percentComplete)
If percentComplete > 100 Then
m_PercentComplete = 100
elseif percentComplete < 1 then
m_PercentComplete = 1
else
m_PercentComplete = percentComplete
end if
UpdateProgressBar()
End Function
Public Function Show()
Set m_ProgressBar = CreateObject("InternetExplorer.Application")
'in code, the colon acts as a line feed
m_ProgressBar.navigate2 "about:blank" : m_ProgressBar.width = 800 : m_ProgressBar.height = 380 : m_ProgressBar.toolbar = false : m_ProgressBar.menubar = false : m_ProgressBar.statusbar = false : m_ProgressBar.visible = True : m_ProgressBar.Resizable = False : m_ProgressBar.top = m_Top : m_ProgressBar.left = m_Left
m_ProgressBar.document.write "<body Scroll=no style='margin:100px;'><div style='text-align:center;padding:15px;'><span name='pc' id='pc'>0% Complete</span></div>"
m_ProgressBar.document.write "<div id='statusbar' name='statusbar' style='border:1px solid blue;line-height:22px;height:30px;color:blue;'>" _
& "<table width='100%' height='100%'><tr><td id='progress' style='width:1%' bgcolor='#0000FF'></td><td></td></tr></table></div>"
m_ProgressBar.document.write "<div style='text-align:center;padding:15px;'><span id='text' name='text'></span></div>"
End Function
Public Function Close()
m_ProgressBar.quit
End Function
Private Function UpdateProgressBar()
if m_CurrentStep <> m_PercentComplete then
If m_PercentComplete = 100 Then
m_ProgressBar.Document.GetElementById("statusbar").InnerHtml = "<table width='100%' height='100%'><tr><td bgcolor='#0000FF'></td></tr></table>"
else
m_ProgressBar.Document.GetElementById("progress").style.width = m_PercentComplete & "%"
end if
m_ProgressBar.Document.title = m_PercentComplete & "% Complete : " & m_Title
m_ProgressBar.Document.GetElementById("pc").InnerHtml = m_PercentComplete & "% Complete : " & m_Title
m_ProgressBar.Document.GetElementById("text").InnerHtml = m_Text
m_CurrentStep = m_PercentComplete
end if
End Function
End Class
Then you add the below code to display the progress bar and update the current status of progress.
'Declare progressbar and percentage complete
Dim pb
Dim percentComplete
'Setup the initial progress bar
Set pb = New ProgressBar
percentComplete = 0
pb.SetTitle("Step 1 of 5")
pb.SetText("Copying bin/Debug Folder")
pb.SetTop(150) ' These are optional
pb.SetLeft(300) ' These are optional
pb.Show()
'Loop to update the percent complete of the progress bar
'Just add the pb.Update in your code to update the bar
'Text can be updated as well by pb.SetText
Do While percentComplete <= 100
wscript.sleep 500
pb.Update(percentComplete)
percentComplete = percentComplete + 10
Loop
wscript.sleep 2000
pb.Close()
'This shows how you can use the code for multiple steps
Set pb = New ProgressBar
percentComplete = 0
pb.SetTitle("Step 2 of 5")
pb.SetText("Copying bin/Release Folder")
pb.Show()
pb.Update(percentComplete)
Do While percentComplete <= 100
wscript.sleep 500
pb.Update(percentComplete)
percentComplete = percentComplete + 10
Loop
msgbox "Completed", vbSystemModal
pb.Close()
wscript.quit
If you're running your script in a console window (via cscript.exe) then you can display a faux progress bar directly in the window/output like this:
First declare the following functions in your VBS file:
Function printi(txt)
WScript.StdOut.Write txt
End Function
Function printr(txt)
back(Len(txt))
printi txt
End Function
Function back(n)
Dim i
For i = 1 To n
printi chr(08)
Next
End Function
Function percent(x, y, d)
percent = FormatNumber((x / y) * 100, d) & "%"
End Function
Function progress(x, y)
Dim intLen, strPer, intPer, intProg, intCont
intLen = 22
strPer = percent(x, y, 1)
intPer = FormatNumber(Replace(strPer, "%", ""), 0)
intProg = intLen * (intPer / 100)
intCont = intLen - intProg
printr String(intProg, ChrW(9608)) & String(intCont, ChrW(9618)) & " " & strPer
End Function
Function ForceConsole()
Set oWSH = CreateObject("WScript.Shell")
vbsInterpreter = "cscript.exe"
If InStr(LCase(WScript.FullName), vbsInterpreter) = 0 Then
oWSH.Run vbsInterpreter & " //NoLogo " & Chr(34) & WScript.ScriptFullName & Chr(34)
WScript.Quit
End If
End Function
Then at the top of your script use the following example:
ForceConsole()
For i = 1 To 100
progress(i, 100)
Next
Don't use popup messages for this unless you want to annoy the heck out of your users. Wrap your code in an HTA that displays a progress indicator like the one in this page, e.g.:
<html>
<head>
<title>Sample</title>
<hta:application
applicationname="Sample"
scroll="no"
singleinstance="yes"
windowstate="normal"
>
<script language="vbscript">
Sub Window_onLoad
'your code here
End Sub
</script>
<style type="text/css">
* {
font-size: 1px;
margin: 1px;
}
div {
position: absolute;
left: 40%;
top: 50%;
}
marquee {
border: 1px solid;
height: 15px;
width: 200px;
}
marquee span {
height: 11px;
width: 8px;
background: Highlight;
float: left;
}
.handle-0 { filter: alpha(opacity=20); -moz-opacity: 0.20; }
.handle-1 { filter: alpha(opacity=40); -moz-opacity: 0.40; }
.handle-2 { filter: alpha(opacity=60); -moz-opacity: 0.6; }
.handle-3 { filter: alpha(opacity=80); -moz-opacity: 0.8; }
.handle-4 { filter: alpha(opacity=100); -moz-opacity: 1; }
</style>
</head>
<body>
<div>
<marquee direction="right" scrollamount="8" scrolldelay="100">
<span class="handle-0"></span>
<span class="handle-1"></span>
<span class="handle-2"></span>
<span class="handle-3"></span>
<span class="handle-4"></span>
</marquee>
</div>
</body>
</html>
If you want to provide some more dynamic information, you could for instance add a paragraph like this to the body:
</div>
<p id="sline" style="visibility:hidden;">Processed
<span id="rcount"></span> Records.</p>
</body>
</html>
and update it every 1000 records:
...
If numRows Mod 1000 = 0 Then
If sline.style.visibility = "hidden" Then sline.style.visibility = "visible"
rcount.innerText = numRows
End If
...