How to use Target Address for multiple rows in VBA? - vba

Need your guidance on how If i can apply Target Address & its Value for multiple rows.
I am new to VBA, The below code is working for 1 Row as of now, but how can i can apply for multiple rows.
Let's say, In a range from B4 to B10, if i select B7, then C7 & D7 should give " Please Select"
As of now its working for row B4 row only.
How it can be used for multiple rows.
Could you please guide me on this.
VB Code
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$4" And Target.Value = "AA1" Then
Range("C4").Value = "Please Select"
Range("D4").Value = "Please Select"
ElseIf Target.Address = "$B$4" And Target.Value = "BB1" Then
Range("C4").Value = "Please Select"
Range("D4").Value = " "
ElseIf Target.Address = "$B$4" And Target.Value = "CC1" Then
Range("C4").Value = "Please Select"
Range("D4").Value = " "
ElseIf Target.Address = "$B$4" And Target.Value = "DD1" Then
Range("C4").Value = "Please Select"
Range("D4").Value = " "
ElseIf Target.Address = "$B$4" And Target.Value = "EE" Then
Range("C4").Value = "Please Select"
Range("D4").Value = " "
ElseIf Target.Address = "$B$4" And Target.Value = "" Then
Range("F4").Value = ""
Range("D4").Value = " "
End If
End Sub
Target Address & Conditional Data Validation

It's worth noting that Target may be a multi-cell range - it's not guaranteed to be a single cell - so you need to allow for that possibility in your code.
Select Case would be useful here:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, c As Range
Set rng = Application.Intersect(Target, Me.Range("B4:B10"))
If rng Is Nothing Then Exit Sub 'nothing to do...
'loop over any affected cells in the range of interest
For Each c In rng.Cells
Select Case c.Value
Case "AA1"
c.EntireRow.Columns("C").Resize(0, 2).Value = Array("Please Select", "Please Select")
Case "BB1", "CC1", "DD1", "EE"
c.EntireRow.Columns("C").Resize(0, 2).Value = Array("Please Select", " ")
Case ""
c.EntireRow.Columns("C").Resize(0, 2).Value = Array("", " ")
End Select
Next c
End Sub

Try
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Long
If Target.Row > 3 And Target.Column = 2 Then
r = Target.Row
If Target.Value = "AA1" Then
Range("C" & r).Value = "Please Select"
Range("D" & r).Value = "Please Select"
ElseIf Target.Value = "BB1" Then
Range("C" & r).Value = "Please Select"
Range("D" & r).Value = " "
ElseIf Target.Value = "CC1" Then
Range("C" & r).Value = "Please Select"
Range("D" & r).Value = " "
ElseIf Target.Value = "DD1" Then
Range("C" & r).Value = "Please Select"
Range("D" & r).Value = " "
ElseIf Target.Value = "EE" Then
Range("C" & r).Value = "Please Select"
Range("D" & r).Value = " "
ElseIf Target.Value = "" Then
Range("F" & r).Value = ""
Range("D" & r).Value = " "
End If
End If
End Sub

Related

Loop through different controls on a user form and read/write the value VBA

I would like to somehow get the value from the different controls on the user form and then write them on the sheet after that if the user form is closed down and re opened if a name is selected in the combobox then load all data in the form back ready to change values. I have 13 rows that a user can use on the user form.
In my code the writing the data to the sheet will write all item selected i want but it takes too long because all of the loops and ifs. Is there a better way to achieve what i want?
Private Sub FillingInForm()
Dim i As Long
Dim WS As Worksheet
Dim ctl As MSForms.Control
Dim lbl As MSForms.Label
Dim cmb As MSForms.ComboBox
Dim txtbox As MSForms.TextBox
Dim optbtn As MSForms.OptionButton
Set WS = ActiveSheet
With WS
For i = 1 To ItemsListFrame.Controls.Count
For Each ctl In ItemsListFrame.Controls
If TypeName(ctl) = "Label" Then
If ctl.Tag = "GroupItem" & i Then
Set lbl = ctl
If Controls("Item" & i).Value <> vbNullString Then
.Range("A" & i + 6).Offset(0, 0).Value = Me.OrderNo.Value
.Range("A" & i + 6).Offset(0, 1).Value = Me.NextCollectionDate.Text
.Range("A" & i + 6).Offset(0, 1).Value = Format(.Range("A" & i + 6).Offset(0, 1).Value, "dd/mm/yyyy")
.Range("A" & i + 6).Offset(0, 8).Value = Me.DateReturnBy.Value
.Range("A" & i + 6).Offset(0, 8).Value = Format(.Range("A" & i + 6).Offset(0, 8).Value, "dd/mm/yyyy")
Controls("OrderLbl" & i).Enabled = True
End If
End If
ElseIf TypeName(ctl) = "ComboBox" Then
If ctl.Tag = "GroupItem" & i Then
Set cmb = ctl
If Controls("Item" & i).Value <> vbNullString Then
Controls("Item" & i).Enabled = True
End If
If Controls("Item" & i).Value <> vbNullString Then
.Range("A" & i + 6).Offset(0, 2).Value = Controls("Item" & i).Text
End If
End If
ElseIf TypeName(ctl) = "TextBox" Then
If ctl.Tag = "GroupItem" & i Then
Set txtbox = ctl
If Controls("Item" & i).Value <> vbNullString Then
.Range("A" & i + 6).Offset(0, 3).Value = Controls("Qty" & i).Value
.Range("A" & i + 6).Offset(0, 4).Value = Controls("UnitPrice" & i).Value
.Range("A" & i + 6).Offset(0, 5).Value = Controls("SubTotal" & i).Value
.Range("A" & i + 6).Offset(0, 7).Value = Controls("Comments" & i).Value
Controls("Qty" & i).Enabled = True
Controls("UnitPrice" & i).Enabled = True
Controls("SubTotal" & i).Enabled = True
Controls("Comments" & i).Enabled = True
End If
End If
ElseIf TypeName(ctl) = "OptionButton" Then
If ctl.Tag = "GroupItem" & i Or ctl.Tag = "InOut" & i Then
Set optbtn = ctl
If Controls("Item" & i).Value <> vbNullString Then
.Range("A" & i + 6).Offset(0, 6).Value = Controls("OptionOut" & i).Value
Controls("OptionIn" & i).Enabled = True
Controls("OptionOut" & i).Enabled = True
End If
End If
End If
Next ctl
Next i
End With
End Sub

VBA Code for Multiple if conditions

I need to categorize my data into different buckets. my worksheet has column V & Column Y (actually a name match & address match respectively) has values that are either "ok" or "check". Column O has IDs, of which some are only numeric and some are alpha numeric.i need to fill my column A based on these 3 columns.
category 1 - Column A to be filled with "Verify name & Address" - logic for this is - If Column A is blank, Column V value = "check", Column Y value = "check" and column O = all alphanumeric IDs (except that starts with CWT) and numeric IDs = 2 & 9612
Category 2 - Column A to be filled with "Verify Address" - logic for this is - If Column A is blank, Column V value = "ok", Column Y value = "check" and column O = all alphanumeric IDs (except that starts with CWT) and numeric IDs = 2 & 9612.
Sub Rules()
'
'Autofill based on Rules
Worksheets("ORD_CS").Activate
Dim sht As Worksheet
Dim LR As Long
Dim i As Long
Set sht = ActiveWorkbook.Worksheets("ORD_CS")
LR = sht.UsedRange.Rows.Count
With sht
For i = 8 To LR
If .Range("A" & i).Value = "" And Range("V" & i).Value = "check" And Range("Y" & i).Value = "check" And Range("O" & i).Value = "2" And Range("O" & i).Value = "9612" Then
.Range("D" & i).Value = "Verify Name & Address"
End If
Next i
End With
End Sub
I have not completed my code. Can someone help? Thanks
The below should work, I changed your O column to be an OR
Edit: for function
Public Function IsAlpha(strValue As String) As Boolean
Dim intPos As Integer
For intPos = 1 To Len(strValue)
Select Case Asc(Mid(strValue, intPos, 1))
Case 65 To 90, 97 To 122
IsAlpha = True
Case Else
IsAlpha = False
Exit For
End Select
Next
End Function
With sht
For i = 8 To LR
If .Range("A" & i).Value = "" And Range("V" & i).Value = "check" And Range("Y" & i).Value = "check" And Range("O" & i).Value = "2" Or Range("O" & i).Value = "9612" Or IsAlpha(Range("O" & i).Value) = True Then
.Range("D" & i).Value = "Verify Name & Address"
Else
If .Range("A" & i).Value = "" AND .Range("V" & i).Value = "ok" AND .Range("O" & i).Value = "2" Or .Range("O" & i).Value = "9612" Then
Do Stuff
End If
End If
Next i
End With

how to lock in between rows in excel vba

I want to lock the in between row's of excel sheet depending the value of the two column's ,
I have following code with me but it's makes entire sheet protected.
the code is :
there is another problem when the loop goes to else part it throws "unable to set Locked property of the range class" the code is :
Do While xlsht.Cells(i, 1) <> vbNullString
If (CStr(xlsht.Cells(i, 54).Value) <> "" And (CStr(Format(xlsht.Cells(i, 55).Value, "dd-MMM-yyyy")) = CStr(Format(Now, "dd-MMM-yyyy")))) Then
.Cells.Locked = False
.Range("A" & i & " : " & "BH" & i).Cells.Locked = True
.Range("A" & i & " : " & "BH" & i).Interior.Color = RGB(255, 255, 0)
.Protect Password:=admin
Else
.Cells.Locked = False
.Range("A" & i & " : " & "AC" & i).Cells.Locked = True
.Range("AE" & i & " : " & "AT" & i).Cells.Locked = True
.Range("BB" & i & " : " & "BH" & i).Cells.Locked = True
.Protect Password:=admin
End If
i = i + 1
Loop
End With
you may be after something like this:
Dim i As Long
i = 1
With Worksheets("mySheetName") '<--| change "mySheetName" to your actual sheet name
Do While .Cells(i, 1) <> ""
If (.Cells(i, 54).Value = "abc" And .Cells(i, 55).Value = "def") Then Intersect(.Range("A:BH"), .Rows(i)).Locked = True
i = i + 1
Loop
.Protect Password:="admin"
End With
By default, the entire sheet is Locked (property of a Range or Cell).
And you can only Protect an ENTIRE sheet.
So you'll have to unLock the rest of the sheet first!
i = 1
With xlsht
.Unprotect Password:=admin
.Cells.Locked = False
Do While xlsht(i, 1) <> vbNullString
If .Cells(i, 54).Values = "abc" And .Cells(i, 55).Values = "def" Then
'here is checking the column depends the row is get lock or not
.Range("A" & i & ":BH" & i).Cells.Locked = True
i = i + 1
End If
Loop
.Protect Password:=admin
End With 'xlsht
Second question
i = 1
With xlsht
.Unprotect Password:=admin
.Cells.Locked = False
Do While .Cells(i, 1).Value <> vbNullString
If CStr(.Cells(i, 54).Value) <> vbNullString And CDate(.Cells(i, 55).Value) = Date Then
With .Range("A" & i & ":BH" & i)
.Cells.Locked = True
.Interior.Color = RGB(255, 255, 0)
End With '.Range("A" & i & ":BH" & i)
Else
.Range("A" & i & ":AC" & i).Cells.Locked = True
.Range("AE" & i & ":AT" & i).Cells.Locked = True
.Range("BB" & i & ":BH" & i).Cells.Locked = True
End If
i = i + 1
Loop
.Protect Password:=admin
End With 'xlsht

Delete empty rows using VBA - MS Excel

I am looking to see if there is a more efficient way to achieve the result below, so it can be extended if needed.
I'm using this to clean up large spreadsheets that have the rows C-Z blank. I imagine there should be a way to clean it up so that it doesn't have to double in size if I need to clean up a spreadsheet with data from C to AZ.
It's been a while since I used VBA, I found the code below online. (counting ROW B as the spreadsheet in question had an empty ROW A)
Sub delem()
Dim lr As Long, r As Long
lr = Cells(Rows.Count, "B").End(xlUp).Row
For r = lr To 1 Step -1
If Range("C" & r).Value = "" And Range("D" & r).Value = "" And Range("E" & r).Value = "" And Range("F" & r).Value = "" And Range("G" & r).Value = "" And Range("H" & r).Value = "" And Range("I" & r).Value = "" And Range("J" & r).Value = "" And Range("K" & r).Value = "" And Range("L" & r).Value = "" And Range("M" & r).Value = "" And Range("N" & r).Value = "" And Range("O" & r).Value = "" And Range("P" & r).Value = "" And Range("Q" & r).Value = "" And Range("R" & r).Value = "" And Range("S" & r).Value = "" And Range("T" & r).Value = "" And Range("U" & r).Value = "" And Range("V" & r).Value = "" And Range("W" & r).Value = "" And Range("X" & r).Value = "" And Range("Y" & r).Value = "" And Range("Z" & r).Value = "" Then Rows(r).Delete
Next r
End Sub
Thanks!
Just add an inner loop to go through the columns you care about. This will actually run much faster, as VBA doesn't short-circuit the If statement (all of the conditionals are evaluated). But with the loop, you can exit early if you find a value anywhere:
Sub delem()
Dim last As Long
Dim current As Long
Dim col As Long
Dim retain As Boolean
last = Cells(Rows.Count, "B").End(xlUp).Row
For current = last To 1 Step -1
retain = False
For col = 3 To 26
If Cells(current, col).Value <> vbNullString Then
retain = True
Exit For
End If
Next col
If Not retain Then Rows(current).Delete
Next current
End Sub
The Excel worksheet function COUNTA is a clean way to test if a range is empty.
Sub delem()
Dim lr As Long, r As Long
lr = Cells(Rows.Count, "B").End(xlUp).Row
For r = lr To 1 Step -1
'This function Counts the number of cells that are not empty
If WorksheetFunction.CountA(Range(Cells(r, 3), Cells(r, 26)) = 0 Then
Rows(r).Delete
End If
Next r
End Sub

Compile error. Argument not optional

I'm sure you will find the problem that I'm uncapable to do.
Below you can see a resume of the code in which I have the problem.
After changing the value in the combobox1 it shows an error "Compile error. Argument not optional", highlighting in yellow "Sub ComboBox1_Change()" and in blue "Call TextBox4_Exit".
I think I'm doing something wrong with the arguments needed but don't know how to handle.
Thank you for your help.
Sub ComboBox1_Change()
If TextBox4.Visible = True And TextBox4.Value <> "" Then
Call TextBox4_Exit
End If
Sub TextBox4_Exit(ByVal cancel As MSForms.ReturnBoolean)
Dim placas As String
placas = TextBox4.Value
I = 3
While Range("E" & I).Value <> ""
If Range("E" & I).Value = mensaje Then
If Range("L" & I).Value = mensaje2 Then
If sheet1 = "SIC" Then
Range("X" & I).Value = placas
TextBox11.Value = Range("Y" & I).Value
TextBox10.Value = Range("Z" & I).Value
Else
Range("U" & I).Value = placas
TextBox11.Value = Range("AN" & I).Value
End If
End If
End If
I = I + 1
Wend
End Sub
First, the Sub TextBox4_Exit(ByVal cancel As MSForms.ReturnBoolean) has one argument and it's not marked as Optional,so you need to pass a parameter to Call TextBox4_Exit.
Second, did you miss your End Sub of ComboBox1_Change()?