Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Wot? Another infinite loop? 3

Status
Not open for further replies.

JPJeffery

Technical User
May 26, 2006
600
GB
There is a way of quitting a DO WHILE loop by checking for the end of the array isn't there? I'm sure I read it somewhere but I'm blowed if I can find it.

Anyway, here's the sub-routine that loops until the end of time if it doesn't find the string it's searching for (strFile is a .cvs file containing a list of usernames):

Code:
Sub FindTheUser(strFile,strUserName) 
    text = strFile.ReadAll 
    strFile.Close '
    arrText = split(text,vbCrLf) 
    eod = 0 
    Do While eod = 0 
    For Each elem In arrText 
'        wscript.echo "elem = " & elem & vbCRLF & _ 
'                     "strUserName = " & strUserName 
        Result = InStr(lcase(elem),lcase(strUserName)) 
        if Result > 0 then 
            eod = 1 
        End if 
'        wscript.echo "Result = " & Result & vbCrLf & _ 
'                     "eod = " & eod 
    Next 
    Loop 
End Sub

Now, I've got two odd behaviours here, firstly, the loop fails to immediately quit out after finding the string - it goes through the whole list even if it found the string on the first line - but worse is that if the string isn't found it just starts all over again.

So, what am I missing? And is my code here hopelessly complicated anyway? And how do I make it check for an exact match instead of partial matches (so that BloggsJ doesn't match against BloggsJ2, although I'm not concerned about case sensitivity)?

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
A starting point:
Sub FindTheUser(strFile, strUserName)
text = strFile.ReadAll
strFile.Close
arrText = Split(text, vbCrLf)
eod = 0
For Each elem In arrText
Result = InStr(LCase(elem), LCase(strUserName))
If Result > 0 Then
eod = 1
Exit For
End If
Next
If eod = 0 Then MsgBox "NOT found !"
End Sub

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 
Tried it, got the same result! :-(

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
>... got the same result!
Same result? I wouldn't think so. At least PHV's is sound. If the user is found, nothing would happens, no message no nothing... How do you plan to make the sub communicate with the external world? appart from the unconcious global scope variable changed as a side effect?
 
I agree that PHVs code looks to be sound but yep, I'm getting the same result.

If the username is found the script still cycles through the rest of the list.

If the username isn't found it loops round again indefinitely.

Observe some example output (and yes, I know I've got some blank lines in the input file, which is a puzzle but not one that I'm particularly bothered about):

[tt]FINDTHEUSER INITIALISED WITH strUserName = won

elem = woeckels
strUserName = won
Result = 0
eod = 0

elem =
strUserName = won
Result = 0
eod = 0

elem = wongj2
strUserName = won
Result = 10
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

elem = woodg
strUserName = won
Result = 0
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

elem = woodt
strUserName = won
Result = 0
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

elem = woolcott
strUserName = won
Result = 0
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

elem = wulkanw
strUserName = won
Result = 0
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

elem = yiannisa
strUserName = won
Result = 0
eod = 1

elem =
strUserName = won
Result = 0
eod = 1

Finished[/tt]

To answer your other question, I don't know yet. I've not got that far but yes I could make the Sub a Function instead...

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
You need to show the code you're using now so we can debug that.

Lee
 
Well, I tell ya, I've no idea WHAT I did wrong but it's now working (with PHV's code).

Yet all I did was edit my original (again) with PHV's code in place of my original sub and save it as a different name and it behaves as expected - as I did the first time around!

So, basically, I'm a shmuck.

But still, thanks everyone!

I'm still left with the problem of making a complete match though. So, if I'm searching for SmithJ it must only match SmithJ but not something like SmithJ2...

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
If I understand you correctly, you can use this
Code:
Result = InStr(LCase(elem), LCase(strUserName)) [b][red]Or InStr(LCase(strUserName), LCase(elem))[/red][/b]

Lee
 
Not sure, I'm just leaving for home so won't be able to test this until tomorrow but to clarify, if, like most companies, we have a collection of users with similar names (e.g. the surname of Smith) then I need to do a character by character full match although I'm NOT concerned about case sensitivity.

So, searching for 'smiths' will match against 'SmithS' but NOT against 'SmithsonP'.

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
I don't think that is conceptually correct. Have to do it properly with regexp.
[tt]
Sub FindTheUser(strFile, strUserName)
on error resume next 'to guard against .readall error
text = strFile.ReadAll
on error goto 0
strFile.Close '[blue]note: it is annoying doing it inside the sub - bad tracing headache[/blue]
arrText = Split(text, vbCrLf)
eod = 0
'add this before the loop
[green]dim rx
set rx=new regexp
with rx
.pattern="\b" & strUserName & "\b" 'suppose strUserName well-tempered
.ignorecase=true
end with[/green]
For Each elem In arrText
'replace this line
'Result = InStr(LCase(elem), LCase(strUserName))
[green]Result = rx.test(elem)[/green]
'If Result > 0 Then
[green]if Result then[/green]
eod = 1
Exit For
End If
Next
If eod = 0 Then MsgBox "NOT found !"
End Sub
[/tt]
 
If you want an exact match, then my code is incorrect. Your latest description sounds like you want an exact match, which would be:
Code:
  If LCase(elem) = LCase(strUserName) Then
    eod = 1
    Exit For
   End If

Your original example was coded to search for a substring inside another string, not what you've referred to in some of your responses.

Lee
 
This hand. This smack on head"

Of course. It's funny how an earlier requirement can lead one completely down the wrong path.

Originally the names in the input file were in the format DOMAINNAME\UserName hence I felt I needed to use InStr to search for the username part.

I've since decided I don't need to include the DomainName so can use the FAR easier method you've described, Lee.

Of course if I was compelled to keep in the domain name I could just split the text using the backslash as the delimiter...

Sometimes the easiest solution is the easiest to oversee.

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
> the input file were in the format DOMAINNAME\UserName
It contains illegal character as a file name, so I can safely suppose that you have never created any of those, not even arriving at the stage of get it and read it!
 
DOMAINNAME\UserName" was the format of each line of text within the filename. The filename itself is something like %temp%\usernames.txt.

:)

JJ
[small][purple]Variables won't. Constants aren't[/purple][/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top