VLOOKUP returns 0 for blank cells - vba

I have a data in SheetW like
A B C D
1 EID Y/N
2 1001 n
3 1004 n
4 1005 n
5 1006 y
6 1009 n
7 1006 y
8 1007 n
9 1008 y
10 1010
I'm using VLOOKUP in other sheetYN to fill Y/N based on above table, using vba vlookup
My vba code
With Sheets("sheetYN")
LastRow2 = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
For X = 2 To LastRow2
wsSheet1.Cells(X, 2).Formula =
"=VLOOKUP(A" & X & ",'SheetW'!$A$2:$B$321,2,FALSE)"
Next X
And the result looks like below. But empty *EID*s are filling with 0. How to
display Y/N as blank instead of 0 if EID is blank
1 EID Y/N
2 0
3 1001 n
4 0
5 1004 n
6 0
7 1005 n
8 0
9 1006 y
10 0
11 1009 n
12 1006 y
13 1007 n
14 1008 y
15 1010 0

Simple If statement should do the trick. Check if the cell next to you is blank. If true, then "" if false then have your formula.

Easiest by way of a quick fix may be merely to accept the output 'as is' and format ColumnB with something like ;;;General, effectively hiding the cell's contents.
An alternative quick fix would be to trap the errors arising from failed lookups (ie #N/A results rather than 0) within the existing formula, by changing it to:
wsSheet1.Cells(X, 2).Formula = "=iferror(VLOOKUP(A" & X & ",'SheetW'!$A$2:$B$321,2,FALSE),"""")"
so where there are no values to be looked up the formula displays nothing.

Related

Dynamic Range Selection with a relative reference (R1C1) in a Loop

I have an excel sheet (examplary extract below) and would like to achieve following with my VBA code (I am a total newbie to VBA).
Go through all rows in coloumn A
Calculate Average value for range in column E with identical dates (column A)
generate a new table with rows: dates; col: average values and create table in a new worksheet.
Important Note:
Ranges can have different number of rows depending on the number of values (E) for a date (A)
As a starting point I have following VBA Code:
1 Sub GotoNewState()
3 Dim i As Integer
4 Dim startRange As Integer
5 i = 0
7 Do
8 i = i + 1
9 If Cells(ActiveCell.Row + i, ActiveCell.Column).Value <> ActiveCell.Value Then
10 Cells(ActiveCell.Row + i, ActiveCell.Column).Select
11 startRange = -(i - 1)
12 'MsgBox startRange
13 ActiveCell.Offset(-1, 5).FormulaR1C1 = "=AVERAGE("R[" & startRange & "]C[-1]":RC[-1])"
14 Exit Do
15 End If
16 Loop
18 End Sub
However I have problems with the syntax for R1C1 notation as the argument I want to pass to R[argument] returns an error.
I would be happy about other solutions to my described intention above.
Extract from Excel:
A B C D E
13.03.2015 1 300 5.00 0
13.03.2015 2 300 5.00 40
13.03.2015 3 300 5.00 4
13.03.2015 4 300 5.00 2
13.03.2015 5 300 5.00 2
13.03.2015 6 300 5.00 22
20.03.2015 6 300 5.00 0
20.03.2015 5 300 5.00 14
20.03.2015 1 300 5.00 1
20.03.2015 2 300 5.00 0
20.03.2015 3 300 5.00 0
20.03.2015 4 300 5.00 0
27.03.2015 3 300 5.00 0
27.03.2015 4 300 5.00 3
27.03.2015 2 300 5.00 15
27.03.2015 6 300 5.00 147
27.03.2015 5 300 5.00 14
27.03.2015 1 300 5.00 0
02.04.2015 1 300 5.00 8
02.04.2015 2 300 5.00 0
02.04.2015 3 300 5.00 63
02.04.2015 4 300 5.00 0
02.04.2015 5 300 5.00 0
02.04.2015 6 300 5.00 3
17.04.2015 1 300 5.00 7
17.04.2015 2 300 5.00 1
17.04.2015 3 300 5.00 19
17.04.2015 4 300 5.00 0
17.04.2015 5 300 5.00 159
17.04.2015 6 300 5.00 84
30.04.2015 1 300 5.00 0
30.04.2015 2 300 5.00 0
30.04.2015 3 300 5.00 2
30.04.2015 3 300 5.00 2
30.04.2015 4 300 5.00 0
30.04.2015 5 300 5.00 182
30.04.2015 6 300 5.00 2
...
If you still want to do this in VBA, then
1.Copy column A unique values in new column
2.then use AVERAGEIF formula to calculate
For example:
Below code copies unique dates from column A and paste it in column G and calculate avg using AVERAGEIF formula in column H
Sub getAvg()
Set ws = ThisWorkbook.Sheets("Sheet1")
lastRow = ws.Range("A60000").End(xlUp).Row ' Last Row number in Column A
'ws.Range("G1").Value = "Dates"
ws.Range("H1").Value = "Avg"
ws.Range("A1:A" & lastRow).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=ws.Range("G1"), Unique:=True ' copy unique values using AdvancedFilter
lastRowNewTble = ws.Range("G60000").End(xlUp).Row ' Last Row number in Column G
ws.Range("H2:H" & lastRowNewTble).Formula = "=AVERAGEIF(A2:A" & lastRow & ",G2,E2:E" & lastRow & ")" ' write formula in column G
End Sub
If you don't want to use filters, you can try with loops. This code will calculate averages for the ranges and put them in F column:
Dim unqDateDict As Scripting.Dictionary
Dim lastRow As Integer
Dim i As Integer
Dim count As Integer
Dim currDate As String
Set unqDateDict = New Scripting.Dictionary
lastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
count = -1
'Fill dictionary with unique dates
For i = 1 To lastRow
currDate = Range("A" & i).Value
If Not unqDateDict.Exists(currDate) Then
unqDateDict.Add currDate, count
count = count + 1
End If
Next
'Calculate averages
Dim tempSum As Integer
Dim keyIndex As Integer
Dim loopIndex As Integer
Dim loopCounter As Integer
Dim Key
loopIndex = 1
keyIndex = 1
loopCounter = 0
For Each Key In unqDateDict.Keys
For i = loopIndex To lastRow
If CStr(Range("A" & loopIndex).Value) = Key Then
tempSum = tempSum + Range("E" & loopIndex).Value
loopIndex = loopIndex + 1
loopCounter = loopCounter + 1
Else
Range("F" & keyIndex) = tempSum / loopCounter
loopCounter = 0
tempSum = 0
keyIndex = keyIndex + 1
Exit For
End If
Next
Next Key
End Sub

Excel formula or VBA searching for matching values, every matching value found move to new column

I'm new to excel and have very basic knowledge of it. I hope that some one will by able to help me as I'm trying to find similar formula or VBA code for few days now and no luck.
I need formula or VBA to find same value in range and when first matching value find move to new column.
For example:
Value in A1 check against all values in column H and if same value found move that value to B1, then again value in A1 check against values left in H column if same found move to C1, every time finds A1 same as value in H column moves that value to new column D1, E1 .....continue until all values in H column have been checked and matching ones moved. After this value in A2 checked against all values in H column and all matching values moved to B2,C2,E2 etc. Continue until all values have been moved from column H.
This how data looks before moving:
0 A B C D E F G H
----------------------------------------------------------
1 123 123
2 256 123
3 333 123
4 123
5 123
6 256
7 256
8 333
9 333
10 333
11 333
12 333
13 333
After movment:
0 A B C D E F G H
----------------------------------------------------------
1 123 123 123 123 123 123
2 256 256 256
3 333 333 333 333 333 333 333
4
5
6
7
8
9
10
11
Something like this:-
Sub tester()
With ActiveSheet
For Each cell In .Range("A1:" & .Range("A1").End(xlDown).Address)
i = 1
For Each c In .Range("H1:" & .Range("H1").End(xlDown).Address)
If cell.Value = c.Value Then
cell.Offset(0, i).Value = c.Value
i = i + 1
End If
Next
Next
End With
End Sub
Note: This does not clear the results from run to run.

how do I conditionally subtract in Excel?

I am trying to do the following with knowing that column A and B are data and C is the result:
A B C
1 5 (B1-A1)=4
2 3 (B2-A1)=2
3 5 (B3-A1)=4
4 7 (B4-A2)=5
5 4 (B5-A2)=3
6 9 (B6-A2)=7
.
.
.
.
How do I do this automatically in Excel or in Excel Visual Basic?
Sub sequence()
Dim i As Integer
Dim j As Integer
i = 2
j = 2
For i = 2 To 25 Step 3
Cells(i, 3) = Cells(i, 2) - Cells(j, 1)
Cells(i + 1, 3) = Cells(i + 1, 2) - Cells(j, 1)
Cells(i + 2, 3) = Cells(i + 2, 2) - Cells(j, 1)
j = j + 1
Next i
End Sub
Here is the VBA code that solves.
You must define the range in for loop, currently it is set from 2nd Row to 25th Row.
A B C
1 4 =B2-A2
1 2 =B3-A3
1 3 =B4-A4
=A2+1 5 =B5-A5
=A3+1 6 =B6-A6
=A4+1 7 =B7-A7
=A5+1 6 =B8-A8
=A6+1 7 =B9-A9
=A7+1 9 =B10-A10
You can initiate your first 3 rows with 1 and then just add 1 in the 4th row column A; drag the formula down. Subsequently, you may then subtract Column B from Column A.
The only drawback is that your column A will not be a sequence incrementing by 1 every step instead a sequence stepping by 1 on every fourth occasion.
OFFSET with ROW() is your friend for any repeating n-th row/column problem.
=B1-OFFSET(A$1,ROUNDUP(ROW()/3,0)-1,0), copied down column C.
1 5 4
2 3 2
3 5 4
4 7 5
5 4 2
6 9 7
You can use the $ in the function ($B5-$A1) and drag the cursor with the cell over the C column to the last element written.

Input user defined values inside multiple cells using vba

I have to manipulate range of cells in excel using VB. Can I do it in the following manner ?
Range("a1:b5")=[1 2 3 4 5 6 7 8 9 0]
I don't think so, I've never seen that syntax. One thing you can do is something like:
For Row = 1 To 5
Range("a" + CStr(Row)).Value = Row
Range("b" + CStr(Row)).Value = (Row + 5) Mod 10
Next Row
assuming that you want it set up thus:
A B
+------
1 | 1 6
2 | 2 7
3 | 3 8
4 | 4 9
5 | 5 0
You may need to use Mid(CStr(Row),2) - I can't remember off the top of my head if Cstr gives you a leading space for non-negative numbers.

macro to re-arrange data

I have been trying to write a macro to re-arrange the Cells in the rows and columns of Stock tables for the output I desire. Luckily the Stock Tables are generally the same each and every time (Different names and values), and the desired outcome is the same format..
Here is some example Data.
A
1 Name
2 description
3 description
4 description
5 description
6 ID#: 56284
7 Quantity in stock: 34
8 Zoom In and Configure
B
1 Name
2 description
3 description
4 description
5 description
6 ID#: 56284
7 Quantity in stock: 50
8 Zoom In and Configure
And I would like the Output to go into something like this(If possible to sheet2 starting on Cell B2):
B C E
B Being Row 1
C being Row 2 3 4 and 5 Combined
E being JUST Row 7 Stock Value I.E 50
On a single spreadsheet there would be 4 columns, and 8 rows I would have to re-arrange.. Making 32 total.
It would be great to automated this, so any help would be greatly appreciated.
Let me clarify my understanding. For each column you want the following data format:
A A
1 Name 1 Name
2 Desc1 2 Desc1; Desc2; Desc3; Desc4
3 Desc2 On sheet 2 3 50
4 Desc3 --------------->
5 Desc4
6 Id#: 56284
7 Quantity in Stock: 50
8 Zoom in and configure
If this is the case you can use the following code. It assumes your data is in A1 to D8 in Sheet 1.
Sub FormatData()
Dim col As Integer
For col = 1 To 4
With Worksheets(2)
.Cells(1, col) = Cells(1, col) //Get name
.Cells(2, col) = Cells(2, col) & "; " & Cells(3, col) & "; " & Cells(4, col) & "; " & Cells(5, col) //Concatenate descriptions into single string
.Cells(3, col) = Cells(7, col) //Get quantity in stock
End With
Next col
End Sub