Applying VBA the same rule to several rows - excel

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

Related

Excel, how to add IF into a loop

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.

Automatically Populate a result from each cell in Column "B" using vlookup formula

I am new in VBA, please help me to create a code based on the lookup value in column "B" and it will generate automatically a result in Column C, and Column H (Please see screenshot below).
Please help me correct my code (below):
Private Sub CommandButton4_Click()
If Sheet1.Range("B13") = "" Is Nothing Then Application.WorksheetFunction.VLookup(Sheet1.Range("B13"),Sheet4.Range("''''A4:D120000"),3,0)
End If
End Sub
Write the formula to the cell rather than the value.
Private Sub CommandButton4_Click()
Const COL_DESCR = 3 ' lookup
Const COL_PRICE = 4
Dim descr As String, price As String, tbl As String, i As Long
tbl = "'" & Sheet4.Name & "'!R1C1:R120000C4"
descr = "=IF(RC[-1]="""","""",VLOOKUP(RC[-1]," & tbl & "," & COL_DESCR & ", 0))"
price = "=IF(RC[-6]="""","""",VLOOKUP(RC[-6]," & tbl & "," & COL_PRICE & ", 0))"
i = 13
With Sheet1
.Range("C" & i).FormulaR1C1 = descr
.Range("H" & i).FormulaR1C1 = price
End With
End Sub
or the values using Application.Match
Private Sub CommandButton4_Click()
Dim r, i As Long, rngLU As Range
Dim price, descr As String
i = 13
Set rngLU = Sheet4.Range("A4:A120000")
With Sheet1
If .Range("B" & i).Value2 <> "" Then
r = Application.Match(.Range("B" & i).Value2, rngLU, 0)
If IsError(r) Then
descr = "#N/A"
price = "#N/A"
Else
descr = rngLU.Cells(r, 3) ' col C
price = rngLU.Cells(r, 4) ' col D
End If
End If
.Cells(i, "C") = descr
.Cells(i, "H") = price
End With
End Sub

UserForm check the existing list before creating new data VBA

I want to create a userform with inputs: Name (TextBox1), Surname (TextBox2), Date of birth (TextBox3) and 1 output which would basically be their ID (goes from 1 to inf). What bothers me is that I want to code that if lets say Name and Surname already exists in database, msg will popup and form will reset else everything will be put to the table. I kind of managed to do that. Problem is now if I do put name and surname that already exists it wont input it in the table and it will show the message, but even if it doesn't exists the message will still pop up but it will input it in the table. This is the code:
Private Sub CommandButton1_Click()
Dim iRow As Long
Dim ws As Worksheet
Set ws = Sheet2
Dim a As Integer
Application.ScreenUpdating = False
iRow = ws.Range("A1048576").End(xlUp).Row + 1
If Not (TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "") Then
With ws
Label1.Caption = iRow - 1
For a = 1 To iRow
If (ws.Cells(a, 2).Value = TextBox1.Value And ws.Cells(a, 3).Value = TextBox2.Value) Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End If
Next a
End With
End If
Application.ScreenUpdating = True
End Sub
The problem is you are checking down to the row where the new record is inserted. So for every row that does not match the new record is inserted at iRow. When the loop gets to the end it checks iRow, matches and shows the message. Separate code into 2 steps, first check then update or reset.
Private Sub CommandButton1_Click()
If TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "" Then
Exit Sub
End If
Dim ws As Worksheet
Dim iRow As Long, r As Long, bExists As Boolean
Set ws = Sheet2
iRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' check exists
For r = 1 To iRow
If (ws.Cells(r, 2).Value = TextBox1.Value) _
And (ws.Cells(r, 3).Value = TextBox2.Value) Then
bExists = True
Exit For
End If
Next
' update sheet
If bExists Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
Label1.Caption = iRow
iRow = iRow + 1
With ws
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End With
End If
End Sub

VBA Search row changed and code needs update

Below is a code that I am now using to automatically insert numbers to a cell that has todays date on Column A and the correct name on the first row of that column.
However, I can't seem to make it work if the names are in any other row than 1.
What changes do I need to make if I want it to search matches on row 2 or multiple rows?
Sub SyöttöEriVälilehti()
Application.ScreenUpdating = False
On Error GoTo M
Dim i As Long
Dim Lastrow As Long
Dim col As Long
col = 0
Dim LastColumn As Long
Dim DateLastrow As Long
Dim ans As String
Dim LString As String
Dim LArray() As String
Dim anss As String
Dim ansss As String
With Sheets("Malli2Data") ' Sheet name
DateLastrow = .Cells(Rows.Count, "A").End(xlUp).Row
Set SearchRange = .Range("A1:A" & DateLastrow).Find(Date)
If SearchRange Is Nothing Then MsgBox Date & " No matches", , "Oops!": Exit Sub
Lastrow = SearchRange.Row
LastColumn = .Cells(1, Columns.Count).End(xlToLeft).Column
ans = InputBox("Input name and number like so: Tom,5")
LString = ans
LArray = Split(LString, ",")
anss = LArray(0)
ansss = LArray(1)
For i = 2 To LastColumn
If .Cells(1, i).Value = anss Then col = Cells(1, i).Column
Next
If col = 0 Then MsgBox anss & " No matches": Exit Sub
.Cells(Lastrow, col).Value = ansss
End With
Application.ScreenUpdating = True
Exit Sub
M:
MsgBox "Error" & vbNewLine _
& "Check input" & _
vbNewLine & "You typedt: " & ans & vbNewLine & "Correct input type: " & vbNewLine & "Name" & ",Number" & _
vbNewLine & vbNewLine & "Try again"
End Sub
The snippet:
For i = 2 To LastColumn
If .Cells(1, i).Value = CDec(anss) Then col = Cells(1, i).Column
Next
Is searching row 1 for your name
If you want to change it and make it a variable, something like
For i = 2 To LastColumn
If .Cells(xRow, i).Value = CDec(anss) Then col = Cells(1, i).Column
Next
With xRow being your defined row to search will work.
At the same time, you could sub out the last bit within the loop and use
For i = 2 To LastColumn
If .Cells(xRow, i).Value = CDec(anss) Then col = i
Next
As they are the same thing.
edit 20201-04-23A: Use of CDec(anss) will convert the string (as gathered from "ans") into a decimal number - which can then be compared against the .Value taken out of the cell.

How to use ListIndex to find row of Combobox value?

I'm trying to set a "Make Changes" button for my userform that changes the appropriate record in the spreadsheet according to any changes made in the userform.
The userform populates according to the selection made on "BusCombo".
I'm trying to set n to the row of the "BusCombo" selection. I found a suggestion to use ListIndex. I can't find information on how ListIndex works.
Private Sub MkChgButton_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Customers")
Dim n
With Me.BusCombo
n = .ListIndex
End With
''''''submit changes
sh.Range("A" & n).Value = Me.BusCombo.Value
sh.Range("B" & n).Value = Me.ServFreqCombo.Value
sh.Range("K" & n).Value = Me.TimeText.Value
sh.Range("C" & n).Value = Me.RateText.Value
sh.Range("D" & n).Value = Me.PayFormCombo.Value
sh.Range("E" & n).Value = Me.PayFreqCombo.Value
sh.Range("F" & n).Value = Me.DayText.Value
sh.Range("G" & n).Value = Me.StartText.Value
sh.Range("H" & n).Value = Me.PayDateText.Value
sh.Range("I" & n).Value = Me.EmpCombo.Value
End Sub
Here's a little demo that shows you how to search through the List items in the Combobox:
Option Explicit
Private Sub UserForm_Initialize()
' add items to the combobox
With ComboBox1
.AddItem ("stuff1")
.List(0, 1) = "test1"
.AddItem ("stuff2")
.List(1, 1) = "test2"
.AddItem ("stuff3")
.List(2, 1) = "test3"
End With
End Sub
Private Sub CommandButton1_Click()
Dim i As Integer
Dim SearchString As String
SearchString = "test3"
' loop through all the items, looking in the 2nd column (column index=1)
For i = 0 To ComboBox1.ListCount - 1
If ComboBox1.List(i, 1) = SearchString Then
MsgBox ("Found it at row index " & i)
Exit Sub
End If
Next
MsgBox SearchString & " not found"
End Sub

Resources