Excel VBA - How to validate input to be in certain column - vba

I have a script that asks for a starting cell
Set myCell = Application.InputBox( _
prompt:="Choose a starting field", Type:=8)
If myCell = Null Or myCell = "" Or Len(myCell.Value) < 3 Or Len(myCell.Value) > 12 Then
MsgBox "Incorrect cell value"
Exit Sub
Else
So, I have these checks for the value of the given cell so the script will not run if the validation does not go through. What I need is also for the validation to check whether the cell in certain column (D in my case).
So I need the validation to say "IS the selected cell in column D?" If Yes, continue, if no stop.
I've relentlessly googled to try to find this kind of comparison but I just fail to give it a good query.
Any help is appreciated. Thanks

With the help of Rich Holton I found the solution.
In order to check whether the input cell is in the column you want it to the following syntax can be used:
If myCell.Column <> 4 Then
...
End If
Where 4 is equal to Column D in this case. (Column A = 1, Column B = 2 and so on...)

Related

VBA: filter data based on cell value and fill in to another sheet

enter image description hereI Have two Excel Sheets ("Record") & ("Register"), " Register" is the database. from this database I need to create Records of each employees based on their employee ID (cell value). i am searching for a VBA code that should give me the training Record a each employee once i have enter their ID in the cell and click "a command button". Attached the Excel screen short for reference.
Steps 1: Enter Employee ID in the "Record" sheet
Step 2: Click command button "Filter" in the Record sheet
Step 3: VBA code to run and filter data from "Register" and fill "Record".
IF i Type another Employee ID in the sheet "Record" , it should ClearContents of the previous query. and produce the data.
Please help me, i am not good in VBA .attached the Excel screen short for reference ( UPDATE on 29/07/2018-Question Solved : sharing the code below; thank you Mr.ComradeMicha for your valuable feedback)
Sub Button2_Click()
'Declare the variables
Dim RegisterSh As Worksheet
Dim RecordSh As Worksheet
Dim EmployeeRange As Range
Dim rCell As Range
Dim i As Long
'Set the variables
Set RegisterSh = ThisWorkbook.Sheets("Register")
Set RecordSh = ThisWorkbook.Sheets("Record")
'Clear old data Record Sheet
RecordSh.Range("A8:F107").ClearContents
Set EmployeeRange = RegisterSh.Range(RegisterSh.Cells(6, 4), RegisterSh.Cells(Rows.Count, 6).End(xlUp))
'I went from the cell row6/column4 (or D6) and go down until the last non empty cell
i = 7
For Each rCell In EmployeeRange 'loop through each cell in the range
If rCell = RecordSh.Cells(4, 2) Then 'check if the cell is equal to "Record"
i = i + 1 'Row number (+1 everytime I found another "Record")
RecordSh.Cells(i, 1) = i - 7 'S No.
RecordSh.Cells(i, 2) = rCell.Offset(0, 2) 'Training name
RecordSh.Cells(i, 3) = rCell.Offset(0, -2) 'End date
RecordSh.Cells(i, 4) = rCell.Offset(0, 6) 'Validity
RecordSh.Cells(i, 5) = rCell.Offset(0, 7) 'Remarks
RecordSh.Cells(i, 6) = rCell.Offset(0, 5) 'Minimal requirement
End If
Next rCell
End Sub
Your code is missing a few essential parts you may want to look into:
It seems to require the user to select a specific row before the macro is started, even though there is a command button to trigger the macro. If the layout stays the same, just use constants to store the row where certain input or lookup fields are located.
ra is used both on the input form and on the lookup sheet. That's asking for trouble... Again, use constants or at least "StartingRow=3" or something similar.
You are correcting your employee number to a format that doesn't fit the data provided in the screenshot. Hopefully just a dummy data issue, but in case you are wondering why you don't find anything ;)
You are typecasting all fields individually. If your layout is always the same, it's much easier to just use the "variant" type for all cell values and make sure you already formatted all columns correctly.
ru is never initialized? It's supposed to be "the next row", why not simply use "ra+1" then instead of ru? Also, TRNRow and RTRNRow are never initialized either.
When you "search" your records, you actually only copy the same row into your results, then "copy next row until employee number is wrong". So this only works for exactly one employee, and even then you only catch the first few trainings. Use the Find function on the employee number cell in the records sheet to find the next row with that id, then copy the row's contents and find next.
I think if you get yourself aquainted with the Find function, you will easily finish this macro on your own. Here's a good guide: https://excelmacromastery.com/excel-vba-find
Good luck!

VBA How to Check if Cell Value is valid and exists?

I have this cell.Offset(0, -2) cell that I need to check if it exists inside my VBA loop.
My idea is that if the cell has an .Offset(0, -2) that does not exist (e.g. say cell = Column B and cell.Offset(0, -2) = Column A-1, cell.Offset(0, -2) is supposed to be invalid), I want to be able to check that it doesn't exist in the if else statement.
Right now when it doesn't exist, I'm getting a “Runtime Error 1004: Application defined or object defined error”.
I've tried IsErr(cell.Offset(0, -2)), cell.Offset(0, -2).Value, If cell.Offset(0, -2) Is Nothing Then, cell.Offset(0, -2) = "", but none of them seem to work... can anyone point me in the right direction? I'm pretty new to VBA and it seems like different variable types have different ways of checking if the value exists.
If you can use your offset amount as a variable, or some method to evaluate against the cell's column, you don't need to defend against errors. Consider below...
Sub IsvalidARea()
Dim OffsetAmount As Integer: OffsetAmount = -2
Dim Cell As Range
If Cell.Column + OffsetAmount < 1 Then
MsgBox "Oh FALSE!"
Else
'EVERYTHING IS OKAY!
End If
End Sub
A solution for this is by using the constantly misused On Error Resume Next, coupled with a If IsError. Here's an example:
On Error Resume Next
If IsError(ActiveCell.Offset(, -2).Select) = True Then
'This is indicative of an error. Meaning you are on Column B, and you ran out of space.
Else
'This means an error did not occur. Meaning you were at least on Column C or above.
End If
There may be a better solution, in fact I am sure there is. But what this will do is allow you to move past the actual 1004 Application error, and you can actually identify, and use the error that was really returned, instead of just forcing your macro/script to end.
To avoid using the error check, you can always check the current column index (B is 2) and make sure whatever you are offsetting by, once subtracted by your index is greater than 0. For example, column B is 2. Your offset is 2. 2 - 2 = 0, so it should not attempt it. Column C is 3, 3 - 2 = 1, which is greater than 0 so it would be valid. Both are explorable methods.

Copy rows based on cell value and paste on a new sheet

Check This
I need a help. I want to copy whole cell from A sheet name "Components" only if value in Column C is > 0 to a new Sheet name "Load list"
Can someone please give me the macro code for this?
on your new sheet you can add this condition the cell or range of cells:
=IF(Components!C5>0,Components!A5)
where C5 has thevalue to compare, and A5 has the value copy if the condition happens.
Right in my swing!
The formula given by #sweetkaos will work fine, in case you want to replicate the data as it is with blanks where data is not found.
I will imagine a slightly more complicated situation. I am assuming you want just one line in the next format as is shown in your image.
Also conveniently assuming the following:
a. both sheets have fixed start points for the lists
b. 2 column lists - to be copied and pasted, with second column having value
c. Continuous, without break source list
d. basic knowledge of vba, so you can restructure the code
Here is the code. Do try to understand it line by line. Happy Excelling!
Sub populateLoadList()
'declaring range type variables
Dim rngStartFirstList As Range, rngStartLoadList As Range
'setting values to the range variables
'you must change the names of the sheets and A1 to the correct starts of your two lists
Set rngStartFirstList = Worksheets("Name_of_your_fist_sheet").Range("A1")
Set rngStartLoadList = Worksheets("Name_of_your_second_sheet").Range("A1")
Do While rngStartFirstList.Value <> ""
If rngStartFirstList.Offset(1, 0).Value < 0 Then
Range(rngStartFirstList, rngStartFirstList.Offset(0, 1)).Copy
rngStartLoadList.PasteSpecial xlPasteValues
Application.CutCopyMode = False
Set rngStartLoadList = rngStartLoadList.Offset(1, 0)
End If
Set rngStartFirstList = rngStartFirstList.Offset(1, 0)
Loop
End Sub
Basically what i want is ... if Value on C is >0 i want whole column 10 copied to that new sheet .... not only that cell

Excel VBA deleting certain rows with certain conditions

I found a code online which works but I am failing to change it for my purpose. Each entry in my spreadsheet contains different formulas as well as an Iferror function with the aim of making cells with error messages appear as blank. For example lets say a cell E3 is dependent on cell F3 with a certain formula (for clarification lets say F3/2.5). It is obvious if there is no entry in cell F3 then an error message would display in cell E3. For this reason, I use the IFERROR function to display the cell as blank. The difficulty arises when I want to delete blank rows after a click on the macro button. However, since that cell does have an entry (a formula which in turn returns an error message), that cell does not delete. Also I need to run this code over 3 different selection ranges. Please can someone help! The code I found was from a different thread on this forum and is:
`sub foo()
dim r As Range, rows As Long, i As Long
Set r = ActiveSheet.Range("A1:Z50")
rows = r.rows.Count
For i = rows To 1 Step (-1)
If WorksheetFunction.CountA(r.rows(i)) = 0 Then r.rows(i).Delete
Next
End Sub`
Thanks Alot!
EDIT: If statement added to the autofilter as it was deleting a row when there were no blanks
You will want to set up a column in the spreadsheet with the following sumproduct:
=SUMPRODUCT((LEN(A1:F1)>0)*1)
This is calculating how many cells' values have a length more than 0 hence are not blank, you will need to adjust cell references accordingly as I tested on a small sample of fake data.
Following this you can just loop:
For i = rows To 1 Step (-1)
If Cells(i,"G") = 0 Then r.rows(i).Delete 'My formula is in column "G"
Next
Or set up an auto-filter and delete entire rows of the visible cells:
Dim lrow As Integer
If Not WorksheetFunction.CountIf(Range("G:G"), "0") = 0 Then
Range("A1:G1").AutoFilter
Range("A1:G1").AutoFilter Field:=7, Criteria1:="0"
lrow = Cells(rows.Count, 7).End(xlUp).Row + 1
Range("G2:G" & lrow).SpecialCells(xlCellTypeVisible).EntireRow.Delete
Range("A1:G1").AutoFilter
End If
The only problem with using a leading column to calculate for this is if you have a lot of data coming and going as you will need to replenish the formula, though you could use auto complete in the code i guess.

How do i add + 1 to activecell in vba

I am kept on getting run time 13 error. all i am trying to do add 1 to activecell.
dim rang as range
rang = activecell + 1
msgbox rang
You're not setting the rang reference.
Set rang = ActiveCell
One problem down.
You're relying on implicit conversions and default properties, which makes it much harder than it needs to be, to understand what's going on.
rang.Value = CLng(ActiveCell.Value) + 1
MsgBox rang.Value
If that blows up with a runtime error 13, then ActiveCell.Value isn't an integer value. You can't legally add +1 to a String... Or do anything (including mere comparison) with an error value. Use IsError to determine if the cell contains a value you can work with, before you work with it:
If Not IsError(rang.Value) Then
MsgBox rang.Value
End If
You want to reference the active cell's value, like this
rang = ActiveCell.Value + 1
Edit - Runtime error 13 is a type mismatch, basically you are trying to combine incompatible data types (assuming the active cell contains a number, not a number formatted as text). Try this.
Dim rang as Integer
rang = ActiveCell.Value + 1
msgbox rang
You can convert numbers formatted as text to numeric values by copying a cell with a one in it, then paste special, and select multiply (assuming the content is valid as a number)
Sub addOne()
ActiveCell = ActiveCell.Value + 1
End Sub
Try This. This will simply add 1 in current value. Make sure its not a string value in active cell. Hope This help.