I have a code that checks in a range if some cells are blank (empty or not). It gives me a message saying so. But, it seems not working well : the output message always says that there are some empty cells in the range (column A to H, until the last populated row) whereas it's the contrary (always data).
I precise that the layout of the range is a table! MsgBox(LastRow) is every time equal to the last row also..
Here is a part of the code:
Set sht = ThisWorkbook.Worksheets("SS upload")
Set StartCell = Range("A14")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
MsgBox (LastRow)
Set Rrng = Range("A14 : H" & LastRow)
For Each cell In Rrng
If IsEmpty(cell) = True Then
bIsEmpty = True
Exit For
End If
Next cell
If bIsEmpty = True Then
MsgBox "There are empty cells in the file"
Else
MsgBox "All cells have values!"
End If
End Sub
Does anything seem wrong in this?
Thank you for your precious help! :)
Regards
Probably you are not realizing, that you are looking in a range(A14:H LAST Row) Thus, if you have 5 rows, then the range is still Range(A14:H5). And there, you have empty values.
Public Sub TestME()
Dim bIsEmpty As Boolean
Set sht = ThisWorkbook.Worksheets(2)
Set StartCell = Range("A14")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).row
MsgBox (LastRow)
Set Rrng = Range("A1 : H" & LastRow)
For Each cell In Rrng
If IsEmpty(cell) = True Then
bIsEmpty = True
Exit For
End If
Next cell
If bIsEmpty Then
MsgBox "There are empty cells in the file"
Else
MsgBox "All cells have values!"
End If
End Sub
That's strange indeed because it also work sometimes. I mean the output message "All cells have value" is conformed to what's really in the file (no blanks at all) but sometimes not..
Here is my full code:
Sub empty_cells()
Dim sht As Worksheet
Dim Rrng As Range
Dim cell As Range
Dim LastRow As Long
Dim StartCell As Range
Dim bIsEmpty As Boolean
Set sht = ThisWorkbook.Worksheets("SS upload")
Set StartCell = Range("A14")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
MsgBox (LastRow)
Set Rrng = Range("A14 : H" & LastRow)
For Each cell In Rrng
If IsEmpty(cell) = True Then
bIsEmpty = True
Exit For
End If
Next cell
If bIsEmpty = True Then
MsgBox "There are empty cells in the file"
Else
MsgBox "All cells have values!"
End If
End Sub
thanks for your support :)
Related
I have this working code that gets the value from "sheet1" column C to set it as sheet name and make a new worksheet and copies the "testscript" sheet.
My problem is I only need to copy that has the column value with "Y".
Here is my code:
Dim rcell As Range
Dim Background As Worksheet
Set Background = ActiveSheet
For Each rcell In Range("C2:C500")
If rcell.Value <> "" Then
For rep = 1 To (Worksheets.Count)
If LCase(Sheets(rep).Name) = LCase(rcell) Then
MsgBox "This sheet already exists!"
Exit Sub
End If
Next
Sheets("TestScript").Copy After:=Sheets(Worksheets.Count)
Sheets(Sheets.Count).Name = rcell.Value
End If
Next rcell
Dim rcell As Range
Dim Background As Worksheet
Set Background = ActiveSheet
For Each rcell In Range("C2:C500")
'if rcell has value and same row column J is equal to "Y"
If rcell.Value <> "" And Sheets("Sheet1").Cells(rcell.Row, 10).Value = "Y" Then
For rep = 1 To (Worksheets.Count)
If LCase(Sheets(rep).Name) = LCase(rcell) Then
MsgBox "This sheet already exists!"
Exit Sub
End If
Next
Sheets("TestScript").Copy After:=Sheets(Worksheets.Count)
Sheets(Sheets.Count).Name = rcell.Value
End If
Next rcell
I'd go as follows
Option Explicit
Sub main()
Dim rcell As Range
With Sheets("Sheet1") ' reference your "source" sheet for subsequent range explicit qualification
For Each rcell In .Range("C2:C500").SpecialCells(xlCellTypeConstants) ' loop through wanted range not empty cells with "constant" (i.e. not formulas) values
If UCase(.Cells(rcell.Row, 10)).Value = "Y" Then ' check current cell row column J value
If Not IsSheetThere(rcell.Value) Then 'check there's no sheet named after current cell value
Sheets("TestScript").Copy After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = rcell.Value
End If
End If
Next
End With
End Sub
Function IsSheetThere(shtName As String) As Boolean
On Error Resume Next 'avoid any error at following line to stop the routine
IsSheetThere = Worksheets(shtName).Name = shtName 'try getting a sheet with the passed name. this will throw an error if no sheet is found with that name
End Function
I'm struggling with the following code which you can see below. It is totally a pain in the *** now. I really need some help.
This code is a search tool which looks for criteria from every worksheet except the summary and the list. After the .Find founds the word, then the code selects a 4 wide range around the searched word, then it copies and pastes it on the Summary sheet.
When the first searched word is found, I also would like to copy and paste the actual worksheet (where the word is found) title (on each worksheet "G3:J3") right after the search result on the summary page. This search tool could help me to find quickly which search criteria where can be found, at which sheet and some properties which also inside the title.
The result should look like this: (r1 = the first 4 columns, r2= the rest 4 columns (that is the excel header))
item nr. Item Owner Used Capacity ESD_nr. box Owner Free capacity location
Sorry for the long description.
CODE:
Private Sub searchTool()
Dim ws As Worksheet, OutputWs As Worksheet, wbName As Worksheet
Dim rFound As Range, r1 As Range, r2 As Range, multiRange As Range
Dim strName As String
Dim count As Long, lastRow As Long
Dim IsValueFound As Boolean
IsValueFound = False
Set OutputWs = Worksheets("Summary") '---->change the sheet name as required
lastRow = OutputWs.Cells(Rows.count, "K").End(xlUp).Row
On Error Resume Next
strName = ComboBox1.Value
If strName = "" Then Exit Sub
For Each ws In Worksheets
If ws.Name <> "lists" And ws.Name <> "Summary" Then
With ws.UsedRange
Set rFound = .Find(What:=strName, LookIn:=xlValues, LookAt:=xlWhole)
If Not rFound Is Nothing Then
firstAddress = rFound.Address
Do
IsValueFound = True
Set r1 = Range(rFound.EntireRow.Cells(1, "B"), rFound.EntireRow.Cells(1, "D"))
Set r2 = Range("G3:J3")
Set multiRange = Application.Union(r1, r2)
multiRange.Copy
OutputWs.Cells(lastRow + 1, 11).PasteSpecial xlPasteAll
Application.CutCopyMode = False
lastRow = lastRow + 1
Set rFound = .FindNext(rFound)
Loop While Not rFound Is Nothing And rFound.Address <> firstAddress
End If
End With
End If
Next ws
On Error GoTo 0
If IsValueFound Then
OutputWs.Select
MsgBox "Seach complete!"
Else
MsgBox "Name not found!"
End If
End Sub
I must admit I had trouble following your requirements and there was not a definition of where it wasn't working, to that end I re-wrote it to help me understand.
Private Sub SearchTool_2()
Dim BlnFound As Boolean
Dim LngRow As Long
Dim RngFind As Excel.Range
Dim RngFirstFind As Excel.Range
Dim StrName As String
Dim WkShtOutput As Excel.Worksheet
Dim WkSht As Excel.Worksheet
StrName = "Hello" 'ComboBox1.Value
If StrName = "" Then Exit Sub
Set WkShtOutput = ThisWorkbook.Worksheets("Summary")
LngRow = WkShtOutput.Cells(WkShtOutput.Rows.count, "K").End(xlUp).Row + 1
For Each WkSht In ThisWorkbook.Worksheets
If (WkSht.Name <> "lists") And (WkSht.Name <> "Summary") Then
With WkSht.UsedRange
Set RngFind = .Find(What:=StrName, LookIn:=xlValues, LookAt:=xlWhole)
If Not RngFind Is Nothing Then
Set RngFirstFind = RngFind
BlnFound = True
Do
WkSht.Range(RngFind.Address & ":" & WkSht.Cells(RngFind.Row, RngFind.Column + 2).Address).Copy WkShtOutput.Range(WkShtOutput.Cells(LngRow, 11).Address)
WkSht.Range("G3:J3").Copy WkShtOutput.Range(WkShtOutput.Cells(LngRow + 1, 11).Address)
LngRow = LngRow + 2
Set RngFind = .FindNext(RngFind)
Loop Until RngFind.Address = RngFirstFind.Address
End If
End With
End If
Next
Set WkShtOutput = Nothing
If BlnFound Then
ThisWorkbook.Worksheets("Summary").Select
MsgBox "Seach complete!"
Else
MsgBox "Name not found!"
End If
End Sub
I found the copy statement was the better option rather than using the clipboard, I also found a missing reference of firstAddress.
I have three ranges in a sheet (rng1, rng2, rng3) where I need to make sure that rng2 and rng3 contain no blanks before proceeding with the macro.
I have tried several methods that I can find and cannot get any of them to work. Willing to try a different method if someone has suggestions.
This is me trying to count blank cells using specialcells(xlCellTypeBLanks) but something isn't working with my error handling when neither range is blank:
Dim wrk As Workbook
Dim sht As Worksheet
Dim twb As Workbook
Dim tws As Worksheet
Dim lrow As Long
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim finprod As Variant
Dim subprod As Variant
Application.ScreenUpdating = False
Set wrk = ActiveWorkbook
Set sht = wrk.Worksheets(1)
For Each sht In wrk.Worksheets
lrow = sht.Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = sht.Range("A2:A" & lrow)
Set rng2 = sht.Range("F2:F" & lrow)
Set rng3 = sht.Range("E2:E" & lrow)
On Error GoTo Err1
If rng3.SpecialCells(xlCellTypeBlanks).Count > 0 Then
MsgBox ("Invalid item number.")
Exit Sub
End If
Err1:
On Error GoTo Err2
If rng2.SpecialCells(xlCellTypeBlanks).Count > 0 Then
MsgBox ("Missing quantity.")
Exit Sub
End If
Err2:
On Error GoTo 0
Exit For
Next sht
I try to avoid using goto in such way - it makes the code confusing when it gets bigger. Here is what I came up with:
Sub check_blank()
Dim sht As Worksheet
Dim twb As Workbook
Dim tws As Worksheet
Dim lrow As Long
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim finprod As Variant
Dim subprod As Variant
Application.ScreenUpdating = False
Set wrk = ActiveWorkbook
Set sht = wrk.Worksheets(1)
For Each sht In wrk.Worksheets
lrow = sht.Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = sht.Range("A2:A" & lrow)
Set rng2 = sht.Range("F2:F" & lrow)
Set rng3 = sht.Range("E2:E" & lrow)
If Application.CountIf(rng3, "") > 0 Then
MsgBox ("Invalid item number.")
Exit Sub
End If
If Application.CountIf(rng2, "") > 0 Then
MsgBox ("Missing quantity.")
Exit Sub
End If
Next sht
End Sub
The Range.SpecialCells method is Nothing when there are no xlCellTypeBlanks cells available and Nothing does not have a count; not even a count of zero.
You can use the On Error Resume Next or choose a non-destructive method of determining if there are blank cells.
if cbool(application.countblank(rng2)) then
'there are zero-length string and/or blank cells
'do something
end if
The problem with the above is that the worksheet's COUNTBLANK function will count zero-length strings returned by a formula (e.g. "") as blanks when they are not truly blank.
To catch only truly blank cells the following will be True - CBool(rng2.Count - application.Countif(rng2, "<>")). Only truly blank cells will be counted and any non-zero count will be true. This avoids having to crash the environment with On Error Resume Next when there is nothing to find.
The code below basically searches for any keyword in any sheet and highlights it. My question is, how to also copy the entire row number where the word/words is/are found to a new sheet in addition to the highlight?
Is it also possible to precise in which worksheet the search will be done?
Many thanks in advance,
Gonzalo
Sub CheckMULTIVALUE()
'This macro searches the entire workbook for any cells containing the text "#MULTIVALUE" and if found _
highlight the cell(s) in yellow. Once the process has completed a message box will appear confirming completion.
Dim i As Long
Dim Fnd As String
Dim fCell As Range
Dim ws As Worksheet
Application.ScreenUpdating = False
Fnd = InputBox("Find what:", "Find and Highlight", "#MULTIVALUE")
If Fnd = "" Then Exit Sub
For Each ws In Worksheets
With ws
Set fCell = .Range("A1")
For i = 1 To WorksheetFunction.CountIf(.Cells, Fnd)
Set fCell = .Cells.Find(What:=Fnd, After:=fCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If fCell Is Nothing Then
MsgBox Fnd & " not on sheet !!"
Exit For
Else
With fCell
.Interior.ColorIndex = 6
End With
End If
Next i
End With
Next ws
Application.ScreenUpdating = True
MsgBox "Check complete"
End Sub
Add code before the For loop to create the results worksheet or clear it if it already exists:
Dim results As Worksheet: Set results = ActiveWorkbook.Sheets("Results")
If results Is Nothing Then
Set results = ActiveWorkbook.Sheets.Add()
results.Name = "Results"
Else
results.Cells.Clear
End If
Create a reference to its A1 cell and a counter:
Dim resultsRange As Range: Set resultsRange = results.Range("A1")
Dim matches As Long
When you find a match add what you need to the Results worksheet and increment the counter.
With fCell
.Interior.ColorIndex = 6
resultsRange.Offset(matches, 0).Value = fCell.Row
resultsRange.Offset(matches, 1).Value = fCell.Value
matches = matches + 1
End With
To specify a specific sheet remove For Each ws In Worksheets and Next ws and replace With ws with With ActiveWorkbook.Sheets("SheetNameHere")
I have followed some answers here in a bid to perform the task above, and found that the most suitable code for my task is the following:
Option Explicit
Const strText2 As String = "FUNDS"
Sub ColSearch_DelRows()
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim cel1 As Range
Dim cel2 As Range
Dim strFirstAddress As String
Dim lAppCalc As Long
Dim bParseString As Boolean
'Get working range from user
On Error Resume Next
Set rng1 = Application.InputBox("Please select range to search for " & strText1, "User range selection", ActiveSheet.UsedRange.Address(0, 0), , , , , 8)
On Error GoTo 0
If rng1 Is Nothing Then Exit Sub
'Further processing of matches
bParseString = True
With Application
lAppCalc = .Calculation
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Set cel1 = rng1.Find(strText2, , xlValues, xlPart, xlByRows, , False)
'A range variable - rng2 - is used to store the range of cells that contain the string being searched for
If Not cel1 Is Nothing Then
Set rng2 = cel1
strFirstAddress = cel1.Address
Do
Set cel1 = rng1.FindNext(cel1)
Set rng2 = Union(rng2.EntireRow, cel1)
Loop While strFirstAddress <> cel1.Address
End If
'Further processing of found range if required
If bParseString Then
If Not rng2 Is Nothing Then
With rng2
.Font.Bold = True
.Offset(1, 0).EntireRow.Insert
End With
End If
End If
With Application
.ScreenUpdating = True
.Calculation = lAppCalc
End With
End Sub
Now the problem with the code here is that when it finds two consecutive rows (with the search query - funds), it inserts two blank rows after the first one, and null after the second.
Can someone help me in finding the problem in this code?
The line where I am inserting the new row is: .Offset(1, 0).EntireRow.Insert
Thanks
Perhaps I'm missing something here, but it sounds like your goal is to:
Prompt the user for a range
Find the cells in that range with the value "FUNDS"
Make the text of those cells bold
Insert a row below each instance of "FUNDS"
The below will do that:
Option Explicit
Const searchstring As String = "FUNDS"
Sub ColSearch_DelRows()
Dim rng1 As Range
Dim ACell As Range
'Get working range from user
On Error Resume Next
Set rng1 = Application.InputBox("Please select range to search for " & searchstring, "User range selection", ActiveSheet.UsedRange.Address(0, 0), , , , , 8)
On Error GoTo 0
If rng1 Is Nothing Then Exit Sub
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For Each ACell In rng1
If (ACell.Value = searchstring) Then
ACell.Font.Bold = True
ACell.Offset(1, 0).EntireRow.Insert
End If
Next ACell
End Sub