excel VBA : how to skip blank cells between 2 cells that contain values? - vba

I am working out a button that can auto sum value at column C that column A = column B
like the picture :
PIC:
I can only copy the value in column C (that the word in column A = column B) to column E so far.
the code
Private Sub CommandButton2_Click()
Dim i As Integer, q As Integer
q = 2
For i = 3 To 100
Range("E" & q).Value = Range("b" & 3).Value
If Range("B" & i).Value = "A-RDL1" And Range("c" & i).Value = "OPEN" Then
Range("E" & i).Value = Range("d" & i).Value
End If
Next i
End Sub
the question 1) is how can I skip the blanks E9 to E17, so the numbers can be continuous? (AFTER CLICK THE BOTTON)
question 2) is it possible to auto sum the Numbers in column E instead of show each?
Thanks a lot and sorry for my poor English...

1) Yes, you can skip those, just carry out a check in the cell value and compare to empty string: Range("").Value2 = "". I personally prefer to do it like this though, to avoid false positives: Len(Trim(Range("").Value2)) = 0.
2) Yes, you can do that. just declare an Integer variable or two and use that to carry out a running count of your values.

Related

Search for value in column B, replace column D & E of that row

New to VBA so go easy on me.
I have a spreadsheet in the below format:
I require VBA that will search column B for the term "LBR-0001", then replace the contents of column D in that row with the value "25", and column E in that row with "AUD". The row containing "LBR-0001" will change so this cannot be hard coded to a particular row.
Currently I am using the code below but it is far too slow to complete since it searches up to 10,000 rows.
For i = 1 To 10000
With Sheets("LPP_Previous_Month")
If .Range("B" & i).Value = "LBR-0001" Then _
.Range("D" & i).Value = "25"
.Range("E" & i).Value = "AUD"
End With
Next i
Any improvements would be greatly appreciated.
Use the worksheet's Match function to quickly locate a matching row in column B. Use that row number to set the values in columns D and E.
dim m as variant
With Sheets("LPP_Previous_Month")
m = application.match("LBR-0001", .range("B:B"), 0)
if not iserror(m) then
.cells(m, "D") = 25
.cells(m, "E") = "AUD"
end if
End With
Use Application.Match (not worksheetfunction.match) and return the result to a variant. This is the only way to reliably test using IsError.

copy cell content based if adjacent cell meets criteria

I have a series of matrices consisting of 7 columns with a varied number of rows. I want the company names that are in column 2 of the matrix if the corresponding data in column 4 is "CM" aggregated into one cell per matrix (lets say B3:B98 for all the different matrices) with a space in between the different names. Please see the below picture for an example of what the matrices look like
The end result is that all the company names in Column E will be aggregated in B3 if the cell on the same row in column G is "CM", the next matrix beginning in Column M in B4 and so on.
I am having zero success in getting my if statement to recognize "CM" in the cell content, or aggregating the results using the Join statement. Any help is much appreciated.
Edits:
The objective is to have all the underwriters on a particular security aggregated in one cell, so that the cell can be easily searched in another part of the sheet for the presence of a particular underwriter.
The code below, as you can likely tell, does not work. I hit a wall as I could not get it to distinguish between cells that contained "CM" and those that did not. (I know that the code below would not aggregate the result in any cell, only copying the result into column B, as I said, it is a work in progress that has stalled.)
Dim Ws5 As Worksheet: Set Ws5 = Worksheets(5)
'turn off some Excel functionality so code runs faster
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
'Compiles the managers in the matrices into a column on the MgrMatrix sheet to be used
'for the entry sheet column of underwriters.
Dim CoL As Range: Set CoL = Ws5.Range("D3:K104")
Dim CeL As Range
For Each CeL In CoL.Columns(4)
If CeL.Text = "CM" Then
CeL.Offset(0, -5) = "CM"
Else
CeL.Offset(0, -5) = CeL.Offset(0, -2).Value
End If
Next
Edit: Using urdearboy's code, i modified it to work for multiple matrices on the same sheet in the below way. This version doesn't have the same finesse as his did, as this version relies on all matrices containing the same number of columns and not exceeding 100 rows.
For i = 7 To 857 Step 9
For y = 3 To 100
If Cells(y, i) = "CM" Then
s = s & Cells(y, i).Offset(0, -1).Value & " "
End If
Next y
If s = "" Then
s = "Sole Lead"
End If
Cells(Rows.Count, 2).End(xlUp).Offset(1, 0) = Trim(s)
s = ""
Next i
Paste code in VBE within Sheet 5 (Or whatever sheet you want to run this on).
The string, s, will build itself as it loops through your column checking for "CM" matches.
As is, the code will add commas between each new value added like, so, and, so, and then remove the last coma at the end before displaying the final string like, so, and, so
Option Explicit
Sub TextCM()
Dim i As Long, s As String
For i = 3 To Range("G" & Rows.Count).End(xlUp).Row
If Range("G" & i) = "CM" Then
s = s & Range("E" & i).Value & ", " 'Remove & ", " if you do not want the comma + space
End If
Next i
Range("B2") = Left(s, Len(s) - 2) 'Change to Range("B2") = s to not delete last character in string
End Sub
You should be able to figure out how to extend this to multiple tables (matrices?) no problem.

Print Value Based on Iteration and condition

I Want to Print Values from 1 to 10 or less in blank cells from range(A1:A10)
If we find any non blank cell in range(A1:A10) then we have to skip the cell and print the values without disturbing the series i.e, 1,2,3,A(non Blank Cell),4,5 etc
i tried
Dim i As Integer
For i = 1 To 10
If Sheets("Data").cell("K" & i).Value Is Nothing Then
Sheets("Data").Range("K" & i).Value = i
i = i + 1
End If
Next i
You would be best using a For Each loop and manually incrementing the i variable each time you do print a number, using the iterated cells row as the row to print the value of i to.
Dim i As Integer, c As Range
i = 1
For Each c In Range("A1:A10")
If Len(c.Value) = 0 Then
Sheets("Data").Range("K" & c.Row).Value = i
i = i + 1
End If
Next c
If Sheets("Data").cell("K" & i).Value Is Nothing Then
In your question text, you mention that the range is from A1:A10. In the code, you mention "K". Unless it's a typo, that may one of the reasons. In addition, replace the above if condition with :
If ((Sheets("Data").cell("K" & i).Value Is Nothing) Or (Trim(Sheets("Data").cell("K" & i).Value) = "")) Then

How do I conditionally format a column in VBA based on each cell's value and a fixed cell's value?

I need to set up conditional formatting for a column where each cell is highlighted based on two other values derived from cells within the spreadsheet. The values are dates. This needs to be done in VBA (for lots of reasons: the code works with other software and clears out contents, groups lines together, etc.). I have failed with many methods and am currently failing with the following:
Sheets("Trial").Activate
With ActiveSheet.Range("E:E")
.Select
.FormatConditions.Add Type:=xlCellValue, Operator:=xlBetween, Formula1:="="
& (Range("P1").Value - 1), Formula2:="=" & (Range("P1").Value + 6)
.FormatConditions(1).Interior.Color = RGB(255, 0, 0)
End With
Ultimately, I need cells in column E to turn red when the value is between P1-1 and P1+6. Even if I extract this code and run it by itself, I am getting a procedure call error. Thoughts?
Please try:
Sheets("Trial").Activate
With Columns("E:E")
.FormatConditions.Add Type:=xlExpression, Formula1:="=AND(E1>=$P$1-1,E1<=$P$1+6)"
.FormatConditions(1).Interior.Color = 255
End With
You don't even have to use conditional formatting if you don't want to. You could use a for loop to loop through all the values in column E. Take this as an example.
Dim TotalERows As Long
Dim EValue As Long
Dim LowerBound As Long
Dim UpperBound As Long
LowerBound = Worksheets("Sheet1").Range("P1").Value - 2
UpperBound = Worksheets("Sheet1").Range("P1").Value + 7
TotalERows = Worksheets("Sheet1").Range("E" & Rows.Count).End(xlUp).Row
For I = 1 To TotalERows
EValue = Range("E" & I).Value
If LowerBound < EValue And EValue < UpperBound Then
Range("E" & I).Interior.ColorIndex = 3
End If
Next I

Am I using the isnumeric function correctly?

This program is to convert a column of data from cumulative to non-cumulative. On my sheet I have A1, B1, and C1 with the text Non-Cumulative, Cumulative, and Converted, respectively. I have numbers 1 to 10 beneath A1, then them summed cumulatively beneath B1. C1 is where I want to convert column B back to non-cumulative.
The IsNumeric is used to make the first row of data in C equal to the first row of data in B. It should detect that the title is above the number it is evaluating, thus knowing that no calculations have to be performed. For the rest of them, it'll see that the number above the one it is evaluating is a number, and thus the calculation has to be done.
My problem is that it isn't working. I think the reason is because IsNumeric() keeps coming back as false. Is there a different function I should be using? Do cell references not work in IsNumeric?
Here's the program!
Option Explicit
Dim i As Variant
Sub Conversion()
Sheets("Test Sheet").Select
For i = 1 To 10
If IsNumeric("B" & i) = False Then
Range("C" & i + 1) = Range("B" & i + 1)
Else: Range("C" & i + 1) = Range("B" & i + 1) - Range("B" & i - 1)
End If
Next
End Sub
The way you wrote your code is logical, just a minor syntax changes you need initially. However,
It's also best to check if the range is empty first...
Then check on if the value is numeric.
Better even, if you set the Range into a Range object and use offset
Code:
Option Explicit '-- great that you use explicit declaration :)
Sub Conversion()
Dim i As Integer '-- integer is good enough
Dim rngRange as Range
'-- try not to select anything. And for a cleaner code
Set rngRange = Sheets("Test Sheet").Range("B1")
For i = 1 To 10
If (rangeRange.Offset(i,0).value) <> "" then '-- check for non-empty
If IsNumeric(rangeRange.Offset(i,0).value) = False Then
rangeRange.Offset(i+1,1) = rangeRange.Offset(i+1,0)
Else
rangeRange.Offset(i+1,1) = rangeRange.Offset(i+1,0) - rangeRange.Offset(i-1,0)
End If
End if
Next i '-- loop
End Sub
To make your code more dynamic:
Another suggestion, you may simply Application.WorkSheetFunction.Transpose() the entire B column range that you need to validate into a variant array
Process the array and Transpose back to the Range with column B and C.
By doing so, you may omit setting for loop size manually but setting it using Lower and Upper bound of the array ;)
You need to check if the range of B i is numeric, not the string "B" & i
and rather than selecting the sheet, simply using a parent identifier like:
sheets("sheet1").range("B" & i)
This will help you avoid errors in your code
For i = 1 To 10
If IsNumeric(sheets("test sheet").range("B" & i).value) = False Then
Range("C" & i + 1) = Range("B" & i + 1)
Else: Range("C" & i + 1) = Range("B" & i + 1) - Range("B" & i - 1)
End If
Next