i was making resource for my programming class well its actually very basic scripting and i found this site and look through it there was realy many useful stuff about scripting but the thing i was searching for wasnt on the list or i wasnt using right keyword
anyway my question is
My teacher ask me to write a Vbs to Print Multiplication Table and i made researches and this is where i am right now;
dim sum, arraynum(), arrayline1, count, arraynum2(), arrayline2, arraynum3(), arrayline3, arraynum4(), arrayline4, arraynum5(), arrayline5
count=1
sum=1
arrayline1=1
for count=1 to 5
redim preserve arraynum(arrayline1)
redim preserve arraynum2(arrayline2)
redim preserve arraynum3(arrayline3)
redim preserve arraynum4(arrayline4)
redim preserve arraynum5(arrayline5)
arraynum(arrayline1)=sum
arraynum2(arrayline2)=sum*2
arrayline2=arrayline2+1
arraynum3(arrayline3)=sum*3
arrayline3=arrayline3+1
arraynum4(arrayline4)=sum*4
arrayline4=arrayline3+1
arraynum5(arrayline5)=sum*5
arrayline5=arrayline5+1
sum=sum+1
arrayline1=arrayline1+1
next
wscript.echo join(arraynum) & vbcrlf & join(arraynum2) & vbcrlf & join(arraynum3) & vbcrlf & join
(arraynum4) & vbcrlf & join(arraynum5)
' Its printing like;
' 1 2 3 4 5
' 2 4 6 8 10
' 3 6 8 12 15
' 4 8 12 16 20
' 5 10 15 20 25
as you can see they are not in a straight line and i wasnt able to do this with an input i mean take an input and show multiplication table for that i hope i made myself clear enough and if its not too much to ask how can i put a border between them or is it possible.
The trick is to apply leftpadding to your values that you are printing: Count the number of characters that a value contains, substract them from a fixed amount and add the same amount of spaces to the value.
This is an example that will replace and leftpad the vbTab character. If you join your arrays with a vbTab instead of the default space, you can use such a function.
Because this is a homework assignment, I added also some code that recursively get the multiples for a number, starting with 0. Just to trigger some curiosity. I would not recommend to just copy paste it, it does not comply to your requirement: "start from 1".
dim multiple
' Get the numbers 0 to 5
for each multiple in split(getMultiples(1,5), vbTab)
' print the multiplication table for each of this numbers
wscript.echo trim(TabToLpad(getMultiples(multiple, 5), 10))
next
' Does the calculation and returns a Tab delimited string of all multiples
function getMultiples(nr, amount)
getMultiples = 0
' As long as the amount is larger then 0, get the next multiple
if amount > getMultiples then getMultiples = getMultiples(nr, amount-1) & vbTab & (nr * amount)
End function
' Pads each value in a tab delimited string with the nrPadChars spaces. Returns a string.
function tabToLpad(str, nrPadChars)
dim part
for each part in split(str, vbTab)
tabToLpad = tabToLpad & string(nrPadChars - len(part), " ") & part
next
End Function
Related
I am trying to add a random set of numbers to the end of a string. I'm still learning the basics of VBS but this has really tricked me and I can't seem to find anything online.
I've tried:
string2 = "hello" + (Rnd() * Len(VALID_TEXT)) + 1
And:
x = rnd*10
string2 = "hello" + x
What am I doing wrong?
All random number generators rely on an underlying algorithm, usually fed by what’s called a seed number. You can use the Randomize statement to create a new seed number to ensure your random numbers don’t follow a predictable pattern.
To get the random numbers, using rnd alone is not sufficient as you will keep on getting the same random number again and again. You have to use randomize to achieve the task as shown below:
Dim strTest:strTest = "Hello"
Dim intNoOfDigitsToAppend:intNoOfDigitsToAppend = 5
Randomize
Msgbox "String before appending: " & strTest
strTest = fn_appendRandomNumbers(strTest,intNoOfDigitsToAppend)
Msgbox "String before appending: " & strTest
function fn_appendRandomNumbers(strToAppend,intNoOfRandomDigits)
Dim i
for i=1 to intNoOfRandomDigits
strToAppend= strToAppend & int(rnd*10) 'rnd gives a random number between 0 and 1, something like 0.8765341. Then, we multiply it by 10 so that the number comes in the range of 0 to 9. In this case, it becomes 8.765341. After that, we use the int method to truncate the decimal part so that we are only left with the Integer part. In this case, 765341 is truncated and we are left with only the integer 8
next
fn_appendRandomNumbers = strToAppend
end function
Reference 1
Reference 2
& is the string concatenation character. + is an old compatability concat character and will error if you mix text and numbers. Use + for maths only.
I'm tyring to make program which takes a sentence as input and then splits the different words in it. Now it compares the words and if a word repeats then gives a message match otherwise it gives no match. But on executing the same no MsgBox is displayed.
This is the script that I have written:
Dim sent
Dim i
Dim j
Dim k
sent = "Its a good day but every day is a good day"
words = Array(Split(sent))
For i = LBound(words) To UBound(words)-1
For j = LBound(words)+1 To UBound(words)
k = StrComp(words(i), words(j))
If k=0 Then
MsgBox ("Match")
Else
MsgBox ("No Match")
End If
Next
Next
The For loop will never run because the UBound(words) will return 0.
This is because the Split() function returns an Array so there is no need for the extra Array() call which ends up giving you a single element Array containing another Array.
The solution is to change
words = Array(Split(sent))
to
words = Split(sent)
That will fix your initial problem, but there are other issues with the code you will need to address before it works correctly.
VBScript's tool for classifying/counting tokens of types/recognizing is the Dictionary.
Demo:
Option Explicit
Dim a : a = Split("Its a good day but every day is a good day")
Dim d : Set d = CreateObject("Scripting.Dictionary")
Dim w
For Each w In a
d(w) = d(w) + 1
If 1 < d(w) Then
WScript.Echo "more than one " & w & " - could 'Exit For'"
End If
Next
For Each w In d.Keys()
WScript.Echo w, d(w)
Next
(look ma, no nested loops!)
output:
cscript 42004404.vbs
more than one day - could 'Exit For'
more than one a - could 'Exit For'
more than one good - could 'Exit For'
more than one day - could 'Exit For'
Its 1
a 2
good 2
day 3
but 1
every 1
is 1
I am concatenation hlinks obtained from word do
data = data & "," & Vbcr & hlnk.Address & ":" & hlnk.TextToDisplay
Here ',' is separator.
Now I get every time data starting with ',' (obviously)
I then use
data = Right(data,Len(data)-1)
But I doubted my method of string concatenation.
Am I using Right method of string concatenation in first place?
I have seen ASP classic - how do I join an array of strings / join / implode do not work but I don't think that is my case. I am not joining array but creating one.
The canonical way to avoid leading (or trailing) list separators is to collect the items you want to concatenate in an array, then join that array. That's probably why #Filburt considered your question a (borderline) duplicate. If you don't know the number of items beforehand you'd dynamically resize the array:
ReDim a(-1)
For Each hlnk In ...
ReDim Preserve a(UBound(a)+1)
a(UBound(a)) = hlnk.Address & ":" & hlnk.TextToDisplay
Next
Once the array is filled you simply join the elements:
data = Join(a, "," & vbCr)
Otherwise you need to either handle the first (or last) element differently from the rest:
If IsEmpty(data) Then
data = hlnk.Address & ":" & hlnk.TextToDisplay
Else
data = data & "," & vbCr & hlnk.Address & ":" & hlnk.TextToDisplay
End If
or remove the leading (trailing) separator after you finished constructing the string:
data = Mid(data, 3)
A VBScript is in use to shorten the system path by replacing entries with the 8.3 versions since it gets cluttered with how much software is installed on our builds. I'm currently adding the ability to remove duplicates, but it's not working correctly.
Here is the relevant portion of code:
original = "apple;orange;apple;lemon\banana;lemon\banana"
shortArray=Split(original, ";")
shortened = shortArray(1) & ";"
For n=2 to Ubound(shortArray)
'If the shortArray element is not in in the shortened string, add it
If NOT (InStr(1, shortened, shortArray(n), 1)) THEN
shortened = shortened & ";" & shortArray(n)
ELSE
'If it already exists in the string, ignore the element
shortened=shortened
End If
Next
(Normally "original" is the system path, I'm just using fruit names to test...)
The output should be something like
apple;orange;lemon\banana
The issue is entries with punctuation, such as lemon\banana, seem to be skipped(?). I've tested it with other punctuation marks, still skips over it. Which is an issue, seeing how the system path has punctuation in every entry.
I know the basic structure works, since there are only one of each entry without punctuation. However, the real output is something like
apple;orange;lemon\banana;lemon\banana
I thought maybe it was just a character escape issue. But no. It still will not do anything with entries containing punctuation.
Is there something I am doing wrong, or is this just a "feature" of VBScript?
Thanks in advance.
This code:
original = "apple;orange;apple;lemon\banana;lemon\banana"
shortArray = Split(original, ";")
shortened = shortArray(0) ' array indices start with 0; & ";" not here
For n=1 to Ubound(shortArray)
'If the shortArray element is not in in the shortened string, add it
'i.e. If InStr() returns *number* 0; Not applied to a number will negate bitwise
' If 0 = InStr(1, shortened, shortArray(n), 1) THEN
If Not CBool(InStr(1, shortened, shortArray(n), 1)) THEN ' if you insist on Not
WScript.Echo "A", shortArray(n), shortened, InStr(1, shortened, shortArray(n), vbTextCompare)
shortened = shortened & ";" & shortArray(n)
End If
Next
WScript.Echo 0, original
WScript.Echo 1, shortened
WScript.Echo 2, Join(unique(shortArray), ";")
Function unique(a)
Dim d : Set d = CreateObject("Scripting.Dictionary")
Dim e
For Each e In a
d(e) = Empty
Next
unique = d.Keys()
End Function
output:
0 apple;orange;apple;lemon\banana;lemon\banana
1 apple;orange;lemon\banana
2 apple;orange;lemon\banana
demonstrates/explains your errors (indices, Not) and shows how to use the proper tool for uniqueness (dictionary).
I am trying to split an RTF file into lines (in my code) and I am not quite getting it right, mostly because I am not really grokking the entirety of the RTF format. It seems that lines can be split by \par or \pard or \par\pard or any number of fun combinations.
I am looking for a piece of code that splits the file into lines in any language really.
You could try the specification (1.9.1) (see External Links on the Wikipedia page - which also has a couple of links to examples or modules in several programming languages).
That would most likely give you an idea of the line insertion "words", so you can split the file into lines using a well-defined set of rules rather than taking a guess at it.
Have you come across O'Reilly's RTF Pocket Guide, by Sean M. Burke ?
On page 13, it says
Here are some rules of thumb for putting linebreaks in RTF:
Put a newline before every \pard or \ (commands that are explained in the "Paragraphs" section.
Put a newline before and after the RTF font-table, stylesheet, and other similar constructs (like the color table, decribed later).
You can put a newline after every Nth space, {, or }. (Alternatively: put a newline after every space, {, or } that's after the 60th column.)
Or were you thinking of extracting the plaintext as lines, and doing it whatever the language of the plaintext?
I coded up a quick and dirty routine and it seems to work for pretty much anything I've been able to throw at it. It's in VB6, but easily translatable into anything else.
Private Function ParseRTFIntoLines(ByVal strSource As String) As Collection
Dim colReturn As Collection
Dim lngPosStart As Long
Dim strLine As String
Dim sSplitters(1 To 4) As String
Dim nIndex As Long
' return collection of lines '
' The lines can be split by the following '
' "\par" '
' "\par " '
' "\par\pard " '
' Add these splitters in order so that we do not miss '
' any possible split combos, for instance, "\par\pard" is added before "\par" '
' because if we look for "\par" first, we will miss "\par\pard" '
sSplitters(1) = "\par \pard"
sSplitters(2) = "\par\pard"
sSplitters(3) = "\par "
sSplitters(4) = "\par"
Set colReturn = New Collection
' We have to find each variation '
' We will look for \par and then evaluate which type of separator is there '
Do
lngPosStart = InStr(1, strSource, "\par", vbTextCompare)
If lngPosStart > 0 Then
strLine = Left$(strSource, lngPosStart - 1)
For nIndex = 1 To 4
If StrComp(sSplitters(nIndex), Mid$(strSource, lngPosStart, Len(sSplitters(nIndex))), vbTextCompare) = 0 Then
' remove the 1st line from strSource '
strSource = Mid$(strSource, lngPosStart + Len(sSplitters(nIndex)))
' add to collection '
colReturn.Add strLine
' get out of here '
Exit For
End If
Next
End If
Loop While lngPosStart > 0
' check to see whether there is a last line '
If Len(strSource) > 0 Then colReturn.Add strSource
Set ParseRTFIntoLines = colReturn
End Function