I would like to create a simple formula to calculate the net change on a certain row, and print it in the same row (column H). But what I plug into the formula will depend on the value at each row's column A.
This is the code that I tried:
Sub totalPnL()
Dim LR As Long
LR = Range("D" & Rows.Count).End(xlUp).Row
If Range("A2:A" & LR).Value = "WIN" Then
Range("H2:H" & LR).Formula = "=ABS(D2-F2)*G2"
ElseIf Range("A2:A" & LR).Value = "LOSS" Then
Range("H2:H" & LR).Formula = "=-ABS(D2-E2)*G2"
End If
Range("T2") = Application.WorksheetFunction.Sum(Range("H:H"))
End Sub
I feel something is wrong with the If statement, but I'm not sure how to edit it
Thanks for all the help
As written in the comment a formula will be easier and quicker but if you want to have your code "fixed" then the following code would do it.
Sub totalPnL()
Dim LR As Long, i As Long
LR = Range("D" & Rows.Count).End(xlUp).Row
' the original statement
' Range("A2:A" & LR).Value = "WIN"
' cannot work as Range("A2:A" & LR) will be an array in case LR > 2
' in this case you have to loop
' AGAIN: usage of a formula will be better
For i = 2 To LR
If Range("A" & i).Value = "WIN" Then
Range("H" & i).FormulaR1C1 = "=ABS(RC[-4]-RC[-2])*RC[-1]"
ElseIf Range("A" & i).Value = "LOSS" Then
Range("H" & i).FormulaR1C1 = "=ABS(RC[-4]-RC[-2])*RC[-1]"
End If
Next i
Range("T2") = Application.WorksheetFunction.Sum(Range("H:H"))
End Sub
To make the code easier to read you could use a Select statement
For i = 2 To LR
Select Case Range("A" & i).Value
Case "WIN"
Range("H" & i).FormulaR1C1 = "=ABS(RC[-4]-RC[-2])*RC[-1]"
Case "LOSS"
Range("H" & i).FormulaR1C1 = "=ABS(RC[-4]-RC[-2])*RC[-1]"
End Select
Next i
Another formula you could use would be
=IF(A2="WIN";1;(IF(A2="LOSS";-1)))*ABS(D2-F2)*G2
I want to have 2 formulas with continuous looping as long as there is value in the cell next to the targeted cell, thus i need to have ifelse function but with continuous looping aswell. for now i don't know how to insert the second formula.
Range("D9").Select
Set ws = Sheets("LAP KEL BIAYA")
lastRow = ws.Range("C" & Rows.Count).End(xlUp).Row
With ws
For i = 9 To lastRow
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
Function Total(Text, Number)
.Range("D" & i).Formula = "=IF(RC[-3]=""B"",IF(AND(R4C3>0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3>0,R5C3=""""),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C[47],'LAP KEL BIAYA'!RC[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3=0,R5C3=0),SUMIFS(F" & _
"BL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),"""")))))" & _
""
ElseIf Total = "False" Then
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
.Range("D" & i).Formula = "=IF(AND(R4C3>0,R5C3>0,OR(R[-1]C1=""7"",R[-1]C1=""5"",R[-1]C1=""4"")),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(AND(R4C3>0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C,'LAP KEL BIAYA'!R[-1]C[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(" & _
"AND(R4C3=0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1])))))" & _
""
.Range("D" & i).Font.Color = vbRed
End If
Next i
End Function
End With
I'm trying to find a solution of
application.match error code 13
this is just a simple code in vba, is someone who can can help me fixing this code
Private Sub cmbName_Change()
If Me.cmbName.Value <> "" Then
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("DATABASE")
Dim i As Integer
i = Application.Match(VBA.CLng(Me.cmbName.Value), sh.Range("A:A"), 0)
Me.txtDatepicker.Value = sh.Range("A" & y).Value
Me.cmbAddress.Value = sh.Range("C" & i).Value
Me.txtContact.Value = sh.Range("D" & j).Value
Me.cmbEducation.Value = sh.Range("E" & i).Value
Me.cmbSpecify.Value = sh.Range("F" & i).Value
Me.txtAge.Value = sh.Range("G" & j).Value
If sh.Range("H" & i).Value = "Male" Then Me.optMale.Value = True
If sh.Range("H" & i).Value = "Female" Then Me.optFemale.Value = True
Me.cmbTraining.Value = sh.Range("I" & i).Value
Me.cmbEmployment.Value = sh.Range("J" & i).Value
Me.txtOthers.Value = sh.Range("K" & i).Value
Me.txtAction.Value = sh.Range("L" & i).Value
Me.txtLivelihood.Value = sh.Range("M" & i).Value
End If
End Sub
Error code 13 stands for Type Mismatch.
Possibility 1
You get this error because you are passing a string that contains characters that can't be interpreted as number to the Clng function. Hence, it can't be converted to a long variable.
To solve this you could add some error handling to convert to a long only when Clng doesn't return an error or you could get rid of the Clng function all together and make sure that Column A is formatted as text (since that's the range you are matching to).
Possibility 2
You get this error because there is no cell in column A that matches the value in the combobox.
To solve this, you would need to add some error handling and decide what you want to do when there is no match.
I'm writing a code that calculate number automatically every time you edit a sheet. But somehow the code I wrote is not functioning properly that it gives a run-time error. I checked the cells and range but they are all valid and correct. All of the inputs and variables involved are simple integers (no more than 3 digits).
I just got a work assignment to automate some excel sheets at work and I just learned vba from ground up recently.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Integer
Dim i As Byte
i = 5
For i = 5 To 12
If Worksheets("Sheet1").Range("D" & i).Value = "" Or Worksheets("Sheet1").Range("D" & i).Value = 0 Then
A = Worksheets("Sheet1").Range("E" & i).Value - Worksheets("Sheet1").Range("C" & i).Value
Worksheets("Sheet1").Range("F" & i).Value = A
Else
Worksheets("Sheet1").Range("F" & i).Value = Worksheets("Sheet1").Range("D" & i).Value * Worksheets("Sheet1").Range("B" & i).Value _
+ Worksheets("Sheet1").Range("E" & i).Value - Worksheets("Sheet1").Range("C" & i).Value
End If
Next i
End Sub
It gives a run-time error
Give this a shot and let me know what error you get:
Private Sub Worksheet_Change(ByVal Target As Range)
'Only run if something changes in column D or E
If Target.Column = 4 Or Target.Column = 5 Then
'Turn off any events so that we don't encounter recursion
Application.EnableEvents = False
'This will help readability a bit
Dim sht As Worksheet
Set sht = ThisWorkbook.Worksheets("Sheet1")
Dim A As Integer
Dim i As Long
'This needs to be removed - it's irrelevant as i is used as an iterable on the next line
'i = 5
For i = 5 To 12
If sht.Range("D" & i).Value = "" Or sht.Range("D" & i).Value = 0 Then
'What's the point of using a variable here?
A = sht.Range("E" & i).Value - sht.Range("C" & i).Value
sht.Range("F" & i).Value = A
Else
'Order of operations - is that important here?
'Are we certain these fields are numeric?
sht.Range("F" & i).Value = sht.Range("D" & i).Value * sht.Range("B" & i).Value _
+ sht.Range("E" & i).Value - sht.Range("C" & i).Value
End If
Next i
'Turn it back on once we're done
Application.EnableEvents = True
End If
End Sub
Something is wrong with the nested If statements, causing the Do loop error. If I simplify my If block to one item, it works fine. (I usually work in C#.NET in VS). This is supposed to be part of a simple form in Excel to aid data entry.
Private Sub cbDelete_Click()
If tbName.Value = "" Then
MsgBox "Sorry, please navigate to a non-blank row."
Exit Sub
End If
Dim i As Integer
i = 3
Do While ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value <> ""
'MsgBox ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value
If (tbName.Value = ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value) Then
If (dpDateSubmited.Value = ThisWorkbook.Worksheets("Non-SR").Range("B" & i).Value) Then
If (tbLocation.Value = ThisWorkbook.Worksheets("Non-SR").Range("C" & i).Value) Then
If (tbBU.Value = ThisWorkbook.Worksheets("Non-SR").Range("D" & i).Value) Then
If (tbTitle.Value = ThisWorkbook.Worksheets("Non-SR").Range("E" & i).Value) Then
If (tbDescription.Value = ThisWorkbook.Worksheets("Non-SR").Range("F" & i).Value) Then
If (tbStatus.Value = ThisWorkbook.Worksheets("Non-SR").Range("G" & i).Value) Then
ThisWorkbook.Worksheets("Non-SR").Rows(i).Delete Shift:=xlUp
Exit Sub
End If
i = i + 1
Loop
MsgBox "Item not found!"
End Sub
New fixed code:
Private Sub CommandButton1_Click()
If tbName.Value = "" Then
MsgBox "Sorry, please navigate to a non-blank row."
Exit Sub
End If
Dim i As Integer
i = 3
Do While ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value <> ""
'MsgBox ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value
If (tbName.Value = ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value) And _
(dpDateSubmited.Value = ThisWorkbook.Worksheets("Non-SR").Range("B" & i).Value) And _
(tbLocation.Value = ThisWorkbook.Worksheets("Non-SR").Range("C" & i).Value) And _
(tbBU.Value = ThisWorkbook.Worksheets("Non-SR").Range("D" & i).Value) And _
(tbTitle.Value = ThisWorkbook.Worksheets("Non-SR").Range("E" & i).Value) And _
(tbDescription.Value = ThisWorkbook.Worksheets("Non-SR").Range("F" & i).Value) And _
(tbStatus.Value = ThisWorkbook.Worksheets("Non-SR").Range("G" & i).Value) Then
ThisWorkbook.Worksheets("Non-SR").Rows(i).Delete Shift:=xlUp
Exit Sub
End If
i = i + 1
Loop
MsgBox "Item not found!"
End Sub
Appreciate all the help.
-RickH
I am not quite sure yet, what you need. Still, I'd like to propose already a few changes to simplify your code block in the following way:
Private Sub cbDelete_Click()
If tbName.Value = "" Then
MsgBox "Sorry, please navigate to a non-blank row."
Exit Sub
End If
Dim i As Integer
i = 3
With ThisWorkbook.Worksheets("Non-SR")
For i = 3 To .Cells(.Rows.Count, "A").End(xlUp).Row
'MsgBox ThisWorkbook.Worksheets("Non-SR").Range("A" & i).Value
If tbName.Value = .Range("A" & i).Value And _
dpDateSubmited.Value = .Range("B" & i).Value And _
tbLocation.Value = .Range("C" & i).Value And _
tbBU.Value = .Range("D" & i).Value And _
tbTitle.Value = .Range("E" & i).Value And _
tbDescription.Value = .Range("F" & i).Value And _
tbStatus.Value = .Range("G" & i).Value Then
.Rows(i).Delete Shift:=xlUp
Exit Sub
End If
Next i
End With
MsgBox "Item not found!"
End Sub
The Do...Loop has been removed and exchanged with a For...Next
All the If statements have been combined into one
A With block has been set to speed up your code and make the code shorter.
If statements are code block.
You can have a single line If statement
VBA
If a = 10 Then do_something Else do_somthingElse
C#
if(a = 10)
do_somthingElse;
Multi-line If statements must be closed
VBA Use End If to enclose the code
If a = 10 Then
do_something
Else
do_somthingElse
End If
C# Use brackets {} to enclose the code
if(a = 10){
do_somthingElse;
else{
do_somthingElse;
}
Your code opened 7 If statement blocks an closed 1 of them