Excel VBA Match function not working - vba

I'm using INDEX and MATCH functions to pull data which is concatenated string of G2 and H2 from column D (sorry I don't have enough points to attach pic). Column D has INDEX(column A and column B) and columns A and B have values till 12th row. MATCH is working fine giving me the position as 6 on the worksheet. But when I use this in VBA code as shown below,INDEX is working in the VBA code (can be seen through MsgBox) but MATCH function which would allot value to the variable 'check' isn't working. I have been breaking my head for really long. Need help from experts here. Somebody please tell me where am I going wrong?
Sub testindex()
Dim check As Long
Set sh = Sheets("Sheet1")
For j = 1 To 11
'Index value is correctly shown
MsgBox "Index Value=" & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2)
'Cells(7, 4)=ISA737775 same as G2&H2
MsgBox "Cells(7,4)=" & Cells(7, 4)
check = Application.WorksheetFunction.Match(Cells(7, 4), Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 1) & Application.WorksheetFunction.Index(sh.Range("A2:B12"), j, 2), 0)
Next j
End Sub
Thanks

Match expects the second paramater to be in the form of a range. When you call match through VBA that range actually needs to be a range object, not just some string like "A1:A12" or whatever it is that your concatenated Index formulas output.
At any rate, you are iterating already, so why not just call those values directly instead of pulling their values through Index?
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j), 0)
Which is writing the same exact thing but without having to use a taxing INDEX function in VBA to do it. Note that this still won't work because the second parameter of match is still just a string which is a concatenated value from Column A and Column B. You could convert to a range by sticking them in the range object with:
check = Application.WorksheetFunction.Match(Cells(7, 4), sh.Range(sh.Range("A" & 2 + j).value & sh.Range("B" & 2 + j)), 0)
I'm assuming that the values in A and B are actual cell names that when concatenated will make a range. Like when j=1 then the it would be like check=Match(Cells(7,4), sh.Range("G2:H50"), 0) or something...

Related

How can I insert variable into formula in VBA

Can anyone solve this?
Sub test
Dim i as integer
For I = 1 to 10
ActiveCell.Offset(0, 2).Formula = "=Sum(E15,&i&)"
Next I
End Sub
your actual goal is unclear
you may want to start form this code
Sub test()
Dim i As Integer
For i = 1 To 10
cells(i, 4).Formula = "=Sum(E" & i & ":E15)"
Next
End Sub
and adjust it to your needs, knowing that:
it currently writes in cells "D1:D10"
since cells(i, 4) references a cell in 4th column (i.e.: column "D") 4 and i row, and we're inside a loop where i is looping through 1 to 10
so if:
you want to reference a different column then just change 4 to the proper column index
you want to reference a different row then just change i to the proper row index (may be some i+2 if you need to iterate through 1 to 10 but start writing from row 3)
the formula written in those cells is:
=SUM(E1:E15) in D1,
=SUM(E2:E15) in D2,
....
=SUM(E10:E15) in D10.
so just change "=Sum(E" & i & ":E15)" to your actual needs
You're close, trying to use ampersands (&) to concatenate strings.
ActiveCell.Offset(0, 2).Formula = "=Sum(E15," & i & ")"
Use the ampersands between strings to merge them, not inside strings.

iteration of loop in formula vba

I'm trying to sum a variable range of data starting at row 3. sortedRow is the row # of the end of the data. lColumn is the last column used as a number.
I'm trying to sum the data in row 1, column H - lColumn.
I need to have the formula calculate the sum of column G, then iterating on referenced column by the current iteration (which will be columns h through x)
I've taken Scott Craner's advice and edited my code as
Dim lColumn As Long
lColumn = ActiveSheet.Cells(3, Columns.Count).End(xlToLeft).Column
sortedRow = Cells(Rows.Count, "D").End(xlUp).Row
Dim i As Integer 'iterated column sum cell
For i = 8 To lColumn
Cells(1, i).Value =Application.WorksheetFunction.SumIfs(Range(Cells(3,7),
Cells(sortedRow, 7)), Range(Cells(3, i), Cells(sortedRow, i)), 1)
Next i
The cells are not being updated with their values though.
It feels like I'm missing something really obvious with actually applying the number to the cell. I thought the above would do it.
added lColumn declaration because of issue with the formula being applied
added sortedRow declaration.
basically this. But with variable column lengths and number of columns.
It didn't matter for Column H that there was "#VALUE" in the volume column. So I assume it doesn't matter for the other columns.
Any help would be appreciated!
You have problems here.
("$G3:$G" & sortedRow, i & "3:" & i & sortedRow, 1)
("$G3:$G" & sortedRow & "," & i & "3:" & i & sortedRow, 1)
But you still have issues in there. If i=4 and sortedRow=12 let's say, this is what you would have.
(G3:G12,43:412, 1)
So you need to fix your Criteria_range1. I'm not clear from your question what you want the criteria to be.
Here is info on the arguments. https://msdn.microsoft.com/en-us/library/office/ff193011.aspx
The issue was resolved after fixing #VALUE cells in the sumifs columns I was trying to add. I made a conditional statement that set all errors to equal zero. This allowed the loop to function.

VBA 1004 error : Application defined or object defined error

I am a novice at Excel VBA and am running into an error 1004 while compiling a portion of the code:
Cells(i, j).Formula = _"=vlookup(Cells(i,1).Value,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(Cells(1,j).Value,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
i and j have been defined previously as integers and are part of a for loop. Could anyone please help me out on this?
A few things wrong there:
First, you're using the literal text "Cells(i, 1).Value" and "Cells(1, j).Value" in the formula string. You would need to concatenate the values into the string like this:
Cells(i, j).FormulaR1C1 = "=vlookup(" & Cells(i,1).Value & ",SKULifeCycle_Table_Temp!R1C1:R5000C500,match(" & Cells(1,j).Value & ",'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
Second, you used the .Formula property but passed R1C1 style references, so you should use the .FormulaR1C1 property (as I did above).
Third, if the values in the cells that you are using for the lookup values are text, you need to enclose them in quotes:
Cells(i, j).FormulaR1C1 = "=vlookup(""" & Cells(i,1).Value & """,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(""" & Cells(1,j).Value & """,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
or use the addresses (in R1C1 format) instead:
Cells(i, j).FormulaR1C1 = "=vlookup(RC1,SKULifeCycle_Table_Temp!R1C1:R5000C500,match(R1C,'SKULifeCycle_Table_Temp'!R1C1:R1C500,0),0)"
One issue that is clear (maybe the cause of the whole error), is that variables are being used within a string. So, what does that mean? I'll simplify using the code below as a template:
Sub Test1()
Dim i as Integer
Dim j as Integer
i = 2
j = 3
Cells(i, j).Value = "The row number is i and the column number is j"
End Sub
In the Cells line, it correctly refers to cell C2, which is the second row and third column. But what value is inserted into the cell? It's literally "The row number is i and the column number is j" using the letters, and not their corresponding numbers. Similarly, in your case, the formula will read: VLOOKUP(CELLS(i,1)... using the letter i, which is incorrect.
Additionally, a cell's formula doesn't use the CELLS syntax. You instead need to build a string using the variables. It would look a lot like:
"=VLOOKUP(" & Cells(i, 1).Address & "SKULifeCycle_Table_Temp!R1C1:R5000C500, Match(" & Cells(i, 1)Address ... "
Try to build out your formula string and refer back to this post with any specific questions.

VBA Loop through Column for Positive/Negative Numbers

I am new to VBA (as in I basically don't know anything about how to code in VBA, but I know python and general coding logic). I have an excel spreadsheet with a particular stock's data from 2004-2014 for every day the NYSE has been open. This data includes about 20 columns, but there are only 3 that I care about: the date (col a), a column with a specific percentage (col h), and a column with the price (col k). I want to write a simple program such that:
1) locate first positive percentage from column h, and the values in the same row for column a and k (i.e., if it's the third row, then find values from cells A3, H3, and K3)
2) locate the first negative percentage following the first positive percentage from step 1 in the same column h, and its corresponding values from column a and k (i.e., if it's the 7th row, then find values from cells A7, H7, and K7)
3) find the % difference of the 2 values found in the k column from the above two steps, and the difference in the number of rows from the positive and the negative percentage (i.e. 7-3=4)
4) Do this for the entire set of data which has almost 3000 rows of data - for example, after completing steps 1, 2, and 3, the program should find the first positive percentage following the negative percentage in step 2, then find the first negative percentage after that, and then find the % difference of the values in the k column and the difference in the number of rows
5) Place the information from the first 4 steps into a new spreadsheet (the values in the A, H, and K columns, the % differences, and the difference in the number of rows from the positive percentage and the negative percentage)
Can someone please write the VBA code for me for this, as I am new to VBA but need to get this done by tomorrow! Also, any tips on how to get started learning VBA would be very much appreciated! Thanks in advance, and Happy New Year!
Please let me know if you need anything clarified.
Just an idea:
Sub CompareData()
Dim srcwsh as Worksheet, dstwsh as Worksheet
Dim i as Integer, j as Integer
'source worksheet
Set srcWsh = Thisworkbook.Worksheets(1) ' or Thisworkbook.Worksheets("SheetName")
'destination worksheet
Set dstWsh = Thisworkbook.Worksheets.Add(After:=Thisworkbook.Worksheets(Thisworkbook.Worksheets.Count))
'define headers
dstWsh.Range("A1") = "Date"
dstWsh.Range("B1") = "Percentage"
dstWsh.Range("C1") = "Price"
dstWsh.Range("C1") = "Difference"
'start searching from 2. row
i = 2
Do While srcwsh.Range("A" & i)<> ""
'if value of column H is positive
If srcwsh.Range("H" & i)>0 Then
'find first empty row in a destination worksheet
j = GetFirstEmptyRow(dstWsh)
Union(srcWsh.Range("A" & i), srcWsh.Range("H" & i), srcWsh.Range("K" & i)).Copy dstWsh.Range("A" & j)
dstWsh.Range("D" & j).Formula = "=IF(ISERROR(D" & j-1 & "-D" & j & "),'',D" & j-1 & "-D" & j & ")"
End If
i = i+1
Loop
End Sub
Function GetFirstEmptyRow(ByVal wsh as Worksheet, ByVal Optional sCol As String = "A") As Integer
GetFirstEmptyRow = wsh.Range(sCol & wsh.Rows.Count).End(xlShiftUp).Row +1
End Function
Note: above code hasn't been tested!
All you need to do is to change the code to your needs. Good luck!

Delete row in Excel if a cell does not contain a specific value

I have a worksheet, i need deleted all rows that not contain the phrase "#" on column G until column K.
This is sample data i have
if cell on Column G until Column K not containing "#", Delete Rows
please help me..
You will have to use several loop commands. Begin by looping through the records that you want to process. Here is an outline of pseudo-code.
loop through the columns that you want to process, G through K
read the value of the cell as a string
initialize variable atdetector = "dunno_yet"
loop through each character of the string
if any character = "#"; then atdetector = "found"
After looping through each column, if atdetector = "dunno_yet", then "#" was never found. Delete the row. Repeat until there are no more rows.
The following macro scans from row 2 and removes rows where columns 2-5 do not contain an #:
Sub Macro1()
CurRow = 2
While CurRow < Application.WorksheetFunction.CountA(Range("A:A")) + 1
If InStr(1, _
Sheet1.Cells(CurRow, 2) _
& Sheet1.Cells(CurRow, 3) _
& Sheet1.Cells(CurRow, 4) _
& Sheet1.Cells(CurRow, 5), _
"#", vbTextCompare) Then
Else
Sheet1.Rows(CurRow & ":" & CurRow).Delete Shift:=xlUp
CurRow = CurRow - 1
End If
CurRow = CurRow + 1
Wend
End Sub
Using Instr, we concatenate the columns of interest (2-5 in my example code above) to create a single string of text. Then we search for # within that concatenated string and remove accordingly.
It changes
into
Alternatively, you can create an additional column containing the following formula:
FIND is used to identify whether an # exists within one of the preceding cells, print No if not and Yes if it does. Now you can filter these elements (No), select the range (making sure only the visible cells are selected), delete the rows and remove the filter.