I have a IF-Statement, and I need to loop it throug column F.
This loop checks for the word "empty" in column F and if found, it gets entered into columns G too. In column H the current date gets added, if it was not already in it. If F and G have "empty" in it, and H a date, the If-Statement gets ended.
If Range("F2").Value = "empty" And Range("G2").Value = "" Then
Range("G2").Value = "empty"
ElseIf (Range("F2").Value = "empty" And Range("G2").Value = "empty") And Range("H2").Value = "" Then
Range("H2") = Date
ElseIf (Range("F2").Value = "empty" And Range("G2").Value = "empty") And Range("H2").Value <> "" Then
End If
Can someone help me to add this into a loop, that goes trough the lines?
It manly needs to go trough line 2 to 1500.
Any help would be apprechiated.
Kind regards.
Nested Statements in a Loop
Sub NestedStatements()
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim rg As Range: Set rg = ws.Range("F2:H1500")
Dim rrg As Range
For Each rrg In rg.Rows
If CStr(rrg.Cells(1).Value) = "empty" Then
Select Case CStr(rrg.Cells(2).Value)
Case ""
rrg.Cells(2).Value = "empty"
Case "empty"
If CStr(rrg.Cells(3).Value) = "" Then
rrg.Cells(3).Value = Date
End If
End Select
End If
Next rrg
End Sub
Try something like this
Dim i as long
For i = 2 to 1500
If Range("F" & i).Value = "empty" And Range("G" & i).Value = "" Then
Range("G" & i).Value = "empty"
ElseIf (Range("F" & i).Value = "empty" And Range("G" & i).Value = "empty") And Range("H" & i).Value = "" Then
Range("H" & i) = Date
ElseIf (Range("F" & i).Value = "empty" And Range("G" & i).Value = "empty") And Range("H" & i).Value <> "" Then
'do something
End If
Next i
I would create a single sub to do the job - to which you pass the range that should be checked:
Option Explicit
Private Const colF As Long = 6
Private Const colG As Long = 7
Private Const colH As Long = 8
'-->> this is an example of how to call the sub
Sub test_checkColumnsFtoH()
checkColumnsFtoH ThisWorkbook.Worksheets("Table1").Range("A1:I500")
End Sub
'-->> this is your new sub
Sub checkColumnsFtoH(rgToBeChecked As Range)
Dim i As Long
With rgToBeChecked
For i = 2 To .Rows.Count
If .Cells(i, colF).Value = "empty" And .Cells(i, colG).Value = "" Then
.Cells(i, colG).Value = "empty"
ElseIf (.Cells(i, colF).Value = "empty" And .Cells(i, colG).Value = "empty") _
And .Cells(i, colH).Value = "" Then
.Cells(i, colH) = Date
End If
Next
End With
End Sub
I am using the cells property to avoid string concatination ("H" & i)
you don't need the last elseif - as nothing happens there.
Related
The following code runs but, not getting the results. The information is there in the correct range.
Dim ID As Range
Dim SN As Range
Dim i As Integer
Set ID = Sheet6.Range("B2:B8")
Set SN = Sheet2.Range("C7:C184")
For i = 2 To ID.Cells.count
If ID.Cells(i) = SN.Cells(i) Then
MsgBox "do something"
ID.Cells.Offset(0, 2).Value = SN.Cells.Offset(0, -2).Value
Else
MsgBox "sorry"
End If
Next
i found another code and modified it to my work sheet. This one works great.
Dim i As Long
Dim j As Long
For i = 2 To 40
If Sheet6.Range("C" & i).Value = "" Then
Exit For
End If
For j = 7 To 1000
If Sheet2.Range("c" & j).Value = "" Then
Exit For
End If
If Sheet6.Range("C" & i).Text = Sheet2.Range("c" & j).Text Then
Sheet6.Range("C" & i).Offset(0, 1).Value = Sheet2.Range("c" & j).Offset(0, -2).Value
Sheet6.Range("C" & i).Offset(0, 2).Value = Sheet2.Range("c" & j).Offset(0, 2).Value
Exit For
End If
Next j
Next i
Hello i m very new at VBA as i m suffering with an issue here,in filtered cell if the condition is correct then put "yes" else put "NO"
but when i run the code in for LOOP it put the yes data in all even if the condition is not true
VBA
Sub check()
Dim j As Long
Dim dsheet As Worksheet
Dim lastrow As Long
Dim fr As Range
Dim psheet As Worksheet
Dim c As Range
Set dsheet = Worksheets("Workings")
Set psheet = Worksheets("sheet1")
lastrow = dsheet.Cells(Rows.Count, 1).End(xlUp).row
For j = 1 To lastrow
psheet.Range("M2").Value = dsheet.Range("A2" & j)
psheet.Range("N2").Value = dsheet.Range("B2" & j)
psheet.Range("A1").AutoFilter Field:=1, Criteria1:=psheet.Range("M2")
psheet.Range("B1").AutoFilter Field:=2, Criteria1:=psheet.Range("N2")
psheet.Range("A2:I" & psheet.Cells(Rows.Count, 1).End(xlUp).row).SpecialCells (xlCellTypeVisible)
dsheet.Range("M2").Value = dsheet.Range("A" & j)
dsheet.Range("N2").Value = dsheet.Range("B" & j)
dsheet.Range("A1").AutoFilter Field:=1, Criteria1:=dsheet.Range("M2")
dsheet.Range("B1").AutoFilter Field:=2, Criteria1:=dsheet.Range("N2")
Set fr = psheet.Range("C2:C50").Find(what:="12345", MatchCase:=True)
For Each c In dsheet.Range("E2:E2000" & Range("A" & Rows.Count).End(xlUp).row).SpecialCells(xlCellTypeVisible)
If fr Is Nothing Then
dsheet.Range("A2" & Range("A" & Rows.Count).End(xlUp).row).SpecialCells (xlCellTypeVisible)
If c.Offset(, -1).Value = vbNullString Then Exit For
c.Value = "NO"
Else
dsheet.Range("A2" & Range("A" Rows.Count).End(xlUp).row).SpecialCells (xlCellTypeVisible)
If c.Offset(, -1). Value =vbNullString Then Exit For
c.Value = "Yes"
End If
Next c
Next j
dsheet. AutoFilterMode = False
psheet. AutoFilterMode = False
End Sub
so, i want the the code to put the "yes" or "NO" according to the condition,It will be great help if anyone help me in this issue
You need an End If for each If statement. It should be like this: Also, proper indenting helps make your code more readable.
If fr Is Nothing Then
dsheet.Range("A2" & Range("A" & Rows.Count).End(xlUp).row).SpecialCells (xlCellTypeVisible)
If c.Offset(, -1).Value = vbNullString Then Exit For
End If
c.Value = "NO"
Else
dsheet.Range("A2" & Range("A" Rows.Count).End(xlUp).row).SpecialCells
(xlCellTypeVisible)
If c.Offset(, -1). Value =vbNullString Then Exit For
End If
c.Value = "Yes"
End If
I have a code that I want to apply to several rows. I only created for Row 11, my problem is that I need to apply below code until Row 60. How can I write it?
Sorry still new in VBA world & I am having hard time understanding the For Each or looping rule.
Sub RectangleRoundedCorners11_Click()
If Range("A11").Value = "new request" Then
If Range("D11").Value = "" Or Range("E11").Value = "" Or Range("G11").Value = "" Or Range("H11").Value = "" Then
MsgBox "Please fill all mandatory fields"
End If
End If
End Sub
Code below:
Sub RectangleRoundedCorners11_Click()
for i=11 to 60
If Range("A" & i).Value = "new request" Then
If Range("D" & i).Value = "" Or Range("E" & i).Value = "" Or Range("G" & i).Value = "" Or Range("H" & i).Value = "" Then
MsgBox "Please fill all mandatory fields"
End If
End If
next i
End Sub
This will check the rows between 11 and 60. If you need more rows, just edit the values in the for statement.
You can use this code
Sub RectangleRoundedCorners11_Click()
Dim col As Integer
If Range("A11").Value = "new request" Then
'loop from D to ...
For col = 4 To 60
If Range(Col2Letter(col) & "11").Value = "" Then
MsgBox "Please fill all mandatory fields"
Exit For
End If
Next
End If
End Sub
Function Col2Letter(lngCol As Integer) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col2Letter = vArr(0)
End Function
Through Rows
Tips
Use Option Explicit for VBA to detect errors.
Use constants at the beginning of the code to quickly be able to change them in one place.
Declare all variables (e.g. Dim i As Integer)
The Code
Option Explicit
Sub RectangleRoundedCorners11_Click()
Const cFirst As Integer = 11 ' First Row
Const cLast As Integer = 60 ' Last Row
Const cRequest As String = "new request" ' Request Text
Const cMsg As String = "Please fill all mandatory fields" ' MsgBox Text
Dim i As Integer
For i = cFirst To cLast
If Range("A" & i).Value = cRequest Then
If Range("D" & i).Value = "" Or Range("E" & i).Value = "" _
Or Range("G" & i).Value = "" Or Range("H" & i).Value = "" Then
MsgBox cMsg
End If
End If
Next
End Sub
A one cell range can be created using Range or Cells e.g. for A1:
Range("A1") or Cells(1, "A") or Cells(1, 1).
The If statement has a few versions. In this case two of them are
equally valid, simplified as follows:
If x=y Then
x=5
End If
' or
If x=y Then x=5
A More Advanced Version
Sub RectangleRoundedCorners11_Click()
Const cFirst As Integer = 11 ' First Row
Const cLast As Integer = 60 ' Last Row
Const cRequest As String = "new request" ' Request Text
Const cMsg As String = "Please fill all mandatory fields" ' MsgBox Text
Const cColumns As String = "A,D,E,G,H" ' Columns List
Dim vnt As Variant ' Columns Array
Dim i As Integer ' Row Counter
vnt = Split(cColumns, ",") ' An array created with Split is 0-based.
For i = cFirst To cLast
If Cells(i, vnt(0)).Value = cRequest Then
If Cells(i, vnt(1)).Value = "" Or Cells(i, vnt(2)).Value = "" _
Or Cells(i, vnt(3)).Value = "" _
Or Cells(i, vnt(4)).Value = "" Then MsgBox cMsg
End If
Next
End Sub
Hi I need to enter multiple rows of data at once based on the checkboxes that are selected. Currently this only adds 1 row. I think I have to use a loop but I'm not sure how I should implement it. Can anyone help please ?
The sample output should look something like this:
TC37 | 1
TC37 | 2
TC37 | 4
Current Code:
Dim LastRow As Long, ws As Worksheet
Private Sub CommandButton1_Click()
Set ws = Sheets("sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row + 1
ws.Range("A" & LastRow).Value = ComboBox1.Text
If CheckBox1.Value = True Then
ws.Range("B" & LastRow).Value = "1"
End If
If CheckBox2.Value = True Then
ws.Range("B" & LastRow).Value = "2"
End If
If CheckBox3.Value = True Then
ws.Range("B" & LastRow).Value = "3"
End If
If CheckBox4.Value = True Then
ws.Range("B" & LastRow).Value = "4"
End If
End Sub
Private Sub UserForm_Initialize()
ComboBox1.List = Array("TC37", "TC38", "TC39", "TC40")
End Sub
Since you are getting the last row 1 time, you should dump the data with reference to that one time. Try something like:
Dim chkCnt As Integer
Dim ctl As MSForms.Control, i As Integer, lr As Long
Dim cb As MSForms.CheckBox
With Me
'/* check if something is checked */
chkCnt = .CheckBox1.Value + .CheckBox2.Value + .CheckBox3.Value + .CheckBox4.Value
chkCnt = Abs(chkCnt)
'/* check if something is checked and selected */
If chkCnt <> 0 And .ComboBox1 <> "" Then
ReDim mval(1 To chkCnt, 1 To 2)
i = 1
'/* dump values to array */
For Each ctl In .Controls
If TypeOf ctl Is MSForms.CheckBox Then
Set cb = ctl
If cb Then
mval(i, 1) = .ComboBox1.Value
mval(i, 2) = cb.Caption
i = i + 1
End If
End If
Next
End If
End With
'/* dump array to sheet */
With Sheets("Sheet1") 'Sheet1
lr = .Range("A" & .Rows.Count).End(xlUp).Row + 1
.Range("A" & lr).Resize(UBound(mval, 1), 2) = mval
End With
Problem is that your variable LastRow does not change. It is set only once at the beginning. So when you try to write the value, it will always write it to the same cell.
If CheckBox1.Value = True Then
LastRow = ws.Range("B100").end(xlup).Row + 1
ws.Range("B" & LastRow).Value = "1"
End If
If CheckBox2.Value = True Then
LastRow = ws.Range("B100").end(xlup).Row + 1
ws.Range("B" & LastRow).Value = "2"
End If
If CheckBox3.Value = True Then
LastRow = ws.Range("B100").end(xlup).Row + 1
ws.Range("B" & LastRow).Value = "3"
End If
If CheckBox4.Value = True Then
LastRow = ws.Range("B100").end(xlup).Row + 1
ws.Range("B" & LastRow).Value = "4"
End If
You could also use and array to store the values and then paste the result of the array in the range.
there are many ways to do this but this one should work. You should always clean the range prior to paste the values.
hope this helps,
Private Sub CommandButton1_Click()
If Range("C4").Value <> "" & Range("D4").Value <> "" & Range("E4").Value <> "" & Range("F4").Value <> "" & Range("G4").Value <> "" & Range("H4").Value <> "" & Range("I4").Value <> "" Then
Set i = Sheets("Sheet2")
Set e = Sheets("Sheet3")
Dim d
Dim j
j = 3
Do Until IsEmpty(e.Range("C" & j))
If e.Range("C" & j, "F" & j) = i.Range("C4:F4") Then
If e.Range("G" & j) Is Nothing Then
e.Range("G" & j, "I" & j) = i.Range("G4:I4")
Else
End If
Else
i.Range("C4:I4").Copy
e.Range("C" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
j = j + 1
Loop
Else
End If
End Sub
Your Type Missmatch is because you are comparing Ranges with more than one cell like this:
If e.Range("C" & j, "F" & j) = i.Range("C4:F4") Then
VBA does not know what to answer as it does not know what do you expect to see, when you compare 4 cells with 4 cells.
In order to make something meaningful, you should implement a function, that compares the ranges. Something like this to get you started:
Public Function CompareRanges(rngA As Range, rngB As Range) As Boolean
If rngA.Count <> rngB.Count Then
CompareRanges = False
Exit Sub
Else
'loop through the cells of rngA and compare them with rngB
End If
End Function