Failing againg with my project
I have formulas with variable Brand that is changed dynamically (AF Column). Basically all I want is to extract Brands into a column next (AE) to the formula column for visial convenience
For i = LBound(Brand) To UBound(Brand)
Range("AF" & i + 2).Formula = "=COUNTIFS(C:C," & RTrim(Month(Mesyaz3)) & _
",H:H,""Headphones"",F:F," & Chr(34) & Brand(i) & Chr(34) & ")"
Next i
Range("AF:AF").Sort Key1:=Range("AF2"), Order1:=xlDescending, Header:=xlYes
ActiveSheet.Range("AG2:AG8").Formula = ActiveSheet.Range("AF2:AF8").Formula
ActiveSheet.Range("AH2:AH8").Formula = ActiveSheet.Range("AF2:AF8").Formula
Dim ws As Worksheet
Set ws = Worksheets(1)
Dim j As Variant
j = Application.Match(""" & Brand(i) & """, ws.Range("AF2:AF8"))
ActiveSheet.Range("AE2").Value = Application.Index(ws.Range("AF2:AF8"), j, 0)
And I get #N/A Already lost two days for that. Would be enourmously grateful to anyone who could help.
It's not exactly clear from your question as to your desired output but here's a guess:
For i = LBound(Brand) To UBound(Brand)
Range("AF" & i + 2).Formula = "=COUNTIFS(C:C," & RTrim(Month(Mesyaz3)) & _
",H:H,""Headphones"",F:F," & Chr(34) & Brand(i) & Chr(34) & ")"
Range("AE" & i + 2).Value = Brand(i)
Next i
Range("AE:AF").Sort Key1:=Range("AF2"), Order1:=xlDescending, Header:=xlYes
I've added a line to write the brand to AE, and altered the Sort to accommodate this.
Related
I'm trying to use a countifs statement by looking in the first 2 columns and comparing them to another table in the same Wokbook. The reference RrC1, RC1 or anything else does not work. I only get "0" as a result. If i type in constants it works. I'm sure that my arguments 2, 4, 6 are the problem. I just can' figure out why!
Sub DataBase()
'Set my tables
Dim Answers As ListObject
Dim Table As ListObject
Set Answers = Worksheets("quantitativ").ListObjects("DataQuant")
Set Table = Worksheets("Database").ListObjects("Tabelle7")
'Set my Ranges for filters (Organizational level, Location, Function...)
Set OrgRange = Answers.ListColumns(1).Range
Set LocRange = Answers.ListColumns(2).Range
'Set Ranges for Answers to Questions (Scale)
Set Q1 = Answers.ListColumns(5).Range
Dim r As Long 'Row variables for For-Loop
For r = 5 To Table.DataBodyRange.Rows.Count + 4
'Q1
Cells(r, 6).FormulaR1C1 = _
Application.WorksheetFunction.CountIfs(Q1, RrC5, OrgRange, RrC1, LocRange, RrC2)
Next r
End Sub
Cells(r, 6).FormulaR1C1 = _
Application.WorksheetFunction.CountIfs(Q1, RrC5, OrgRange, RrC1, LocRange, RrC2)
This is quite a mess. You're attempting to load a formula with the result of a worksheet function.
If you want to load the formula to the cell then I'd do this:
Cells(r, 6).Formula = "=CountIfs(" & Q1.Address & ", " & _
Cells(r, 5).Address & ", " & OrgRange.Address & ", " & _
Cells(r, 1).Address & ", " & LocRange.Address & ", " & _
Cells(r, 2).Address & ")"
Or even:
Cells(r, 6).Formula = .Formula = "=CountIfs(" & _
Q1.Address & ", E" & r & ", " & _
OrgRange.Address & ", A" & r & ", " & _
LocRange.Address & ", B" & r & ")"
However, if you want the formula evaluated and just the result dumped in the cell..
Cells(r, 6).Value = Application.WorksheetFunction.CountIfs(Q1, _
Cells(R, 5), OrgRange, Cells(R, 1), LocRange, Cells(R, 2))
Keep in mind though with all of these options, Cells(.. are not fully qualified.
Changing all to .Cells(.. would make this much better, wrapping the lot
in a
With WorkSheet("DESTINATION_SHEET")
...
...
End With
is highly advisable.
I'm trying to do a VBA code to accomplish 2 things as follows:
Count how many characters there is on cell A1, using the formula LEN(A1) and one the last line, I'm trying to have the formula RIGHT(LEFT(A1;Q1-2);6) on cell J1
Please follow down my VBA code so far:
LR = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To LR
cel = "A" & i
cel2 = "P" & i
cel3 = "Q" & i
Range("P" & i).Formula = "=LEN(" & cel & ")"
Range("J" & i).Formula = "=RIGHT(LEFT(" & cel & "," & cel3 & "-" & 2 & ")," & 6 & ")"
Next i
It seems something silly what is missing, however, I couldnt manage to solve it so far
Thanks in advance
You’re missing a Right, and some other things
Range("J" & i).Formula = "=RIGHT(LEFT(" & cel & "," & cel3 & "-2), 6)"
There is a particular part of my code which I cannot make work,
I'm trying to do the following command on VBA =RIGHT(LEFT(X1;Z1-2);LEN(LEFT(X1;Z1-2))-FIND(":";X1))
On cell X1, there is a text: RESULTS:NG & MODEL:IJ
My VBA code is:
LR = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To LR
cel = "A" & i
cel2 = "Y" & i
cel3 = "Z" & i
cel4 = "X" & i
Range("M" & i).Formula = "=RIGHT(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "),LEN(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "))-FIND(:" & cel4 & "))"
Next i
I'm open for a better approach for this issue as well
Thanks in advance
Try writing all the formulas at once and reduce using quotes within the formula as much as possible.
Range(Cells(1, "M"), cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
All range and cells reference within a sub procedure are better with a properly defined parent worksheet reference.
dim lr as long
with worksheets("sheet1")
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range(.Cells(1, "M"), .cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
end with
I think I'm overlooking something simple...
My idea is to create a function in Excel that's easier to set up than the following:
=INDEX($A$1:$A$5,AGGREGATE(15,6,ROW($B$1:$B$5)/($B$1:$B$5=1),ROW(1:1)))
(see ScottCraner's comment in this answer for that function in practice)
I have created the following UDF:
Public Function findUnique(ByVal indexRange As Range, matchRange As Range, matchVal As Long)
' Trying to create a dynamic function of:
' =INDEX($A$1:$A$5,AGGREGATE(15,6,ROW($B$1:$B$5)/($B$1:$B$5=1),ROW(1:1)))
findUnique = Evaluate("=Index(" & indexRange.Address & ",AGGREGATE(15,6,Row(" & matchRange.Address & _
")/(" & matchRange.Address & "=" & matchVal & "),Row(" & ActiveCell.Row & ":" & ActiveCell.Row & ")))")
End Function
And it almost works. Except, when I drag down from the first row, the data doesn't update. I have to click into the cell to "retrigger" the function to get the correct data to show:
(Column D is that formula, entered correctly).
But, how do I get the formula to update automatically, without re-entering the cell?
I've also tried adding a fourth Variable:
Public Function findUnique(ByVal indexRange As Range, matchRange As Range, matchVal As Long, curRow as Long)
findUnique = Evaluate("=Index(" & indexRange.address & ",AGGREGATE(15,6,Row(" & matchRange.address & _
")/(" & matchRange.address & "=" & matchVal & "),Row(" & curRow & ":" & curRow & ")))")
End Function
and enter like: =findUnique($A$1:$A$5,$B$1:$B$5,1,ROW())
but it just returns a #VALUE error
(Also, how do I avoid ActiveCell.Row, as I have it drilled in to my head to avoid using Active anything...)
Thanks for any thoughts or advice!
From this SO answer, try the following ...
With Application.Caller
CallerRow = .Row
End With
findUnique = Evaluate("=Index(" & indexRange.Address & ",AGGREGATE(15,6,Row(" & matchRange.Address & _
")/(" & matchRange.Address & "=" & matchVal & "),Row(" & CallerRow & ":" & CallerRow & ")))")
I have a whole bunch of data on a whole bunch of sheets and for each of them, I want to find the count of the unique values in a given column.
When I use the following command in a sheeet, it works perfectly
=SUM(IF(FREQUENCY(MATCH(REST!D2:D2225,REST!D2:D2225,0),MATCH(REST!D2:D2225,REST!D2:D2225,0))>0,1))
But when I use an equivalent command inside VBA, I am getting errors
range1 = Cell(2,j).Address & ":" & Cells(k,j).Address
= Application.WorksheetFunction.SUM( Application.WorksheetFunction.IF( Application.WorksheetFunction.FREQUENCY( Application.WorksheetFunction.MATCH(Range(range1),Range(range1),0), Application.WorksheetFunction.MATCH(Range(range1),Range(range1),0))>0,1))
I have tried other combinations, like using
Application.Match
and
Application.Frequency
I've also got "type mismatch errors.
On the other hand, the following function works perfectly
Application.Worksheetfunction.Sum(Range(range2))
The big difference between range1 and range2 is that range2 data is strictly numeric while range1 data is both numeric and string.
EDIT: TO implement BX201's solution
range_TradeID_total_FL = .Cells(2, TradeId_column).Address & ":" & Cells(Finalrow, TradeId_column).Address
doubleQ = Chr(34) & Chr(34)
fStr = "=SUMPRODUCT((range_TradeID_total_FL & " <> " & " & doubleQ & ")/COUNTIF(range_TradeID_total_FL , range_TradeID_total_FL & " & " & " & doubleQ & "))"
var_TOTAL_TradeId_count_FL = Evaluate(fStr)
MsgBox var_TOTAL_TradeId_count_FL
I don't want to store the values in a cell but store it in a variable. But when I do that, the MsgBox gives me the value "True" instead of a number.
#SiddharthRout I am not aware of evaluate. Can you please tell me how it would work in my context, especially when I use variables for range.
Try this (UNTESTED)
This is an example where row is a variable.
Sub Sample()
Dim r1 As Long, r2 As Long
Dim formulaString As String
r1 = 2
r2 = 2225
'=SUM(IF(FREQUENCY(MATCH(REST!D2:D2225,REST!D2:D2225,0),MATCH(REST!D2:D2225,REST!D2:D2225,0))>0,1))
formulaString = "=SUM(IF(FREQUENCY(MATCH(REST!D" & r1 & _
":D" & r2 & _
",REST!D" & r1 & _
":D" & r2 & _
",0),MATCH(REST!D" & r1 & _
":D" & r2 & _
",REST!D" & r1 & _
":D" & r2 & _
",0))>0,1))"
Debug.Print Application.Evaluate(formulaString)
End Sub
A much simpler formula for getting count of unique values in a column is:
=SUMPRODUCT((REST!$D$2:$D$2225<>"")/COUNTIF(REST!$D$2:$D$2225,REST!$D$2:$D$2225&""))
Normal formula so no need to CSE. This works best if there are no conditions attached to your values, like maybe a simple list of names or values.
I think evaluating this should give you the result you want. You can also assign it as a formula to a cell. Either of the following two approaches works, in that regard.
Insert formula into cell
Sub UniqueCount1()
doubleQ = Chr(34) & Chr(34)
fStr = "=SUMPRODUCT((REST!D2:D2225<>" & doubleQ & ")/COUNTIF(REST!D2:D2225,REST!D2:D2225&" & doubleQ & "))"
Range("C1").Formula = fStr
End Sub
Evaluate the formula and insert result into cell
Sub UniqueCount2()
doubleQ = Chr(34) & Chr(34)
fStr = "=SUMPRODUCT((REST!D2:D2225<>" & doubleQ & ")/COUNTIF(REST!D2:D2225,REST!D2:D2225&" & doubleQ & "))"
Range("C1").Value = Evaluate(fStr)
End Sub
A third one approach is to use a scripting dictionary. This is a bit more complicated, but it's pretty fast and can be used in a myriad of ways.
Sub UniqueDict()
Dim oDict As Object
Dim sElem As Variant, sList As Variant
sList = ThisWorkbook.Sheets("REST").Range("D2:D2225").Value
Set oDict = CreateObject("Scripting.Dictionary")
With oDict
For Each sElem in sList
If Not .Exists(sElem) And Not IsEmpty(sElem) Then
.Add sElem, Empty
End If
Next sElem
End With
MsgBox oDict.Count
End Sub
Hope this helps.
EDIT:
Here's an approach using your variables.
startRow = 2 'Or whatever it is based on your other code.
finalRow = 2225 'Or whatever it is based on your other code.
rngStr = "REST!$D$" & Startrow & ":$D$" & Finalrow '$D$2:$D$2225
dQ = Chr(34) & Chr(34) 'Double quote string.
fStr1 = "=SUMPRODUCT((" & rngStr & "<>" & dQ & ")" '=SUMPRODUCT((REST!$D$2:$D$2225<>"")
fStr2 = "/COUNTIF(" & rngStr & "," & rngStr & "&" & dQ & "))" '/COUNTIF($D$2:$D$2225,$D$2:$D$2225&""))
fStr = fStr1 & fStr2 '=SUMPRODUCT((REST!$D$2:$D$2225<>"")/COUNTIF($D$2:$D$2225,$D$2:$D$2225&""))
var_Total = Application.Evaluate(fStr)
MsgBox var_Total
Hope this helps.