VBA isEmpty() - Check if cells are empty and tell me which ones - excel

Apologies if this has been answered already, I did search and can't seem to find an answer:
How could I change the code below to check for empty cells across two sheets and not in a continuous range and to tell me which cells are blank.
The range will be sheet "Request" Range, B5,B6,B7,b10,b11 & sheet "Data" Range A8, B8, D8,
Is it possible for the code to tell me the adjacent Cell name so can find it and put a value in, for example B5, A5 is called "request name" so I'd need to highlight to the user request name is blank for them to go and put a value and so on for the other cells.
Sub check_empty()
Dim i As Long
Dim c As Long
Dim myRange As Range
Dim myCell As Range
Set myRange = Sheets("Request").Range("B5:B8")
For Each myCell In myRange
c = c + 1
If IsEmpty(myCell) Then
i = i + 1
End If
Next myCell
MsgBox _
"There are total " & i & " empty cell(s) out of " & c & "."
End Sub

Is it correct the range for sheet "Data"?
Cause Range A8 won't have a named range adjacent to it, and B8 would have A8 as its named range... anyway, here's what I came up with:
Sub check_empty()
Dim c As Integer
Dim i As Integer
Dim sReport As String
Dim rResults() As String
c = 0
i = 0
Call loop_check_empty("Request", "B5:B7,B10:B11", rResults, c, i)
Call loop_check_empty("Data", "A8,B8,D8", rResults, c, i)
sReport = Join(rResults, vbCr)
MsgBox "There are total " & i & " empty cell(s) out of " & c & "." & vbCr & sReport
End Sub
Sub loop_check_empty(ByVal sSheet As String, ByVal sRange As String, ByRef rResults() As String, ByRef c As Integer, ByRef i As Integer)
Dim myCell, myRange As Range
Dim sColumn, sRow As String
Set myRange = Sheets(sSheet).Range(sRange)
For Each myCell In myRange
c = c + 1
If IsEmpty(myCell) Then
i = i + 1
ReDim Preserve rResults(1 To i)
sColumn = Mid(myCell.Address, 2, 1)
sRow = Mid(myCell.Address, 4, Len(myCell.Address))
Sheets(sSheet).Range(sColumn & sRow).Interior.Color = vbRed
If sColumn = "A" Then
rResults(i) = sColumn & sRow
Else
rResults(i) = sColumn & sRow & " for "
sColumn = Chr(Asc(sColumn) - 1)
rResults(i) = rResults(i) & Sheets(sSheet).Range(sColumn & sRow).Name.Name
End If
End If
Next myCell
End Sub
Assuming the ranges A5, A6, A7, A10 and A11, in sheet "Request" are named ranges.
And ranges A8 and C8 in sheet "Data".
The code will turn sheet "Request" Range, B5,B6,B7,b10,b11 & sheet "Data" Range A8, B8, D8 all into red, so the user will know where to enter data.
And the msgbox will report the empty ranges, as well as the named range adjacent to it.

Related

Exce VBA how to generate a row count in that starts with specific row and stops at last row? Formula is flawed

So I have what might be a simple issue. I have a worksheet where I'm just hoping to generate a row count starting with cell A4. So A4 = 1, A5 = 2 , etc. The problem is I'm not sure how to configure this with the following goal:
1 - I'm hoping the count starts with cell A4 and ends the count at the final row with data.
The code I have below only works if I manually put A4 = 1, and also populates formulas past the last row unfortunately.
Please help if this is possible.
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(5, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B5="""","""",DCT!A4+1)"
End With
End Sub
Write Formula to Column Range
The Code
Sub V14()
Const wsName As String = "DCT" ' Worksheet Name
Const tgtRow As Long = 4 ' Target First Row Number
Const tgtCol As String = "A" ' Target Column String
Const critCol As String = "B" ' Criteria Column String
' Define worksheet ('ws').
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
' Define Last Non-Empty Cell ('cel') in Criteria Column ('critCol').
Dim cel As Range
Set cel = ws.Cells(ws.Rows.Count, critCol).End(xlUp)
' Define Target Column Range ('rng').
Dim rng As Range
Set rng = ws.Cells(tgtRow, tgtCol).Resize(cel.Row - tgtRow + 1)
' Define Target Formula ('tgtFormula').
Dim tgtFormula As String
tgtFormula = "=IF('" & wsName & "'!" & critCol & tgtRow _
& "="""","""",MAX('" & wsName & "'!" & tgtCol _
& "$" & tgtRow - 1 & ":" & tgtCol & tgtRow - 1 & ")+1)"
' Write Target Formula to Target Range.
rng.Formula = tgtFormula
' If you just want to keep the values:
'rng.Value = rng.Value
End Sub
I think you might just need an extra IF:
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(4, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B4="""","""",IF(A3="""",1,SUM(DCT!A3,1)))"
End With
End Sub
Report any question you have or bug you have encountered. If, according to your judgment, this answer (or any other) is the best solution to your problem you have the privilege to accept it (link).
Dim target As String
Dim lastrow As Long
target = "A4"
lastrow = ActiveSheet.UsedRange.Rows.count
'for example
Range(target) = "1"
Range(target).Offset(1, 0) = "2"
Range(Range(target),Range(target).Offset(1, 0)).Select
Selection.AutoFill Destination:=Range(target & ":A" & lastrow + Range(target).Row - 1), Type:=xlFillDefault
You only got to change the target cell, this does the rest.

Copy several cells to paste into one single cell

I have three different named ranges, I want the macro to copy all three, to consolidate them all (each on one separate line), and to paste them in one single cell in another worksheet.
Dim range1 As Range, range2 As Range, range3 As Range, multipleRange As Range
Set range1 = wsForm.Range("Details_Absenteisme")
Set range2 = wsForm.Range("Boite_Infraction")
Set range3 = wsForm.Range("Boite_Corrections")
Set multipleRange = Union(range1, range2, range3)
ws_operation.Range("I" & lrow_operation).Value = multipleRange
This only paste the value in range1.
Concatenate the values together and then paste them into the cell you want.
I added a space in between the different values.
dim copystr as string
copystr = wsForm.Range("Details_Absenteisme").value & _
" " & wsForm.Range("Boite_Infraction").value & _
" " & wsForm.Range("Boite_Corrections").value
ws_operation.Range("I" & lrow_operation).Value = copystr
Loop the pre mention ranges and get all the values included. This is used in case you have many cells in your range
Sub test()
Dim nameRng As Variant
Dim i As Long
Dim cell As Range
Dim str As String
nameRng = Split("Details_Absenteisme,Boite_Infraction,Boite_Corrections", ",")
str = ""
For i = LBound(nameRng) To UBound(nameRng)
With wsForm
For Each cell In .Range(nameRng(i))
If str = "" Then
str = cell.Value
Else
str = str & " " & cell.Value
End If
Next cell
End With
Next i
MsgBox str
End Sub

Putting R1C1 formula on variable rows to reference the same column

I need help to write a code which puts an R1C1 formula into a row’s cells.
The start position of the row’s will vary each time the macro is run.
Ie. If the macro is run the first time, the formula will be entered into Row B16 as R[-5]C[3]. R[-5] in the case is E12.
However, when the macro is run another time, & its entered into row B25, I still want it to reference to E3, but it references to E20.
Here is my code
Dim cell As Range, MyRange As Range
Set MyRange = Range("B1:B5000")
For Each cell In MyRange
If cell = " " And cell.Offset(, 1) <> "Record" Then
cell.FormulaR1C1 = "=SUM(R[-5]C[3]: SUM(R[-5]C[4])"
End If
Next cell
End With
You are right, my code was trying to say This row - 5, this column + 3: this row -5, this column + 4
The problem I have is that This row could be any row & I would like to use relative referencing as this formula copies down to the next row
So what I’m trying to do is this
Cell B16 = E11+F11
Cell B17 = E12+F12
Cell B18 = E13+F13 etc
Then when the macro is run again & start cell is E25, then
Cell E25 = E20+F20
Cell E26 = E21+F21
Cell E26= E22+F22 etc
So, regardless of which cell the macro points to, it will always start the calculation from E11+F11
Here is my code
Dim cell As Range, MyRange As Range
Set MyRange = Range("B1:B5000")
For Each cell In MyRange
If cell = " " And cell.Offset(, 1) <> "Record" Then
cell.FormulaR1C1 = "=SUM(R[-5]C[3]: SUM(R[-5]C[4])"
End If
Next cell
End With
You're using relative references in your formula, and the formula won't work as you're trying to say =SUM(E1:SUM(F1) if the entered in cell B6. Any rows higher than that and it will try and reference off the sheet.
To use absolute referencing use R3C5 (row 3, column 5 = E3).
At best your formula was trying to say This row - 5, this column + 3: this row -5, this column + 4
Maybe try "=SUM(R3C5:R3C4)" which is the same as =SUM($E$3:$F$3).
Also - cell = " " - the cell must contain a single space? Should it be cell = ""?
Edit:
In response to your edit - if you want the first formula to always look at E11:F11, and the next to be E12:F12, etc you can use one of these solutions:
To add the formula to all rows in one hit - this doesn't check for a cell with a space:
Public Sub Test()
Dim MyRange As Range
Dim lOffset As Long
Set MyRange = Range("B1:B5000")
With MyRange
lOffset = 11 - .Row
.FormulaR1C1 = "=IF(RC[1]<>""Record"",SUM(R[" & lOffset & "]C5:R[" & lOffset & "]C6),"""")"
End With
End Sub
To check that each cell has a space in it before adding the formula:
Public Sub Test1()
Dim MyRange As Range
Dim rCell As Range
Dim lOffset As Long
Set MyRange = Range("B30:B5000")
lOffset = 11 - MyRange.Row
For Each rCell In MyRange
If rCell = " " And rCell.Offset(, 1) <> "Record" Then
rCell.FormulaR1C1 = "=SUM(R[" & lOffset & "]C5:R[" & lOffset & "]C6)"
End If
Next rCell
End Sub
Here's the results for the second code block showing the formula always starts in row 11:
And if you change the range the formula goes in:
Edit 2:
If rows 20:24 have Record then this will place =SUM($E11:$F11) in row 25. If row 26 has a record then row 27 will have =SUM($E12:$F12)
Public Sub Test1()
Dim MyRange As Range
Dim rCell As Range
Dim lOffset As Long
Set MyRange = Range("B20:B30")
lOffset = 11
For Each rCell In MyRange
If rCell = " " And rCell.Offset(, 1) <> "Record" Then
rCell.FormulaR1C1 = "=SUM(R[" & lOffset - rCell.Row & "]C5:R[" & lOffset - rCell.Row & "]C6)"
lOffset = lOffset + 1
End If
Next rCell
End Sub

VLOOKUP from another sheet, apply formula every nth row

I'm working on the below formula to Vlookup data from another sheet. The formula must be placed on the 14th column, and every 7 rows, vlookuping the first column value.
Sub test3()
'Vlookuping on Column N
Dim lastRow As Long
lastRow = Cells(Rows.Count, 14).End(xlUp).Row 'Checks last row with data
Dim cel As Range, rng As Range
Dim sheetName, lookupFrom, myRange 'variables
sheetName = "Plan2" 'the worksheet i want to get data from
lookupFrom = ActiveCell.Offset(0, -14).Address '
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7 '
Cells(i, 14).Select 'i= first value; step= lines to jump
ActiveCell.Formula = "=VLOOKUP(" & lookupFrom & ";" & myRange & "; 14; FALSE)"
Next i
End Sub
Example Sheet
I want to place the formula on the pink cells (column N), vlookuping the pink value from the first cell on another worksheet. My actual formula isn't even executing.
Try the code below, with 2 exceptions:
1.Modify "VlookRes" to your Sheet name - where you want to results to be.
2.You have Merged Cells in Column A (according to your image uploaded), you are merging Rows 2 untill 6 in column A, this means that the value of Cell A3 will be 0. If you want the values to read from the third row, start the merging from row 3 (and soon for the next values in Column A).
Option Explicit
Sub test3()
'Vlookuping on Column N
Dim ShtPlan As Worksheet
Dim ActSht As Worksheet
Dim lastRow As Long
Dim sheetName As String
Dim lookupFrom As String
Dim myRange As String
Dim i As Long
' modify this Sheet Name to your sheet name (where you want to keep your results)
Set ActSht = Sheets("VlookRes")
lastRow = ActSht.Cells(ActSht.Rows.Count, 14).End(xlUp).Row ' Checks last row with data
sheetName = "Plan2" 'the worksheet i want to get data from
Set ShtPlan = Sheets(sheetName)
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7
lookupFrom = ActSht.Cells(i, 1).Address ' ActiveCell.Offset(0, -14).Address '
Cells(i, 14).Formula = "=VLOOKUP(" & lookupFrom & "," & myRange & ", 14, FALSE)"
Next i
End Sub

Extract 1st letter from cell concatenate with another cell paste in third cell, then next row

I need to extract 1st letter from cell B2 concatenate with cell C2 paste in cell A2,
then move to next row and repeat till last data row.
I have the following, which partially works, but only works for the first row A2 then fills down this one string through all the rows till last data row.
Sub UserName()
Dim rng As range
Dim lastRow As Long
With Sheets("sheet1")
lastRow = .range("E" & .Rows.Count).End(xlUp).Row
End With
For Each rng In Sheets("Sheet1").range("A2:A" & lastRow)
rng.Value = fUserName(rng.Value)
Next
End Sub
The function
Function fUserName(ByVal strUserName As String) As String
Dim r As String
r = range("B2").Select
strUserName = Left(Trim(r), 1) & " " & range("C2")
fUserName = strUserName
End Function
IMHO you don't need VBA for that. Just use formula in A2
=CONCATENATE(LEFT(B2, 1),C2)
And then just replicate it for all cells that contain data.
Try below code. I have combined both your procedure.
No need of using a function , No need of For each loop
Sub UserName()
Dim lastRow As Long
With Sheets("sheet1")
lastRow = .Range("C" & .Rows.Count).End(xlUp).Row
End With
Range("A1:A" & lastRow).FormulaR1C1 = "= left(RC[1],1) & RC[2]"
End Sub
Your function is wrong, you are passing strUserName to the function but then setting the same variable within the function, however the real source of your issue is that you are using static references in your function so it does not matter which cell your sub routine is dealing with the function looks a cells B2 and C2.
I would get rid of the function all together and just replace the line
rng.Value = fUserName(rng.Value)
With
rng.Value = Left(Trim(rng.offset(0,1)), 1) & " " & rng.offset(0,2)
If you really want to use a function you need to pass the range to the function, not the value of the active cell as this has no bearing on the values of the other cells around it.
You need to pass the range into the function:
Sub UserName()
Dim rng As range
Dim lastRow As Long
With Sheets("sheet1")
lastRow = .range("E" & .Rows.Count).End(xlUp).Row
End With
For Each rng In Sheets("Sheet1").range("A2:A" & lastRow)
rng.Value = fUserName(rng)
Next
End Sub
Function fUserName(rn as Range) As String
fUserName = Left(Trim(rn(1,2).value), 1) & " " & rn(1,3).value
End Function
Well obviously B2 and C2 are hardcoded values so they do not change. You need to make those change by using a range object, for instance. Here's a pseudo-code of what I would do. I leave it up to you to make the necessary adjustments to make it work (because I don't see much effort in your question).
Function fUserName(rng as Range) as String
fUserName = Left(Trim(rng.Offset(0, 1).value), 1) & " " & rng.Offset(0, 2).value
End Function
Instead of calling fUserName() with rng.value, just put in rng. This will use the range object to get the proper rows for B and C.
Following code select first blank row
Sub SelFrstBlankRow()
Dim r1 As Range, r2 As Range, r3 As Range
Set r1 = Sheets("Sheet1").Range("a20")
Set r2 = Sheets("Sheet1").Range("u20")
Set r3 = Range(r1.End(xlUp), r2.End(xlUp)) 'r3 is the 1st blank row
r3.Select
End Sub

Resources