If with multiple and & or - vba

I've been trying to run the below IF condition, however it does not work as intended:
If (LandscapingDataRange(MailCounter, 6) = 1 And (LandscapingDataRange(MailCounter, 4) = 0 Or LandscapingDataRange(MailCounter, 5) = 0)) _
Or (LandscapingDataRange(MailCounter, 6) = 1 And ((LandscapingDataRange(MailCounter, 4) - LandscapingDataRange(MailCounter, 7)) / LandscapingDataRange(MailCounter, 4)) > 0.1) _
Or (LandscapingDataRange(MailCounter, 6) = 0 And LandscapingDataRange(MailCounter, 5) > 0) _
Or (0 < LandscapingDataRange(MailCounter, 6) < 1 And (LandscapingDataRange(MailCounter, 4) = 0 Or LandscapingDataRange(MailCounter, 5) = 0)) _
Or (0 < LandscapingDataRange(MailCounter, 6) < 1 And ((LandscapingDataRange(MailCounter, 4) - LandscapingDataRange(MailCounter, 7)) / LandscapingDataRange(MailCounter, 4)) > 0.1) Then
Those rows with 0 in (LandscapingDataRange(MailCounter, 6)
and 0 in LandscapingDataRange(MailCounter, 5)
Are still applied in the IF function.

I would take a guess that you are using Or where you should be using ElseIf and so your logic is wrong. In that case, use Select Case instead - it's quicker and cleaner. Here's an example with the first 3 conditions and an Else clause - just add the other conditions as required.
Select Case True
(LandscapingDataRange(MailCounter, 6) = 1 And (LandscapingDataRange(MailCounter, 4) = 0 Or LandscapingDataRange(MailCounter, 5) = 0))
'// Do Something
(LandscapingDataRange(MailCounter, 6) = 1 And ((LandscapingDataRange(MailCounter, 4) - LandscapingDataRange(MailCounter, 7)) / LandscapingDataRange(MailCounter, 4)) > 0.1)
'// Do Something
(LandscapingDataRange(MailCounter, 6) = 0 And LandscapingDataRange(MailCounter, 5) > 0)
'// Do Something
Case Else
'// Do Something if none of the criteria are met.
End Select

I don't get, what you want to achieve, but logic operator have an order, in which they are resolved, just like multiplication/division before addition/substraction.
Maybe that is the problem in your case. Before any Or is computed, all And are resolved. So you have to use brackets, if this isn't the order, you want it to be computed.
The precedence order in Visual Basic is Not before And before Or before Xor, and the same rules should apply to VBA too.

Related

Getting an integer value from dates VBA

I am trying to get a value difference (integer) between the years of 2 different dates in VBA and take also month (for example 2020 - 2019, the result I would want is 1) but my code only give me a date. Any ideas?
For i = 2 To PnLD1WS.Cells(1, 1).End(xlDown).Row
PnLD1WS.Cells(i, 164).Value = ((((DateSerial(Year(PnLD1WS.Cells(i, 13)), 0, 0) - DateSerial(Year(PnLD1WS.Cells(i, 3)), 0, 0)) * 12) + (DateSerial(0, (Month(PnLD1WS.Cells(i, 13))), 0) - (DateSerial(0, (Month(PnLD1WS.Cells(i, 3))), 0)))))
Next i
You can use DateDiff:
DateDiff("yyyy", dat1, dat2)
With your code:
...
With PnLD1WS
.Cells(i, 164).Value = DateDiff("yyyy", .Cells(i, 13), PnLD1WS.Cells(i, 3))
End with
....

Do loop until 2 things in column do not equal. Pulling information from another sheet

I am trying to pull information from another sheet and then have it check to make sure 2 cells in this sheet are not the same. It is for a randomized meal plan, but on the same day you can not eat the same protein (to give you a little background). I have the code checking to see if it can be used during that meal and if it can be it is put into the next sheet. It does this for lunch and dinner. It is getting caught in the do - loop until loop and I am not sure how to solve this.
If you need anymore information I can provide screenshots if this does not make sense.
Do
RandNumLunch = Int((10 - 2 + 1) * Rnd + 2)
Do Until Sheet2.Cells(RandNumLunch, 6) = "Yes"
If Sheet2.Cells(RandNumLunch, 6) = "Yes" Then
Else
RandNumLunch = Int((10 - 2 + 1) * Rnd + 2)
End If
Loop
If Sheet2.Cells(RandNumLunch, 6) = "Yes" Then
Sheet3.Cells(3, 2) = Sheet2.Cells(RandNumLunch, 1)
End If
RandNumDinner = Int((10 - 2 + 1) * Rnd + 2)
Do Until Sheet2.Cells(RandNumDinner, 7) = "Yes"
If Sheet2.Cells(RandNumDinner, 7) = "Yes" Then
Else
RandNumDinner = Int((10 - 2 + 1) * Rnd + 2)
End If
Loop
If Sheet2.Cells(RandNumDinner, 7) = "Yes" Then
Sheet3.Cells(4, 2) = Sheet2.Cells(RandNumLunch, 1)
End If
Loop Until Sheet3.Cells(4, 2) <> Sheet3.Cells(3, 2)
In your final If..Else, you use RandNumLunch where you should be using RandNumDinner. This means that the whatever happens in between, you set Sheet3.Cells(3, 2) and Sheet3.Cells(4, 2) to the same value, so the final check can never be true.

Type Mismatch Array Position Compare Vba

I don't understand why I cannot compare an array in VBA. I created an array that starts 0 1 2 3. I added a comparison due to subscript errors trying to compare 0 to 0 - 1 so it can only start comparisons at 1 and continue. Now I'm receiving a type Mismatch 13 and I can't figure out why the data type is different/not working. I'm guessing i in a for loop is not considered an int or something?
It fails at CoordinatesArray(i) = CoordinatesArray(i-1)
Code:
For i = 0 To NumLines - 1
coordx1 = (vLines(12 * i + 6))
coordy1 = (vLines(12 * i + 7))
coordz1 = (vLines(12 * i + 8))
CoordinatesArray(i) = Array(coordx1, coordy1, coordz1)
If i > 0 Then
If CoordinatesArray(i) = CoordinatesArray(i - 1) Then
coordx1 = (vLines(7))
You will need to compare each value in the jagged array separately:
For i = 0 To NumLines - 1
coordx1 = (vLines(12 * i + 6))
coordy1 = (vLines(12 * i + 7))
coordz1 = (vLines(12 * i + 8))
CoordinatesArray(i) = Array(coordx1, coordy1, coordz1)
If i > 0 Then
If CoordinatesArray(i)(1) = CoordinatesArray(i - 1)(1) And _
CoordinatesArray(i)(2) = CoordinatesArray(i - 1)(2) And _
CoordinatesArray(i)(3) = CoordinatesArray(i - 1)(3) Then
coordx1 = (vLines(7))

How i can use a criteria in cicle for i

i want to use a criteria in my loop
but not work
UR = 3
ReDim arng(UR, 3) As Variant
For X = 0 To UR
arng(X, 0) = ConvDate(Cells(X , 8))
arng(X, 1) = ConvDate(Cells(X , 12))
arng(X, 2) = Iif(Cells(X , 12) = "", MsgBox("empty"), MsgBox("Full"))
Next X
even if the cell(X,12) is actually empty both messages show
Why?!?!?
isn't possible to use a criteria??
thank
Worked over a lil bit, try this
dim UR as integer
UR = 3
ReDim arng(UR, 3) As Variant
For X = 0 To UR
arng(X, 0) = ConvDate(Cells(X , 8))
arng(X, 1) = ConvDate(Cells(X , 12))
if Cells(X , 12) = "" then
MsgBox("empty")
else
msgbox("full")
end if
Next X

Working with Excel ranges and arrays

In VBA, I can easily pull in an sheet\range into an array, manipulate, then pass back to the sheet\range. I'm having trouble doing this in VB.Net though.
Here's my code.
Rng = .Range("a4", .Cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count))
Dim SheetArray(,) As Object = DirectCast(Rng.Value(Excel.XlRangeValueDataType.xlRangeValueDefault), Object(,))
For X As Integer = 0 To SheetArray.GetUpperBound(0)
If IsNothing(SheetArray(X, 0)) Then Exit For
SheetArray(X, 6) = SheetArray(X, 3)
SheetArray(X, 7) = CDbl(SheetArray(X, 3).ToString) - CDbl(SheetArray(X, 1).ToString) - _
CDbl(SheetArray(X, 7).ToString)
For Y As Integer = 0 To 3
SheetArray(X, Y * 2 + 1) = Math.Round(CDbl(SheetArray(X, Y * 2 + 1).ToString), 3)
Next
If Math.Abs(CDbl(SheetArray(X, 7).ToString)) > 0.1 Then _
.Range(.Cells(X + 1, 1), .Cells(X + 1, 8)).Font.Color = -16776961
Next
I'm getting an error on the first If IsNothing(SheetArray(X, 0)) Then Exit For
line. It is telling me index is out of bounds of the array. Any idea why? The SheetArray object contains the data, but I just am not sure how to get to it.
In the For you have to loop from 0 to Count - 1:
For X As Integer = 0 To SheetArray.GetUpperBound(0) - 1
'...
Next
That will fix your problem.