Excel VBA Macro: Searching For Blank From Selection - vba

I am trying to search through a selection from a table, find a value and then return a specific result.
The conditions I am trying are:
IF 'Name' = blank, return "N / A".
IF 'Result' = blank, OR "N/A", return "N / A".
IF 'Count' = 0, return "No", ELSE "Yes".
The code I have tried so far is as follows:
Sub DoStuffIfNotEmpty()
Set M = Selection
If Not IsEmpty(M) Then
MsgBox "I'm not empty!"
Else
MsgBox "Empty Value"
End If
End Sub
Also for reference, here is the test table I have created:
Reference Image

Test() sets up the worksheet and cells to examine -- if you want to work down a list of cells you can do it here -- and calls DoStuffIfNotEmpty, which examines the Name, Result and Count columns in order. Its not even close to being elegant but there you go...
Sub Test()
Dim cWorksheet As Worksheet
Dim CRange As Range
Set cWorksheet = ActiveWorkbook.Sheets("Sheet1")
Set CRange = cWorksheet.Range("A2:C2")
MsgBox DoStuffIfNotEmpty(cWorksheet, CRange), vbOKOnly
End Sub
Function DoStuffIfNotEmpty(CurrWorksheet As Worksheet, CurrRange As Range) As String
CurrWorksheet.Select
CurrRange.Select
Set m = Selection
If m.Cells(1, 1) = "" Or IsNull(m.Cells(1, 1)) Then
retmsg = "N/A"
Else
If m.Cells(1, 2) = "" Or IsNull(m.Cells(1, 2)) Or m.Cells(1, 2) = "N/A" Then
retmsg = "N/A"
Else
If m.Cells(1, 3) = 0 Then
retmsg = "No"
Else
retmsg = "Yes"
End If
End If
End If
DoStuffIfNotEmpty = retmsg
End Function

Related

VBA not able to discern between empty cells, numeric cells, and text?

I am trying to read cells in VBA and do certain things based on the contents of them. However, VBA is unable to accurately determine if the contents of a cell are blank, numeric, or text. It will think that cells with only a '1' in them are blank, and cells with text are blank. If it makes a difference, I turn off all screen updating and the like when this runs.
Please see code below:
Function IsNumber(ByRef expression As Variant) As Boolean
IsNumber = Not IsEmpty(expression) And IsNumeric(expression)
End Function
Function IsText(ByRef expression As Variant) As Boolean
IsText = Not IsEmpty(expression) And Not IsNumeric(expression)
End Function
Sub RA()
Dim cell As Range
With ActiveWorkbook.Worksheets("Sheet1")
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set r = Worksheets("Sheet1").Range(Cells(3, 3), Cells(lastrow, lastCol - 1))
End With
For i = 3 To lastrow
Set c = Cells(i, 3)
Select Case True
Case S1_Func(c)
End Select
Next i
End Sub
Function S1_Func(c As Variant)
Dim SR As Worksheet
Set SR = Worksheets("Financials")
Dim c2 As Range
Set c2 = c.Offset(0, 1)
If IsNumber(c2.Value2) Then
Select Case True
Case SR.Cells(i, 5).Value2 = "LY"
End Select
ElseIf IsText(c2.Value2) Then
Cells(i, 72).Value2 = "Incorrect"
End If
End sub
Updated after discussion below.
Function IsNumber(ByRef expression As Variant) As Boolean
IsNumber = expression <> "" And IsNumeric(expression)
End Function
Function IsText(ByRef expression As Variant) As Boolean
IsText = expression <> "" And Not IsNumeric(expression)
End Function
Original post:
There are some mixed problem in your code. The Select statement have several issues and is very misleading. In this case you can't use Select. If is your best option. Try something like this:
Sub Example()
If Len(Value) = 0 Then
'Empty
ElseIf IsNumeric(Value) Then
'Numeric
Else
'Alphanumeric
End If
End Sub

Check that all values in a range are identical

I need to display a message box when all the values in a range on my spreadsheet are zero. Currently I am using the following code:
Dim Cell As Range
For Each Cell In Range("E17:E25")
If Cell.Value = "0" Then
MsgBox ("If hardware is required, please manually populate the corresponding sections.")
End If
Next
The message is displayed, however it is shown 9 times (for each of the cells in the range). What I need is to check if all the values in the range E17:E25 are zero, and then display only one message box. Any ideas?
Thanks.
You want to know if all the values are 0? You could just do
If WorksheetFunction.Sum(Range("E17:E25")) = 0 Then MsgBox ("If hardware is required, please manually populate the corresponding sections.")
No need for loops.
Edit: If you want to check for any other number, and if all cells are that number, you can do this:
Sub t()
Dim rng As Range
Dim myNum as Long
myNum = 1
Set rng = Range("B3:B6")
If WorksheetFunction.CountIf(rng, myNum) = rng.Count Then MsgBox ("All the same!")
End Sub
And cause there are infinite ways to skin a cat here is another approach.
Dim Cell As Range
Dim ZeroCount As Integer
Dim CellCount As Integer
ZeroCount = 0
CellCount = 0
For Each Cell In Range("E17:E25")
CellCount = CellCount + 1
If Cell.Value = 0 Then ZeroCount = ZeroCount + 1
Next Cell
If ZeroCount = CellCount Then MsgBox ("If hardware is required, please manually populate the corresponding sections.")
To test that:
The range doesn't contain any empty values
All cells are the same
function
Function SameRange(rngIn As Range) As Boolean
If Application.CountA(rngIn) = rngIn.Cells.Count Then SameRange = (Application.CountIf(rngIn, rngIn.Cells(1).Value) = rngIn.Cells.Count)
End Function
test
Sub test()
MsgBox SameRange([d1:d5])
End Sub
'something like this
Dim isDataPresent as boolean
isDataPresent = true
for each Cell in Range(....)
if cell.value = "0" then
isDataPresent = false
exit for
end if
next
if not isDataPresent then
show message box here
end if

VBA: Over-writing cell with multiple IF conditions

I would like to write a VBA macro to give a specific value when two conditions are met, but I can't seem to figure out a way to do so, and searching doesn't help me with my specific issue.
Here's a quick summary of the problem:
I want to over-write the value in a specific cell if the values in two other cells match something specific.
I have a working code for the same report that over-writes a value if one other value matches something specific, and here is the code for that:
Sub test_overwrite()
Dim msheet As Worksheet
Set msheet = ActiveSheet
'Overwrites for test and reactivated cells
For i = 2 To msheet.UsedRange.Rows.Count
Select Case msheet.Cells(i, 7)
Case Is = "test"
msheet.Cells(i, 5) = "test"
Case Is = "reactivated"
msheet.Cells(i, 5) = "reactivated"
End Select
Next i
End Sub
Basically, what I would like to add to this code is the ability to overwrite a cell in (i,7) if the value of (i,5) matches "expired" and the value of (i,6) matches "#N/A".
How would I do so?
Edit 1:
Here's something I have just tried, but I get an 'Object Required' error
Sub subs_test_new_tests()
'Mark certain fields that are 'expired' as 'test'
Dim msheet As Worksheet
Dim state As String
Dim match As String
Dim status As String
Set msheet = ActiveSheet
For i = 2 To msheet.UsedRange.Rows.Count
Set state = msheet.Cells(i, 5)
Set match = msheet.Cells(i, 6)
Set status = msheet.Cells(i, 7)
If state = "expired" And match = "#N/A" Then
status = "test"
End If
Next i
End Sub
Sub subs_test_new_tests()
With ActiveSheet
For i = 2 To .UsedRange.Rows.Count
If .Cells(i, 5) = "expired" Then
If .Cells(i, 6) = "#N/A" Or Application.IsNA(.Cells(i, 6)) Then
.Cells(i, 7) = "test"
End If
End If
Next i
End With
End Sub
Try this:
Sub test_overwrite()
Dim msheet As Worksheet
Set msheet = ActiveSheet
With msheet
'Overwrites for test and reactivated cells
For i = 2 To .UsedRange.Rows.Count
Select Case Trim(.Cells(i, 7).Text)
Case Is = "test"
Trim(.Cells(i, 5).Text) = "test"
Case Is = "reactivated"
Trim(.Cells(i, 5).Text) = "reactivated"
End Select
if Trim(.Cells(i, 5).Text) = "expired" And ISERROR(.Cells(i, 6)) then .Cells(i, 7) = "test"
Next i
End With
End Sub

vba access function for extract cell value

I'm trying to write a function for extract cell string value of the first previous valorized cell of a certain column.
I try to explain better:
I've a column in witch not all cells cointans values.
So if I want to build a function that accept as parameter 1 cell, e.g. 'A5'.
If into A5 cell there is not any value it check if previous cell (A4) has some value. If fails again it recursively go back (A3..A2..A1) until it find something.
Public Function getPreviousValorizedCellValue(ByVal cell As Range) As String
If (cell.Value = "") Then
Set cell = cell.Offset(-1, 0)
getPreviousValorizedCellValue (cell)
Else: getPreviousValorizedCellValue = cell.Value
End If
End Function
It doesnt work. Excel give me error
Any ideas?
try this:
Public Sub TestgetPrevious()
Dim cell As Range
Set cell = ActiveSheet.Range("A5")
MsgBox getPreviousValorizedCellValue_v2(cell)
End Sub
Public Function getPreviousValorizedCellValue_v2(ByVal cell As Range) As String
Debug.Print cell.Address
If cell.Row <= 0 Then Exit Function
If (Trim(cell.Value = "")) Then
If cell.Row > 1 Then
Set cell = cell.Offset(-1, 0)
getPreviousValorizedCellValue_v2 = getPreviousValorizedCellValue_v2(cell)
Else
getPreviousValorizedCellValue_v2 = ""
End If
Else
getPreviousValorizedCellValue_v2 = cell.Value
End If
End Function
Try the below Code.
Function Foo(iRange As Range)
For i = iRange.Row To 1 Step -1
If Trim(Range("A" & i).Value) <> "" Then
Foo = Range("A" & i).Value 'Put the code you want here
Exit Function
End If
Next i
End Function

Screen out values which didn't fit two conditions

i wanna write a VBA programme that screen out values which didnt satisfy the specified values. However, I kinda stuck in the object-defined error of line 4 (If...Then). Would somebody pls help me out. Many thanks!!!!!!!!
Sub Macro1()
If Cells(A, 1) <> "none" Or Cells(A, 1) <> 0 Then
Cells(A, 2) = "checked"
Else
Cells(A, 2) = "Not checked"
End If
End Sub
You have your rows and columns reversed. Try:
Sub Macro1()
If Cells(1, "A") <> "none" Or Cells(1, "A") <> 0 Then
Cells(2, "A") = "checked"
Else
Cells(2, "A") = "Not checked"
End If
End Sub
A cell is referenced by a row and column or address. So use
Cells(1,1)
or
Cells("A1")
Use this:
Sub Macro1()
If Cells(1, 1) <> "none" Or Cells(1, 1) <> 0 Then
Cells(1, 2) = "checked"
Else
Cells(1, 2) = "Not checked"
End If
End Sub
Or you this:
Sub Macro2()
If Range("A1") <> "none" Or Range("A1") <> 0 Then
Range("B1") = "checked"
Else
Range("B1") = "Not checked"
End If
End Sub
You need to be careful to:
0) respect the language's syntax/semantics: is kind of obvious for a human, but what would mean A for VBA?
1) be sure what cell values are you accessing: i.e. which worksheet those cells belong to;
2) ynot compare apples with oranges: if something is a string, comparing it with an integer value gives you type mismatch errors. You need to be sure before comparing what type are you comparing.
3) follow the rules of Boolean logic, not the the ones common language logic: to say that something shouldn't be "none" or 0.0 doesn't translate logically into your If condition.
So, this is a proposal for a more robust macro:
Public Sub Macro1()
Dim in_value As Variant
Dim out_value As String
' Adjust the name of the worksheet to your needs'
With Worksheets("Sheet1")
' Read data '
in_value = .Range("A1").Value
' Check what type '
Select Case TypeName(in_value)
Case "Empty"
Let out_value = "Not checked"
Case "String"
If LCase(in_value) <> "none" Then
Let out_value = "checked"
Else
Let out_value = "Not checked"
End If
Case "Integer", "Long", "Single", "Double"
If in_value <> 0 Then
Let out_value = "checked"
Else
Let out_value = "Not checked"
End If
Case Else
Let out_value = "checked"
End Select
' Write data '
Let .Range("A2").Value = out_value
End With
End Sub