How to check if empty cell in a range? - excel

I just want to check if there are empty rows in a range, for instance, if S28 is either "KO" or "OK", the line above (offset(-1,0) should not be blank.
If it is blank the function should stop.
If a cell is blank and the cell above is blank, that is ok.
Each cell in S has a formula, countif function.
The code says that there are empty rows, which is not the case. I removed the data in S28, which you can see on the picture. Hence, there should be no msgbox. The first line check is in S12.
Private Function detecht_empty_rows() As Boolean
Call DefineVariables
Dim lrowS As Long
Dim cell As Range
Dim startingcell As String
lrowS = shInput.cells(Rows.Count, 19).End(xlUp).Row
For Each cell In shInput.Range("S13" & ":" & "S" & lrowS)
startingcell = cell.Address
If cell.Text = "" And IsEmpty(cell.Offset(-1, 0)) = True Then
ElseIf cell.Text = "OK" Or cell.Text = "KO" And IsEmpty(cell.Offset(-1, 0)) = True Then
MsgBox "Please remove the blank rows"
Exit Function
End If
Next cell
End Function

Please, test the next adapted function. I assume that DefineVariables defines the shInput worksheet. My code, for testing reasons, defines the sheet in discussion as the active one. You can delete/comment the declaration and the value allocation:
Private Function detecht_empty_rows() As Boolean
'Call DefineVariables
Dim lrowS As Long, cell As Range, startingcell As String
Dim shInput As Worksheet, boolEmpty As Boolean, rowNo As Long
Set shInput = ActiveSheet 'use here your defined worksheet.
'Clear the declaration if declared at the module level
lrowS = shInput.cells(rows.count, 19).End(xlUp).row
'new inserted code line:________________________________
lrowS = lastR(shInput.range("S13" & ":" & "S" & lrowS))
'_______________________________________________________
For Each cell In shInput.Range("S13" & ":" & "S" & lrowS)
If cell.text = "" And cell.Offset(-1, 0) = "" Then
boolEmpty = True: rowNo = cell.Offset(-1).row: Exit For
ElseIf (cell.text = "OK" Or cell.text = "KO") And cell.Offset(-1, 0) = "" Then
boolEmpty = True: rowNo = cell.Offset(-1).row: Exit For
End If
Next cell
If boolEmpty Then MsgBox "Please remove the blank row (" & rowNo & ").": detecht_empty_rows = False: Exit Function
detect_empty_rows = True
End Function
The next function will calculate the last row to be processed in a different way:
Function lastR(rng As range) As Long
Dim i As Long, lngStart As Long, lngEnd As Long, sh As Worksheet
lngStart = rng.cells(1).Row: lngEnd = lngStart + rng.Rows.Count - 1
Set sh = rng.Parent
For i = lngStart To lngEnd
If WorksheetFunction.CountIf(sh.range(sh.range("S" & i), sh.range("S" & lngEnd)), "OK") + _
WorksheetFunction.CountIf(sh.range(sh.range("S" & i), sh.range("S" & lngEnd)), "KO") = 0 Then
lastR = i - 1: Exit Function
End If
Next i
End Function
You must change
ElseIf cell.text = "OK" Or cell.text = "KO" And IsEmpty(cell.Offset(-1, 0))
with
ElseIf (cell.text = "OK" Or cell.text = "KO") And cell.Offset(-1, 0) = ""
The Or conditions must be checked like a single check toghether with IsEmpty part.
Then, startingcell = cell.Address is useless and unused, it takes a new value for each iteration.
Not necessarily to use IsEmpty(cell.Offset(-1, 0)) = True. It is enough to use IsEmpty(cell.Offset(-1, 0)).The method returns a Boolean variable, anyhow.
Being a function returning a Boolean, it should return it. It can be used in the code calling the function.
But in case of a formula, even if it returns a null string (""), IsEmpty cannot be used. I mean, it does not work, the cell no being empty. The code must use cell.Offset(-1, 0) = "".
Please, take care to not have an empty cell at "S12"...

Related

How can you extract characters from a cell, that have a specific property (like underlined)? [duplicate]

I have an Excel cell with text. Some words are bolded. Those words are keywords and should be extracted to another cell in the row for identification of the keywords.
Example:
Text in Cell:
I want to use Google Maps for route informations
Output:
Google; Maps; route;
You can also use this UDF to produce same result. Please enter below code in module.
Public Function findAllBold(ByVal rngText As Range) As String
Dim theCell As Range
Set theCell = rngText.Cells(1, 1)
For i = 1 To Len(theCell.Value)
If theCell.Characters(i, 1).Font.Bold = True Then
If theCell.Characters(i + 1, 1).Text = " " Then
theChar = theCell.Characters(i, 1).Text & ", "
Else
theChar = theCell.Characters(i, 1).Text
End If
Results = Results & theChar
End If
Next i
findAllBold = Results
End Function
Now you can use newly created function to return bold values from any cell.
Try this
Option Explicit
Sub Demo()
Dim ws As Worksheet
Dim str As String, strBold As String
Dim isBold As Boolean
Dim cel As Range
Dim lastRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet1") 'change Sheet1 to your data sheet
isBold = False
With ws
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row 'last row with data in Column A
For Each cel In .Range("A1:A" & lastRow).Cells 'loop through each cell in Column A
strBold = ""
For i = 1 To Len(cel.Value)
If cel.Characters(Start:=i, Length:=1).Font.Bold = True Then 'check if character is bold
isBold = True
str = Mid(cel.Value, i, 1)
If cel.Characters(Start:=i, Length:=1).Text = " " Then 'check for space
strBold = strBold & "; "
isBold = False
Else
strBold = strBold & str
End If
Else
If isBold Then
strBold = strBold & "; "
isBold = False
End If
End If
Next
cel.Offset(0, 1) = strBold
Next
End With
End Sub
Derived this code from here.

How to loop through multiple cell values on VBA?

I'm trying to simplify the following code into one loop only. How can I do that?
Dim VARIANTE as LONG
For Each cell In Sheets("Libro2").Range("C1:C30000")
If cell.Value = Sheets("Libro1").Range("AA1") Then
VARIANTE = cell.Row
Sheets("Libro2").Range("Z" & VARIANTE) = 1
End If
Next
For Each cell In Sheets("Libro2").Range("C1:C30000")
If cell.Value = Sheets("Libro1").Range("AA2") Then
VARIANTE = cell.Row
Sheets("Libro2").Range("Z" & VARIANTE) = 1
End If
Next
For Each cell In Sheets("Libro2").Range("C1:C30000")
If cell.Value = Sheets("Libro1").Range("AA3") Then
VARIANTE = cell.Row
Sheets("Libro2").Range("Z" & VARIANTE) = 1
End If
Next
[...] 'and so on, and so forth
Here is something I've tried, but it didn't work, of course. Maybe there is a solution out there, but I couldn't find it because of language issues.
For Each cell In Sheets("Libro2").Range("C1:C30000")
If cell.Value = Sheets("Libro1").Range("AA1:AA50") Then
VARIANTE = cell.Row
Sheets("Libro2").Range("Z" & VARIANTE) = 1
End If
Next
Please, try the next code:
Sub testLoopCols()
Dim sh As Worksheet, shL As Worksheet, rngAA As Range, arrC, arrZ, i As Long, mtch
Set sh = ActiveSheet 'use here the sheet you need
Set shL = Sheets("Libro1")
arrC = sh.Range("C1:C30000").value 'place the range in an array for faster iteration
arrZ = sh.Range("Z1:Z30000").value 'place the range to return (using an array)
Set rngAA = shL.Range("AA1:AA50") 'the range where to match each cell of C:C range
For i = 1 To UBound(arrC)
mtch = Application.match(arrC(i, 1), rngAA, 0) 'match in a range = much faster than in an array...
If Not IsError(mtch) Then 'if a match exists:
arrZ(i, 1) = 1 'place 1 in the final array
End If
Next i
'drop the processed array result, at once:
sh.Range("Z1:Z30000").value = arrZ
MsgBox "Ready..."
End Sub
This solution is what so brilliantly BigBen, in only one sentence, answered my question inmediately, and which I'm enterily grateful.
For Each cell In Sheets("Libro2").Range("C1:C30000")
If WorksheetFunction.CountIf(Sheets("concat").Range("AD20951:AD20956"), cell.Value) > 0 Then
VARIANTE = cell.Row
Sheets("Libro2").Range("Z" & VARIANTE) = 1
End If
Next

InStr in Array not populating value if found

I've written the below code to search for a value(Supplier Name) in sheet "Fusion" Column H in sheet "CX" column D. I'm also doing a check the other way around so if the same value(Supplier Name) in sheet CX is in sheet "Fusion". I'm not looking for an Exact match hence the use of Instr and doing the comparison both ways as i'm not sure how a user has entered the information in either sheet.
The data type in either cell should be text.
If a match is found then in the last column of sheet "CX" it should just populate either "Supplier Found" or "Supplier Not Found"
Currently it's not populating the last column with any data but the Macro isn't erroring at any point.
I've tried adding msgboxes and "Here" and "Here3" are being triggered but it doesn't seem to be hitting the section of code that is "Here2" so I think it's there that's causing the issue but not sure how to resolve it.
Screenshot of my Data is :CX Sheet
Fusion Sheet
Any help would be greatly appreciated.
Option Explicit
Sub CompareCXFusion()
Dim CX As Worksheet
Dim Fusion As Worksheet
Dim strTemp as string
Dim strCheck as string
Dim i As Long, J As Long
Dim CXArr As Variant
Dim FusionArr As Variant
Dim match As Boolean
Dim CXRng As Range
Dim FusionRng As Range
Set CX = ActiveWorkbook.Sheets("CX")
Set Fusion = ActiveWorkbook.Sheets("Fusion")
Set CXRng = CX.Range("A2", CX.Cells(Rows.Count, "A").End(xlUp).Offset(0, 6))
Set FusionRng = Fusion.Range("A2", Fusion.Cells(Rows.Count, "A").End(xlUp).Offset(0, 9))
CXArr = CXRng.Value2
FusionArr = FusionRng.Value2
strTemp = lcase(trim(FusionArr(J, 7)))
strCheck = lcase(trim(CXArr(i, 3)))
For i = 1 To UBound(CXArr)
Match = False
For J = 1 To UBound(FusionArr)
MsgBox "Here"
If (Instr(strTemp, strCheck) > 0) OR (InStr(strCheck, strTemp) > 0) Then
MsgBox"Here2"
CXArr(i, 6) = "Supplier Found"
Else
Msgbox"Here3"
CXArr(i, 6) = "Supplier not found"
End If
Next J
Next i
End Sub
The expected output i'd expect is: If in Column H of Fusion the Supplier Name is "Supplier A" and the value in Column D of sheet "CX" is "Supplier A LTD" then i'd expect it to populate column G in sheet CX with "Supplier Found" due to it being found in the string.
If you need any more info please let me know.
I don't know how to correctly insert examples of my data else I would have
Option Explicit
Sub CompareCXFusion()
Dim CX As Worksheet
Dim Fusion As Worksheet
Dim i As Long, J As Long, lastRowCX As Long, lastRowFU As Long
Dim CXText As String, FusionText As String
Dim match As Boolean
Dim CXRng As Range, FusionRng As Range
Set CX = ActiveWorkbook.Sheets("CX")
Set Fusion = ActiveWorkbook.Sheets("Fusion")
lastRowCX = CX.Range("D1").SpecialCells(xlCellTypeLastCell).Row - 1
lastRowFU = Fusion.Range("H1").SpecialCells(xlCellTypeLastCell).Row - 1
Set CXRng = CX.Range("D1:D" & lastRowCX)
Set FusionRng = Fusion.Range("H1:H" & lastRowFU)
For i = 1 To lastRowCX
match = False
For J = 1 To lastRowFU
'Debug.Print "Here"
FusionText = FusionRng.Range("A1").Offset(J, 0).Value
CXText = CXRng.Range("A1").Offset(i, 0).Value
If FusionText <> "" And CXText <> "" Then
If InStr(FusionText, CXText) Or InStr(CXText, FusionText) Then
'Debug.Print "Here2"
match = True
End If
End If
Next J
'Result goes to column G of CX range:
If match Then
CXRng.Range("A1").Offset(i, 3).Value = "Supplier found" ' "Supplier found - " & i & " - " & CXRng.Range("A1").Offset(i, 0).Address & " - " & CXRng.Range("A1").Offset(i, 3).Address
Else
CXRng.Range("A1").Offset(i, 3).Value = "Supplier NOT found" '"Supplier NOT found - " & i & " - " & CXRng.Range("A1").Offset(i, 0).Address & " - " & CXRng.Range("A1").Offset(i, 3).Address
End If
Next i
End Sub
You need to make sure to check for case sensitivity:
Dim strTemp as string
Dim strCheck as string
'Inside for I loop
'Inside for j Loop
strTemp = lcase(trim(FusionArr(J, 7)))
strCheck = lcase(trim(CXArr(i, 3)))
If (Instr(strTemp, strCheck) > 0) OR (InStr(strCheck, strTemp) > 0) Then
'...
End If
'end for j
'end for i

VBA Excel: How to put a value into a cell using two variable as its location

I am trying to take variant 'row' and 'column' and use them to input an "x" into the cell. 'row' and 'column' have numbers stored in them.
Private Sub CheckInButton_Click()
Dim found_name As Range
Dim name_to_find As String
Dim row As Variant
Dim column As Variant
Dim ColLetter As Variant
Dim xLocation As Excel.Range
row = 0
column = 0
name_to_find = Worksheets("Forms").Range("N5").Value
Set found_name = Worksheets("Updated 1.0").Range("A:A").Find(what:=name_to_find,LookIn:=xlValues, lookat:=xlWhole)
If Not found_name Is Nothing Then
MsgBox (name_to_find & " found in row: " & found_name.row)
row = found_name.row
MsgBox (row)
Else
MsgBox (name_to_find & " not found")
End If
event_to_find = Worksheets("Forms").Range("N3").Value
Set found_event = Worksheets("Updated 1.0").Range("A1:DZ1").Find(what:=event_to_find, LookIn:=xlValues, lookat:=xlWhole)
MsgBox (found_event)
If Not found_event Is Nothing Then
ColLetter = Split(found_event.Address, "$")(1)
MsgBox (event_to_find & " found in column: " & ColLetter)
column = found_event.column
MsgBox (column)
Else
MsgBox (event_to_find & " not found")
End If
Worksheets("Updated 1.0").Cells(column & row).Value2 = "x"
End Sub
You can just use Cells().
Cells(row, column).Value = "X"
So, in your case:
Worksheets("Updated 1.0").Cells(row, column).Value = "x"
.Cells takes two arguments, the row and the column. The & operator concatenates two values, so you're just giving .Cells one argument, the row appended to the column.
Just change Worksheets("Updated 1.0").Cells(column & row).Value2 = "x" to Worksheets("Updated 1.0").Cells(row, column).Value2 = "x"

Increase cell value that contains number and text VBA

I have tried this code which works fine for a cell that only contain number:
Sub IncreaseCellValue()
'Add 1 to the existing cell value
Range("A1").Value = Range("A1") + 1
End Sub
How can I do something similar if the cell has text and a number. For example, I have "Apple 1" and I want to "increase" the cell text to "Apple 2" and next time I run the macro I want "Apple 3".
Here's another way you could solve this problem:
Sub IncreaseCellValue()
Dim value As Variant
'Add 1 to the existing cell value
If IsNumeric(Range("A1").value) Then
Range("A1").value = Range("A1") + 1
Else
value = Split(Range("A1").value, " ")
Range("A1").value = value(0) & " " & (CInt(value(1)) + 1)
End If
End Sub
It will cover the 2 cases you presented in your question but not every scenario you could throw at it.
Try using the following function
Sub IncreaseCellValue()
'Add 1 to the existing cell value
Range("A1").Value = Replace(Range("A1").Value2, CleanString(Range("A1")), vbNullString) & CInt(CleanString(Range("A1").Value2)) + 1
End Sub
Function CleanString(strIn As String) As String
Dim objRegex
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Global = True
.Pattern = "[^\d]+"
CleanString = .Replace(strIn, vbNullString)
End With
End Function
please check:
Option Explicit
Sub IncreaseCellValue()
'Add 1 to the existing cell value
Dim rg As Range
Set rg = Cells(Rows.Count, "A").End(xlUp)
Range("A1" & ":" & rg.Address).AutoFill Destination:=Range("A1" & ":" & rg.Offset(1, 0).Address), Type:=xlFillDefault
End Sub
Or you may try something like this...
Function GetNumber(ByVal rng As Range) As Long
Dim i As Long
For i = Len(rng.Value) To 1 Step -1
If IsNumeric(Mid(rng.Value, i, 1)) Then
GetNumber = GetNumber & Mid(rng.Value, i, 1)
Else
Exit For
End If
Next i
End Function
Sub IncrementNumber()
Dim num As Long
num = GetNumber(Range("A1"))
Range("A1").Value = Replace(Range("A1").Value, num, num + 1)
End Sub

Resources