I have a small macro program that matches values between two worksheets (big data).
I'm using Application.Match method to find the match of a certain value in another worksheet.
The problem is, when I try to assign a row variable on the range, the result gets Row 1 instead of Row 7 where the exact match is.
Application.Match(data1, Worksheets("Data").Range("O" & lRowRange & ":O" & lLastRow), 0)`
lRowRange = 5
If Not IsError(Application.Match(data1, Worksheets("Data").Range("O" & lRowRange & ":O" & lLastRow), 0)) Then
lMatchFound = Application.WorksheetFunction.Match(data1, Worksheets("Data").Range("O" & lRowRange & ":O" & lLastRow), 0)
sDataFound = Sheets("Data").Cells(lMatchFound, 15)
End if
I'm not using LOOP statements to find the match because the worksheets contain large amount of data.
Hope you could help me out. Thanks in advance.
You are looking for a match in O5:O10. If your searched text is in O5, then your match function give you a '1', because it is found in the first cell of your range.
Use
sDataFound = Sheets("Data").Cells(lMatchFound + lRowRange - 1, 15)
and you will be fine.
Related
I have two formulas that I need to transfer to VBA.
On Excel, my formula would be =countif(A$2:A2,A2) so I transferred that using this formula but everything is returning to 1. The rows didn't become dynamic and I want only the values to be displayed.
For a = 2 To lrow
ws.Range("T" & a).Formula = "=CountIf(A$2&"":""&A2)"",""&A2)"
Next a
Next formula that I use in Excel is
=IF(COUNTIF(A:A,A2)>Q2,"Check","Ok")
I tried this formula in VBA:
For i = 2 to lrow
If Countif(ws.Range("A2:A" & lrow), "A2") > ws.Range("Q2:Q", & lrow) Then
ws.Range("T" & i).Value = "Check"
Else
ws.Range("T" & i).Value = "Ok"
End If
Next i
You could populate column T with your first formula with this line of code:
ws.Range("T2:T" & lrow).FormulaR1C1 = "=COUNTIF(R2C[-19]:RC[-19],RC[-19])"
I can't advise on your second formula unless you clarify where you want to write it...
Basically, i am trying to use sumif function in vba. Instead of using fixed rows and columns, i am trying to make everything dynamic. here is the code i wrote to accomplish the task but failed.
sh.Range("V" & StartRowData + j).Value = Application.WorksheetFunction.SumIf _
(MettBeheer.Range("A1", "A" & LastRowMettBeheer), sh.Range("A" & StartRowData + j).Value, MettBeheer.Range("K1", "K" & LastRowMettBeheer))
the first two parameter of the function are ok. this part of the code Range("K1", "K" & LastRowMettBeheer) where i want to make it dynamic. instead of a fixed k range, it could be from a to end of the used columns in the sheet based on the criteria give from this code sh.Range("A" & StartRowData + j).Value
any suggestion or help is highly appreciated?
I am trying to find the average of a column with undefined number (i) of values (range is likely to be between 3-20 cells in column I, row 24 up to undefined number - j = 23 + i). The code previously included only the standard average function.
Now, I'd like it to average those cells in the give range, only including those cells in the proposed range. Hence, ignoring the identified outliers that are above and/ or below LFe, UFe. Location of that averaged value is Range("E" & m).
Is this even possible in the given worksheetfunction? And if so, what do I need to change to get this working?
I have tried to use existing solutions based on conditions such as 'average only cells that are positive' or 'only those that do not include N/A', but can't seem to get it working.
'Identifying outliers based on interquartile range
qe1 = Application.Quartile(Range("E24:E" & j), 1)
qe3 = Application.Quartile(Range("E24:E" & j), 3)
IQRe = qe3 - qe1
UFe = qe3 + (IQRe * 1.5)
LFe = qe3 - (IQRe * 1.5)
'[EDIT] Currently I have it as follows:
Range("E" & m).Value = Application.WorksheetFunction.AverageIfs(Range("E24:E" & j), "<" & UFe, Range("E24:E" & j), ">" & LFe, Range("E24:E" & j))
Which returns: #VALUE! without the .WorksheetFunction, and 'run error '424' Object required' as written above.
The only option that functioned, BUT not with my variable ranges is formatting it similarly as following: (How can this otherwise be adapted to work for my variable ranges, including 'j' etc.?)
Range("E" & m).Select
ActiveCell.FormulaR1C1 = "=AVERAGEIF(R[-6]C[4]:R[-3]C[4],"">""& 4.3,R[-6]C[4]:R[-3]C[4])"
Not enough rep to comment (sorry!), but here are a few ideas I had:
1) As SJR has mentioned, if there is a numeric value you're basing the color-coding from, you can use that in your code instead of a color. I'm thinking UFe & LFe are the upper and lower thresholds. So you could just have cells with formulas to automate the UFe & LFe via formulas instead and then use "AVERAGEIFS".
2) Alternatively, you could integrate your variables into a ".formula" instead, like:
Sheet1.Range("E" & m).Formula = "=AVERAGEIFS($E$24:$E$" & j & ",$E$24:$E$" & j & ","">" & LFe & """,$E$24:$E$" & j & ",""<" & UFe & """)"
Just change "Sheet1" to whatever sheet you're referencing
Solved, I made a "MATCH" mistake, thanks all!
I have uncertain number of worksheets every time with uncertain name, but my target worksheet to search is always the 3rd last one
so in VBA I did this UDF:
Function SHEETNAME() As String
Dim L As Long
L = ThisWorkbook.Worksheets.Count
SHEETNAME = Sheets(L - 2).Name
End Function
therefore, calling =SHEETNAME() in my spreadsheet will always return the name of my target worksheet
then unfortunately, the exact value I need is 1 row below what I can reach with VLookup (3rd column)
=VLOOKUP($K$2,INDIRECT("'" & sheetname() & "'!"&"A2:X30"), 3, 0) <--- I need 1 row below this result
so I converted the formula to INDEX + MATCH
=INDEX(INDIRECT("'" & sheetname() & "'!" & "A2:X30"),MATCH($K$2,INDIRECT("'" & sheetname() & "'!" & "A2:A30"),0)+1,3)
somehow, the result of MATCH($K$2,INDIRECT("'" & sheetname() & "'!" & "A2:A30"),0) from F9 is N/A, why....
From A:X you want the third column's value in your VLOOKUP so it's INDEX(C:C, ...) or INDEX(A:X, ..., 3). The VLOOKUP always uses the first column for the lookup so it's going o be MATCH(K2, A:A, 0).
=INDEX(INDIRECT("'" & sheetname() & "'!A2:X30"), MATCH($K$2, INDIRECT("'" & sheetname() & "'!A2:A30"), 0)+1, 3)
Don't complicate INDIRECT strings with $. Nothing is going to change the string.
I have gotten so much excellent help from this site. This is my first question. I have googled all the wordings I can think of and looked at all possible related threads on this site and others, and cannot find an explanation.
I am trying to automate a sheet into which a data table of variable size will be pasted.
Here is the formula I am trying to replicate:
=(C26-B26)/B26 (percent variation to previous month)
Edited to respond to a comment: This formula is in cell C28 in the sheet I am being asked to automate. So it is referring to cells two rows above and 1 column to the left of the cell where the formula is located.
Here is my code which the editor accepts:
ActiveCell.Formula = "=(" & (Cells(Index(Row() - 2), Index(Col())).Address(False, False)) & "-" & Cells(Index(Row() - 2), Index(Col() - 1)).Address(False, False) & "/" & Cells(Index(Row() - 2), Index(Col() - 1)).Address(False, False) & ")"
When I run this, I get a compile error: Sub or Function not defined and the first instance of row is highlighted.
It seems to me I read somewhere that one cannot calculate with Row() and Column() but I have not been able to find that again. I have found many examples online of people using Row() and Column() in this way to find cells adjacent to the active cell.
I appreciate any help and suggestions.
Thank you in advance.
I'd determine the indices of your reference cell (the one that's not known). In the example below, I'm simply using the indices and converting them to characters from ASCII and concatenating the returned character and the row number.
Dim activeRow, activeColumn As Integer
activeRow = 40 'Iterate through or use Range reference as Range.Row
activeColumn = 3 'Iterate through or use Range reference as Range.Column
MsgBox ("=(" & Chr(64 + activeColumn) & (activeRow - 2) & "-" & Chr(64 + activeColumn - 1) & (activeRow - 2) & "/" & Chr(64 + activeColumn - 1) & (activeRow - 2) & ")")
Update:
Also take a look at this question for referencing the instance of the calling cell in a Public Function, specifically Fionnuala's answer.