VBA applying function to each cell in range - vba

I need to write macro or function or whatever in VBA, what will apply a function with arguments (e.g. vlookup) on a rangeof cells. I thought it can be done by macro, but there I could not use arguments for vlookup, so I dont know any way how to do it. Is it possible?
For example:
I want to have this:
vlookup(A1;G1:H50;2;0) in cell B1 and
vlookup(A2;G1:H50;2;0) in cell B2 and so on, to e.g. B10
but I want to write formula only once and let other cells to be filled automaticaly.
Thanks a lot.

If I understand you correctly, here is one way (you'll have to change the delimiter to match your country settings, and adjust where you want the formula to go, I just put in B1:B10 as an example):
Sheet1.Range("B1:B10").Formula = "=vlookup(A1,$G$1:$H$50,2,0)"
This bit of code will write the formula to the range B1:B10 on sheet1, which has the same effect of putting the formula in the B1 and then "dragging" it down to B10. What makes this work is that Excel has the built in functionality of auto-incrementing a formula references based on whether or not the range is preceded by a $ symbol.
If a column reference has a $ in front, it will not increment as the formula is dragged across columns. If the $ is in front of the row reference, it will not increment as the formula is dragged down.
So looking back at my proposed formula, you can see that the A1 will increment as the formula is dragged to B2, B3, B4, etc...auto-incrementing the look up value to be cell A2, A3, A4, respectively. The look up range does not change at all because both the column and the row references are preceded by a $.
If you run the code I gave you, you'll see that you should have the expected results of only writing one formula, but changing the look up range through the built in auto incrementing functionality.
--------------------More edits based on comments--------------------
To do what you want, you don't need VBA at all (even though you initially requested a VBA / macro solution). You can put the formula in a cell and drag it down to how ever far down you want it to go. Please take a look at this link to see if it helps answer your questions:
How to fill data automatically in Excel

You could use Application.VLookup just like this following this example http://www.exceltrick.com/formulas_macros/vlookup-in-vba/:
Sub SetValues(columnToChange As String, columnToLookup As String, range As String, startColumn As Integer, endColumn As Integer)
For number = startColumn To endColumn Step 1
valueLookup = columnToLookup + CStr(number)
valueToChange = columnToChange + CStr(number)
Sheets("yourSheetName").Range(valueToChange).value = Application.VLookup(valueLookup, range, 2, 0)
Next number
End Sub
If you want to call them, create another subroutine without parameters that you can call from a button click for instance.
Sub DoStuff()
On Error GoTo ErrorHandler
Dim valueLookup as String
Dim valueToChange as String
Dim range as String
Dim firstColumn as Integer
Dim lastColumn as Integer
Label1:
valueLookup = InputBox("Enter the column to lookup")
valueToChange = InputBox("Enter the column to change")
range = InputBox("Enter the range of the lookup")
firstColumn = CInt(InputBox("Enter the first column number to lookup"))
lastColumn = CInt(InputBox("Enter the last column number to lookup"))
Call SetValues(valueToChange, valueLookup, range, firstColumn, lastColumn)
Exit Sub
ErrorHandler:
MsgBox("One value has an error in it.")
Resume Label1:
End Sub

Related

Change cell color based on another cell value

In a workbook I have, the D column has a formula in it to derive the last six digits of a value in column C. These columns are located in a sheet titled "JE". I have a dynamic SQL connected query that has values in the A column. That query is located in a sheet titled "required_refs". I essentially, want to write: If the value in the D column cell matches/equals any of the values in that query in sheet "required_refs", turn the F column cell red in sheet JE.
Example: If cell D10 has a value that equals any of the values in column A in "required_refs", turn cell F10 red. In addition, if cell D13 has a value that matches/equals a value in column A in sheet "required_refs", turn F13 red. And so on.
Here is the code I tried. I added it in Sheet "JE":
Code:
Sub ChangeCellColor()
Dim ref_code As Range: Set ref_code = Range("D7:D446").Value
Dim refCode_Confirm As Range: Set refCode_Confirm = Worksheets("required_refs").Range("A:A").Value
Dim colorChange As Range: Set colorChange = Worksheets("required_refs").Range("A:A")
For Each cell In ref_code
If cell.Value = refCode_Confirm.Value Then
Range("F7:F446").ActiveCell.Interior.ColorIndex = 3
Next cell
End If
End Sub
Currently, this code just doesn't do anything. It doesn't turn the F column cell red. I've asked a question similar to this but, the workbook I'm using has changed a bunch since then, and this question is a bit more simple than the previous one.
If anyone could help, I'd really appreciate it. Thanks!
Your code has a number of issues.
.Value returns a basic type, like a string or long. You can't assign this to a range variable.
Your End If and Next cell statements are swapped around. Always use correct indentation so these errors become more obvious.
You have an undeclared variable cell. This can potentially cause bugs. In the VBE, turn on the Tools > Options > Editor > Required Variable Declaration option to force the use of Option Explicit in new modules.
Fixing these issues leads us to this:
Sub ChangeCellColor()
Dim cell As Range
Dim ref_code As Range: Set ref_code = Range("D7:D446")
Dim refCode_Confirm As Range: Set refCode_Confirm = Worksheets("required_refs").Range("A:A")
Dim colorChange As Range: Set colorChange = Worksheets("required_refs").Range("A:A")
For Each cell In ref_code
If cell.Value = refCode_Confirm.Value Then
Range("F7:F446").ActiveCell.Interior.ColorIndex = 3
End If
Next cell
End Sub
Unfortunately, it still doesn't work as you can't compare a single value directly against a column of values in VBA.
This following code corrects this remaining issue. Note the choosing of good meaningful names as well as the use of RVBA for the variables. This is a good tip for how to avoid making similar errors. Also note the use of .Value2 instead of .Value. This is highly recommended.
Sub ChangeCellColor()
Dim rngRef As Range
Dim rngRefsToCheck As Range: Set rngRefsToCheck = Range("D7:D446")
Dim rngRequiredRefs As Range: Set rngRequiredRefs = Worksheets("required_refs").Columns("A")
Dim rngColorChangeRequired As Range: Set rngColorChangeRequired = Columns("F")
For Each rngRef In rngRefsToCheck
If Not IsError(Application.Match(rngRef.Value2, rngRequiredRefs, 0)) Then
rngColorChangeRequired.Cells(rngRef.Row).Interior.ColorIndex = 3
End If
Next rngRef
End Sub
The best and fastest way to achieve the color change would be to use Advanced Filters, thus avoiding the need to loop. However, since you're still learning the basics, I've shown the looping version.

Highlight unique values based on another range

Column 1 is in Sheet1 and column 2 is in Sheet2. If the value is not found , then highlight that cell. I am trying to do a vlookup comparing two columns. I think the Syntax is incorrect. Please see my code I was trying below:
Option Explicit
Sub VlookupColoums()
' declarations
Dim lookFor As Range
Dim srchRange As Range
Dim I As Long
Dim vtest As Variant
' start
Set lookFor = Sheets("Sheet1").Range("A13").End(xlUp)
Set srchRange = Sheets("Sheet2").Range("A2").End(xlUp)
vtest = Application.VLookup(lookFor.Rows.Count, srchRange.Rows.Count, 2, False)
' process
For I = 1 To lookFor.Rows.Count
If IsError(vtest) Then
srchRange.Interior.Color = 4
Else
Exit Sub
End If
Next I
End Sub
Assuming you have data on Sheet1!A1:A15 and Sheet2!A1:A10.
Also assuming you want to highlight unique cells (ones withouth at least one identical in the other list) on Sheet2.
Basically you want to format all the cells that if counted on the other list comes up with 0. The steps:
Select all the cells to be evaluated on Sheet2
Go to Home/Styles/Conditional Formatting
Select New Rule, then Use a formula to determine...
Enter this formula: =COUNTIF(Sheet1!$A$1:$A$5,A1)=0
Click on the Format button, and set up a formatting for the unique cells
OK
Profit. :)

Repeat command and increase range

I have almost no experience with VBA that being said.
I have a function in "B21" that I have copied over the same row up to "Z21"
I want the results from these cells to be shown on a different sheet all in one Column starting at "B2" and repeating until till it reaches the end.
This is what I have for that.
Sheets("Barlist").Range("B2").Value = "B21"
Alternatively the function I have in "B21" that I have copied over to repeat itself is:
=IF((COLUMN()-1)<$B$16,ROUND(TAN(RADIANS($B$5))*(($B$6)-($B$15*(COLUMN()-2))),2)+($B$11-0.33),IF((COLUMN()-1)=$B$16,$B$18,""))
So if I could just tell in to repeat this function down Column "B" until it returns a blank result that would should work to.
This code would cycle through all cells from B21 to the last column in row 21 with data and if the cell is blank you would need to add the code for what you wanted to do with that cell. Otherwise, the cells gets placed into "Barlist" starting at B2 and working down (using the next blank row each time)
Sub NAMEOFSUB()
Dim LastCol As Long
Dim CurCol As Long
Dim DestRow As Long
LastCol = Sheets("CURRENT SHEET NAME").Cells(21, Columns.Count).End(xlToLeft).Column
For CurCol = 2 to LastCol
If Sheets("CURRENT SHEET NAME").Cells(21, CurCol).Value = "" Then
'Do Something with your blank cell such as add a .Formula
Else
DestRow = Sheets("Barlist").Range("B" & Rows.Count).End(xlUp).Row + 1
Sheets("Barlist").Range("B" & DestRow).Value = Sheets("CURRENT SHEET NAME").Cells(2, CurCol).Value
End If
Next CurCol
End Sub
What exactly are you trying to do?
Right now your code would just enter the value "B21" in cell B2 on sheet Barlist.
If you want to add a reference to that cell, you could use Sheets("Barlist").Range("B2").FormulaR1C1="R21C2"
Although I really don't see any reason to use VBA at all for this. If you want a dynamic range, so it is linked to the original range, you could simply use the Transpose Function.
For your example, select the cells B2 to B26 on your Barlist sheet. Press F2 (should enter cell B2) and enter the formula =TRANSPOSE(SHEET!B21:Z21). This is an array function, so you don't just press enter, you have to press CTRL+SHIFT+ENTER at the same time to enter it. Excel will automatically append little curly brackets {} around the formula so you know it's an array formula.
If you want static values, select the range B21:Z21 you want to copy, then go to cell B2 on your Barlist sheet and right click>paste special and use the "trasnpsose" option

Excel Drop Down Box with Formula

Hi I have an excel with a drop down box whose list has 3 cells. One of these cells contain a formula. The problem is this formula is dependent on data in another cell and when this data changes the calculated value changes. The value is automatically update in the list where it was chosen from but I will manually have to go back to the drop down box and change it. How can I have the value be updated automatically. Willing to look at a VBA solution if need be
Put the following into the worksheet module. It assumes that the cell with validation applied is G9, and the second option of the list is the formula.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(False, False) = "G9" Then
If Target.HasFormula Then Exit Sub 'or else infinite loop
Dim ListRange As Range
Dim FoundIdx As Variant
Set ListRange = Me.Evaluate(Me.Range("G9").Validation.Formula1)
FoundIdx = Application.Match(Target.Value, ListRange, 0)
If Not IsError(FoundIdx) Then
If FoundIdx = 2 Then
Target.Formula = ListRange(2).Formula
End If
End If
End If
End Sub
Note that this will not work if the formula might have the same value as any of the other options!
I couldn't reproduce your issue. Here is what I did:
Populate 2 cells with a random value and a third cell with a formula (columns B3, B4, B5)
Define a Name Range with these 3 cells called it Options
Create a drop down using Insert/Form Controls/Combo Box
Set the input range of the drop down to Options
Change the cells value to get the formula give different results and the new values are reflected on the Options list and the Drop Down.
Is this what you are doing?

VBA Count cells in column containing specified value

I need to write a macro that searches a specified column and counts all the cells that contain a specified string, such as "19/12/11" or "Green" then associate this number with a variable,
Does anyone have any ideas?
Do you mean you want to use a formula in VBA? Something like:
Dim iVal As Integer
iVal = Application.WorksheetFunction.COUNTIF(Range("A1:A10"),"Green")
should work.
This isn't exactly what you are looking for but here is how I've approached this problem in the past;
You can enter a formula like;
=COUNTIF(A1:A10,"Green")
...into a cell. This will count the Number of cells between A1 and A10 that contain the text "Green". You can then select this cell value in a VBA Macro and assign it to a variable as normal.
one way;
var = count("find me", Range("A1:A100"))
function count(find as string, lookin as range) As Long
dim cell As Range
for each cell in lookin
if (cell.Value = find) then count = count + 1 '//case sens
next
end function
If you're looking to match non-blank values or empty cells and having difficulty with wildcard character, I found the solution below from here.
Dim n as Integer
n = Worksheets("Sheet1").Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
Not what you asked but may be useful nevertheless.
Of course you can do the same thing with matrix formulas.
Just read the result of the cell that contains:
Cell A1="Text to search"
Cells A2:C20=Range to search for
=COUNT(SEARCH(A1;A2:C20;1))
Remember that entering matrix formulas needs CTRL+SHIFT+ENTER, not just ENTER.
After, it should look like :
{=COUNT(SEARCH(A1;A2:C20;1))}