When I run the following snippet, and enter an acceptable value, I get the desired result.
do while len(strselect) = 0 'or strselect<>"1" or strselect<>"2" or strselect<>"3"
strselect = inputbox ("Please select:" &vbcrlf&vbcrlf&_
"1. Add an entry" &vbcrlf&vbcrlf&_
"2. Remove an entry" &vbcrlf&vbcrlf&_
"3. Search for an entry" &vbcrlf, "Contact Book")
if isempty(strselect) then
wscript.quit()
elseif strselect="1" then
wscript.echo "You chose 1"
elseif strselect="2" then
wscript.echo "You chose 2"
elseif strselect="3" then
wscript.echo "You chose 3"
end if
loop
However if I try constrain the validation process further (by including the remark in the do while conditions), and run the snippet again, I get the corresponding if condition triggered, but the do loop continues, instead of exiting.
I've tried using isnumeric and cstr on the do loop strselect conditions, with no joy... What am I missing to get the darn thing to exit the loop?
You have a problem with the logic in the condition
condition 1 condition 2 condition 3 condition 4
v----------------v v------------v v------------v v............v
do while len(strselect) = 0 or strselect<>"1" or strselect<>"2" or strselect<>"3"
Depending on value inside strselect, you have
value c1 c2 c3 c4
len=0 <>"1" <>"2" <>"3" c1 or c2 or c3 or c4
-------------------------------------- --------------------
empty true true true true true
1 false false true true true
2 false true false true true
3 false true true false true
other false true true true true
In each line you have at least one condition evaluated as true, and as you are concatenating the conditions with Or operators (evaluate to true if at least one of the values is true), the full condition is evaluated as true and the code keeps looping
You only need to change the condition
Do While strselect<>"1" And strselect<>"2" And strselect<>"3"
Do While Not (strselect="1" Or strselect="2" Or strselect="3")
....
Related
I need this to effect only the current record within the continuous form.
On the Offender Type I select "offender 1" and the code correctly sets all four fields not enabled.
However when I go record 2, in the Offender Type, I select "Offender 2" the code incorrectly sets all four fields to enabled of every record of the continuous form not just the fields for record 2.
Combo box Name: Offender_Type
Selections for Offender_Type: Offender 1; Offender 2; Offender 3
Private Sub Offender_Type_AfterUpdate()
If Me.Offender_Type.Value = "offender 1 " Then
Me.Field1.Enabled = False
Me.Field2.Enabled = False
Me.Field3.Enabled = False
Me.field4.Enabled = False
ElseIf Me.Offender_Type.Value <> "offender 1" Then
Me.Field1.Enabled = True
Me.Field2.Enabled = True
Me.Field3.Enabled = True
Me.field4.Enabled = True
Else
End If
End Sub
I am not an expert on VBA, all I know is based on browsing internet, but some simple codes work for me well.
I am switching pictures based on P52 value, that works perfectly, but then I want to swich different pictures based on cell value P117 and that part of the code does not really work for me. What am I missing in the code?
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
If Target.Address <> "$P$52" Then Exit Sub
With ActiveSheet
Select Case Target.Value
Case "Horizontal - feet"
.Pictures("B3A").Visible = True
.Pictures("V1A").Visible = False
.Pictures("V1AF").Visible = False
Case "Vertical - simple"
.Pictures("B3A").Visible = False
.Pictures("V1A").Visible = True
.Pictures("V1AF").Visible = False
Case "Vertical - lantern"
.Pictures("B3A").Visible = False
.Pictures("V1A").Visible = False
.Pictures("V1AF").Visible = True
End Select
End With
If Target.Address <> "$P$117" Then Exit Sub
With ActiveSheet
Select Case Target.Value
Case "Right"
.Pictures("3P1").Visible = True
.Pictures("3P1M").Visible = False
Case "Left"
.Pictures("3P1").Visible = False
.Pictures("3P1M").Visible = True
End Select
End With
End Sub
Thanks for your help.
Think through the logic of your if statements causing you to exit the sub.
If the cell is P117, you will hit the first if statement which causes you to exit the sub immediately. So you will never get to your second check.
Embed the logic for each of your operations in if statements like I show here and you will be able to "do something if the cell range is P52 or P117" a bit more appropriately.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
'only do the following operation if your cell address is P52 - don't exit out
'of your entire code if it's not
If Target.Address = "$P$52" Then
With ActiveSheet
Select Case Target.Value
Case "Horizontal - feet"
.Pictures("B3A").Visible = True
.Pictures("V1A").Visible = False
.Pictures("V1AF").Visible = False
Case "Vertical - simple"
.Pictures("B3A").Visible = False
.Pictures("V1A").Visible = True
.Pictures("V1AF").Visible = False
Case "Vertical - lantern"
.Pictures("B3A").Visible = False
.Pictures("V1A").Visible = False
.Pictures("V1AF").Visible = True
End Select
End With
End If
'you skip to down here if it is NOT P52, which then lets you check again to
'see if it's P117
If Target.Address = "$P$117" Then
With ActiveSheet
Select Case Target.Value
Case "Right"
.Pictures("3P1").Visible = True
.Pictures("3P1M").Visible = False
Case "Left"
.Pictures("3P1").Visible = False
.Pictures("3P1M").Visible = True
End Select
End With
End If
End Sub
If you are going to have a lot of checks like this, you may want to create a Select case statement for Target.Address too. It's hard to say which is better for you given what you've asked here.
Okay, I've searched and searched and am hoping someone here can help me out.
I've been trying to get a VBScript program to open a word document, search for a specific char and replace it with a Addin field (i.e. { SEQ # } )
Here's what I have thus far:
1 Const wdReplaceAll = 2
2 Set objWord = CreateObject("Word.Application")
3 objWord.Visible = True
4
5 Set ObjDoc = objWord.Documents.Open("C:\path\to\.doc")
6 Set objSelection = objWord.Selection
7
8 objSelection.Find.Text = "#"
9 objSelection.Find.Forward = True
10 objSelection.MatchWholeWord = True
11
12 objSelection.Find.Replace.Text = "replacement text"
13
14 objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
This code works for "Find/Replace" but does not work for fields.
Much help would be awesome! Thanks!
Replace replaces text, but you want to add a field. That's an entirely different thing. I'd suggest to Find the search text (leaves the text selected) and then Add the field (replaces the selected text):
With objWord.Selection
.Find.Text = "#"
.Find.Forward = True
.Find.MatchWholeWord = True
.Find.Execute
.Fields.Add .Range, -1, "SEQ #", True
End With
To replace all occurrences of the search string you have to create a loop that keeps executing .Find.Execute until no further occurrences are found. The return value of the Execute method indicates if another match was found.
With objWord.Selection
.Find.Text = "#"
.Find.Forward = True
.Find.MatchWholeWord = True
Do
found = .Find.Execute
If found Then .Fields.Add .Range, -1, "SEQ #", True
Loop While found
End With
Make sure your cursor is positioned at the beginning of the document before you run the above code, otherwise you might miss occurrences of your search text.
I'm working with a bit of old VB6 code that goes thus...
Dim STATUS As Integer
STATUS = -1
If (Not STATUS) Then
' do something
Else
' do something else
End If
so I was, naturally, wondering which branch of this code is executed. So does anyone know what the numeric values of True and False are in VB6?
True is stored as -1 and false as 0. Any non-zero value is considered as true.
To see why it is so please check - http://www.vbforums.com/showthread.php?t=405047
In VB 6, True has a numeric value of -1. False has a numeric value of 0.
The reason for this is because the Boolean data type is stored as a 16-bit signed integer. Therefore,-1 evaluates to 16 1s in binary (1111111111111111). False is 16 0s (0000000000000000). This produces the relationship that has held throughout the evolution of BASIC: True = Not False.
Not really an answer, but just poking about, I typed this into the immediate window, with these results:
For x = -5 To 5 : ? x, CBool(x), ( x = True ), ( x = False ) : Next x
-5 True False False
-4 True False False
-3 True False False
-2 True False False
-1 True True False
0 False False True
1 True False False
2 True False False
3 True False False
4 True False False
5 True False False
(I tested more values, but only -1 and 0 had anything "interesting" going on. The rest were all True/False/False.) So, empirically, I'd say that the comparison is being done arithmetically unless you cast with CBool. Why? I can't really say...
I would extremely appreciate if anyone can suggest a solution for this.
I have a simple function that is is expecting for a browser to be opened on a page containing a web list that each value of it represents an account. When an account is selected it's products (if any) are displayed.
The functions goal is to retrieve an index of an account with products (the first to be found) or -1 if there are none.
The problem, which I can't figure out what is causing it, is that the function will return the correct result when I'm debugging it - meaning running the code step by step using F10, but will return a wrong result if I'll run regularly (F5). This behavior is consistent and the function retrieves the same result each time for each type of runs, meaning it's not a bug that just makes the function return a random answer.
This is the function:
' #return: a random account index with products if one exists
' otherwise returns -1
Public Function getRandomAccountWithProducts()
On Error Resume Next
Set Page1 = Browser("micclass:=browser").Page("micclass:=Page")
Set br = Browser("micclass:=Browser")
originalURL = br.GetROProperty("URL")
br.Navigate Environment.Value("SOME URL") & "REST OF URL"
br.Sync
Page1.WebList("name:=accountId").Select "#1"
br.Sync
' Display only products
Page1.WebRadioGroup("name:=name0").Click
Page1.WebList("name:=name1").Select "Display None"
Page1.WebList("name:=name2").Select "Display None"
Page1.WebButton("value:=Apply","visible:=True").Click
' Init
numOfAccounts = Page1.WebList("name:=accountId").GetROProperty("items count") - 1
If numOfAccounts < 1 Then
getRandomAccountWithProducts = -1
Reporter.ReportEvent micFail, "Number of accounts","There are no accounts. No account with products exists"
Exit Function
End If
hasProducts = false
accountIndex = 1
' Get account with products
While ((Not hasProducts) AND (accountIndex =< numOfAccounts))
' Return account if has products
If Page1.WebList("name:=webListName","index:=0","micclass:=WebList","visible:=True").Exist(5) Then
hasProducts = true
End If
If (Not hasProducts) Then
accountIndex = accountIndex + 1
Page1.WebList("name:=accountId").Select "#" & accountIndex
End If
Wend
br.Navigate originalURL
Set Page1= Nothing
Set br = Nothing
' If no account has products, report and exit, else return selected account index
If Not hasProducts Then
Reporter.ReportEvent micFail,"Accounts","No account has products."
getRandomAccountWithProducts = -1
Else
getRandomAccountWithProducts = accountIndex
End If
If Err<>0 Then
errorMessage = "Error number: " & Err.Number & vbNewLine & "Error description: " & Err.Description & vbNewLine & "Error source: " & Err.Source
Reporter.ReportEvent micFail,"Run Time Error",errorMessage
Err.Clear
End If
On Error GoTo 0
End Function
I'm running on Pentium 4, 3.2 GHZ, 2 GB RAM, Win XP, SP 3,IE 7, QTP 10.0 Build 513
Thanks!
Have you considered using the all items property?
AllItems = Page1.WebList("name:=accountId").GetROProperty("all items")
SplitItems = Split(AllItems, ";")
Found = False
For i = 0 To UBound(AllItems)
If AllItems(i) = "<product>" Then
Found = True
Exit For
End If
Next
Solution was found thanks to Jonty,
The problem was in the following section:
' Get account with products
While ((Not hasProducts) AND (accountIndex =< numOfAccounts))
' Return account if has products
If Page1.WebList("name:=webListName","index:=0","micclass:=WebList","visible:=True").Exist(5) Then
hasProducts = true
End If
If (Not hasProducts) Then
accountIndex = accountIndex + 1
Page1.WebList("name:=accountId").Select "#" & accountIndex
End If
Wend
The first time entered to the loop, the account really didn't have any products, so obviously none was recognized. So accountIndex was increased by one and the corresponding account was selected in the web list.
No here lies the problem. The select method caused a refresh in the page and the condition Page1.WebList("name:=webListName","index:=0","micclass:=WebList","visible:=True").Exist(5)
was evaluated before the web list was loaded thus, returning false.
I considered that option, but I thought (wrongly apparently) that the Exist(5) should do the trick, but it seems that it works differently than expected.
Thanks,
Alon