Calling Another Code - vba

I am trying to figure out another way to write this line. Currently, I have it to where if any of the ranges AA2:AA7 = 1 then call code OneLineItem. Issue is, the parameter I need set is if only one of those cells equals 1 and only one other cell to be greater than 1. I.e. AA2 = 1 and AA7=200 (for example). A problem i'm running into is that AA2 = 1, AA3 = 100, AA7 = 200. However I just need one cell to equal 1 and another cell to be >1 and everything else to be 0. If that criteria is met, then call code OneLineItem. Thank You.
If ActiveSheet.Range("AA2") = 1 Or ActiveSheet.Range("AA3") = 1 Or
ActiveSheet.Range("AA4") = 1 Or ActiveSheet.Range("AA5") = 1 Or
ActiveSheet.Range("AA6") = 1 Or _
ActiveSheet.Range("AA7") = 1 Then
Call OneLineItem
Else

There are 6 numbers so:
1 should be 1
1 should be greater than 1
4 should be 0
so we can use COUNTIF() to find if it follows the pattern
Dim OneTrue As Boolean
Dim MoreTrue As Boolean
Dim RestTrue As Boolean
RestTrue = Application.WorksheetFunction.CountIf([AA2:AA7], 0) = 4 [AA2:AA7].Cells.Count - 2
OneTrue = Application.WorksheetFunction.CountIf([AA2:AA7], 1) = 1
MoreTrue = Application.WorksheetFunction.CountIf([AA2:AA7], ">1") = 1
If RestTrue And OneTrue And MoreTrue Then
Call OneLineItem
End If
Another method would be to nest the IF:
IF Application.WorksheetFunction.CountIf([AA2:AA7], 0) = [AA2:AA7].Cells.Count - 2 Then
IF Application.WorksheetFunction.CountIf([AA2:AA7], 1) = 1 Then
'we do not need the third, If the others are true then the last must be true.
'Unless you can have negative numbers. Then you can add the third.
Call OneLineItem
End If
End If
The advantage to the second is that it only does the COUNTIFs necessary till it find a False return, then it does not do any more. while the first does all three no matter what.

Related

VBA min value and table

I have a sheet with 2 tables. I want to find and return the cell of column 1 which has the minimum proteges.
For example, my code would return either Phil,Levy or Sean, Montain in the first run. (then my spreadsheet will add +1 to one of the two - this is already set in excel). etc....
Coach List Protégées
Phil, Levy 7
Sean, Monteine 7
Victor, Chatelais 8
I have write a code but unfortunately ot does it randomly. Any thoughts ?
Code:
Dim Coach As String
Dim ws As Worksheet, t As ListObject, r As Long
For Each t In MyWorksheet.ListObjects
Select Case t.Name
Case "Table1", "Table3", "Table4", "Table6", "Table8", "Table10", "Table12", "Table14", "Table16"
'do nothing
Case Else
'Coach = Application.WorksheetFunction.Min(t.ListColumns(2).Range)--> could use that ?
For r = 1 To t.DataBodyRange.Rows.Count
For r = t.DataBodyRange.Rows.Count To 1 Step -1
If t.DataBodyRange(r, 2) <= t.DataBodyRange(r + 1, 2) Then
Coach = t.DataBodyRange(r , 1)
End If
Next r
End Select
Next t
I think your method needs a variable for the lowest number found as each row is compared.
p = 9999
For r = 1 To t.DataBodyRange.Rows.Count
If t.DataBodyRange(r, 2) <= p Then
p = t.DataBodyRange(r, 2)
Coach = t.DataBodyRange(r, 1)
End If
Next r

Iterative IF condition in For Loop assigned to Matrix

I am trying to assign values from one worksheet (DATA) to a matrix (TaskArray()) using nested for loops. My issue is that the IF statement, when met, will be assigned to all values in the appropriate TaskArray() row. How do I set singular IF (or boolean) conditions in nested for loops that only get recognized once?
Dim TaskArray(1 to 10, 1 to 300) as String
For i = 1 to 300
For j = 1 to 10
If Sheets("DATA").Cells(i,1).Value = TRUE Then
TaskArray(1, AA) = Sheets("DATA").Cells(i,4).Value
AA = AA + 1
If Sheets("DATA").Cells(i,2).Value = TRUE Then
TaskArray(1, BB) = Sheets("DATA").Cells(i,4).Value
BB = BB + 1
End if
Next j
Next i
Thank you!

Looping through a specified array?

I am trying to match the row height of specific rows from one sheet to another, This works if I just remove all lines with rowlist and do For i = 1 to 200, but this takes too long. I only want to match a few row heights and not go through all between 1 and 200. My code is below:
Dim y As Double
Dim i As Long
Dim rowlist() As Variant
rowlist = Array(3, 5, 23, 30)
For i = LBound(rowlist) To UBound(rowlist)
y = Worksheets("Development").Rows(i).RowHeight
Worksheets("Final").Rows(i).RowHeight = y
Next i
When you're setting and using y, use .Rows(rowlist(i)) rather than .Rows(i).
i simply stores the index of the array, not the value, i.e.
i = 0 ; rowlist(i) =3
i = 1 ; rowlist(i)= 5
i = 2 ; rowlist(i)= 23
i = 3 ; rowlist(i)= 30
So you're correct in looping from LBound(rowlist) to UBound(rowlist), you just need to make sure that you're using the values stored in the array within that loop.

Issues with For Loop in VB

For i = 1 To 5
If i = 0 Then
i = i + 1
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1
Else
LabelOdds.Text = i
i = i + 1
End If
Next i
I'm making a program in VB where I have to use a for loop to sort between 2 numbers(loop limit 1 and 2) and find if they are even or odd, Then output the results to 2 labels. This loop makes sense to me, but for example when I put in 1 and 4 all it outputs is a 5 in the odd label. I guess my question is can anyone see the issue with my loop?
You don't need to add 1 to your loop variable i manually, the for loop itself does that for you behind the scenes:
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = i
Else
LabelOdds.Text = i
End If
Next i
You'll noticed I've also removed the If i = 0 bit since i can never be zero within that loop. It ranges from one to five inclusive.
One other thing you'll need to do is to append the value to your text box. What you have at the moment is a replacement so that it'll only be set to the last value processed. Something like this should suffice:
' Initialise to empty strings '
LabelEvens.Text = ""
LabelOdds.Text = ""
' Append the values '
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & "," & CStr(i)
Else
LabelOdds.Text = LabelOdds.Text & "," & CStr(i)
End If
Next i
' Remove initial comma from both '
LabelEvens.Text = Mid(LabelEvens.Text,2)
LabelOdds.Text = Mid(LabelOdds.Text,2)
Some issues in your code:
For i = 1 To 5
If i = 0 Then <-- 'I' will never be 0 since you start from 1
i = i + 1 <-- Don't manually increment since you are using a for
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
Else
LabelOdds.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
End If
Next i
Another issue you have is that if you have more than one odd number in the for range (say in a range of 1 to 10) you will only get the last number. What do you want to do in this case? Concatenate all odd numbers in a string or stop after the first one is found? Do you really need a FOR loop at all?
you can Also state
LabelEvens.Text="" 'Clear contents of the label before assigning new values
LabelOdds.Text=""
For i As Integer = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & i
Else
LabelOdds.Text = LabelOdds.Text & i
End If
Next
From Above you can replace '&' with '+' if you want the Total.

Verify Gamefield VB.NET

So I'm developing a minesweeper game and im assigning the mines, but I've got to check where are the mines now, in order to generate the numbers. The problem is that when I'm verifying the columns and lines I need the program not to get out of the game field.
Here's how my code looks like now:
Public Sub avisinhos(ByVal line, ByVal column)
If mat(line, column) = 0 Then
mat(line, column) = -1
numbandeiras = numbandeiras + 1
End If
For auxlinha = -1 To 1
For auxcolumn = -1 To 1
Next
Next
End Sub
How do I create a IF function to verify that I don't get out of the game field?
Best regards, joao.
pseudo code
int linestart = -1;
int lineend = 1;
int colstart = -1;
int colend = 1;
Assuming a 10 x 10 grid (zero based)
if line < 2 linestart = 0
if line > 8 lineend = 0
if column < 2 colstart = 0
if column > 8 colend = 0
For auxlinha = linestart To lineend
For auxcolumn = colstart To colend
// check
Next
Next
Personally though I wouldn't bother with the loops, they add very little to nothing
HasMineAbove = (line > 1) and (gamefield[line -1,column] = MinePresentValue
would be my approach, do it all in one.
Not to mention the huge potential confusion when auxlinha and auxcolumn are both zero...
I'm not sure exactly what your code is saying. It's a bit cryptic since you're using abbreviations and all lowercase names. You might want to try camelCasing and spelling out the words more completely, intellisense is your friend. =)
But coding style aside, if you are trying to loop through a limited range of values, you can keep your values bounded by using the modulus operator (%). For example, if you need to keep you values between 0-7 and you end up with a value of 12, just take the modulus of 8 to loop back to within range with a value of 4:
12 % 8 = 4
9 % 8 = 1
15 % 8 = 7
24 % 8 = 0
I realize this doesn't answer your specific question, but it's a handy technique might find useful.