Excel Countif in a macro - excel

My countif function works fine in the excel sheet itself as shown below
=COUNTIF(F111506:K111519,">0")
I however do not get the same results when executing this in a macro. Stepping through the macro, I do the see the correct range highlighted.
nonZeroCount = Application.CountIf(Range(("F" & curRow + 5), ("K" & curRow + 18)).Select, ">0")
I always get a value of 0. Can anybody suggest what I am doing wrong?
thanks

Use this one:
nonZeroCount = Application.CountIf(ThisWorkbook.Worksheets("shName").Range("F" & curRow + 5 & ":K" & curRow + 18), ">0")
where shName relevant sheet name.
Or another way:
With ThisWorkbook.Worksheets("shName")
nonZeroCount = Application.CountIf(.Range(.Cells(curRow + 5, "F"), .Cells(curRow + 18, "K")), ">0")
End With

Maybe use the Evaluate command:
FormulaResultCount = Evaluate("CountA(C:C)")
Replace the stuff in quotes with your formula.

Another way to get your desired result is
nonZeroCount = WorksheetFunction.CountIf(Range("F" & curRow + 5, "K" & curRow + 18), ">0")

Related

Excel VBA Lookup two values in same row based on values in three columns

I have a table that looks like this:
Basically, "MatGroup" is a subtype of "StorLoc" which is a subtype of "Department".
I need to look for a match in those three columns, then return the values of two of the other columns to the right (those columns represent weeks).
I've highlighted an example in the picture above. There I'm searching for Department 1101, StorLoc 0001 and MatGroup 1225 in week 4 and 5, which should return the values 243 and 245, which can then be added together = 488.
For testing purpose, I have a working formula that does this in the same worksheet:
=SUMPRODUCT(XLOOKUP(K6&J8&K7;A2:A40&B2:B40&C2:C40;D2:E40))
However, I need a pure VBA solution for this as I'll be pulling this data into a completely separate workbook. I'm not able to use the same solution as in the formula above because apparantly VBA does not allow you to concat multiple criteria with &.
My current solution of using tons of CountIfs is not exactly satisfying and completely a lot more resource intensive than necessary (and messy!):
resultCount = Application.WorksheetFunction.SumIfs(dataWorkBook.Range("A" & departmentStartRow & ":BC" & departmentEndRow).Columns(weekNumber + 1), dataWorkBook.Range("B" & departmentStartRow & ":B" & departmentEndRow), StorLoc, dataWorkBook.Range("C" & departmentStartRow & ":C" & departmentEndRow), MatGroup)
Please, try the next code. It uses an array and should be very fast even for big ranges, working in memory:
Sub LookupThreeConditions()
Dim sh As Worksheet, sh1 As Worksheet, lastRow As Long, arr, i As Long
Dim dep As String, stLoc As String, matGr As String, result As Long
dep = "1101": stLoc = "0001": matGr = "1225"
Set sh = ActiveSheet
Set sh1 = sh.Next 'use here the sheet you need to copy in
lastRow = sh.Range("A" & sh.rows.Count).End(xlUp).row
arr = sh.Range("A2:F" & lastRow).value 'put the range in an array
For i = 1 To UBound(arr)
If arr(i, 1) & arr(i, 2) & arr(i, 3) = dep & stLoc & matGr Then
result = arr(i, 5) + arr(i, 6): Exit For
End If
Next i
MsgBox "Result is " & result
sh1.Range("A1").value = result 'use here what range you need
End Sub

Giving formula to a cell which has Unknown Range [ERROR]

I'm basically trying to give a formula to a cell including unknown range. But I'm keep getting error. "inpt1" changes according to inpt1's count so I cannot formulate that. As inpt1 changes I cannot control the sum formula due to its range changes as well. Let me illustrate;
Cells(inpt1 + 3, 4).Formula = "=SUM(" & Range(Cells(3, 9), Cells(inpt1 + 2, 9)) & ")"
I added an example image for you guys to understand it better.
Try to sum the prices of I3:I5 & write it as a formula in green area in the picture
Can you try this:
Cells(inpt1 + 3, 4).Formula = "=SUM(I9:I" & inpt1 + 2 & ")"
Good luck
You need to return a string to the Formula.
Currently:
Range(Cells(3, 9), Cells(inpt1 + 2, 9))
Is trying to return a variant array to the formula string. A variant array cannot be converted to a string.
You want the address string. To get that we add .Address to the end of the Range:
Range(Cells(3, 9), Cells(inpt1 + 2, 9)).Address

get the differences between 2 Integer columns into third column

I have to calculate the difference between the values of 2 columns(firstCol and lastCol) and set those differences in a different column(NextColumn). The row count keeps changing, so I have to calculate the rowCount before calculating the difference. I'm trying to write a loop using Range so that the difference can be calculated but it doesn't seem to work.
For i = 3 To lastRow
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).FormulaR1C1 = "=Range(Cells(i, firstCol),Cells(i,firstCol)).Value - Range(Cells(i, lastCol),Cells(i,lastCol)).Value"
Next i
Any help would be greatly appreciated!
Thank you
Nick
For any input of "i" into the formula, you need to use " & i & " when using using a formula="", such as:
"=A" & i & "+B" & i
When you change to just a formula that doesn't input a formula to the cell (math happens in VBA), you can ignore the Excel formatting and "" blocking, such as:
= Cells(i,"A").Value + Cells(i,"B").Value
Make sure to use your loop variable where appropriate, so that you would have an outcome in a loop like:
Dim i as Long
For i = 1 to 10
Cells(i,"C").Formula = Cells(i,"A").Value + Cells(i,"B").Value
Next i
Why looping ? Unless I misunderstood the question, something like this should do the trick:
Range("X3:X"& lastrow).Formula = "=C3-D3"
The formula will adjust.
vba needs to be outside the quotes and you do not need the loop:
Range(Cells(3, NextColumn), Cells(lastRow, NextColumn)).Formula = "=" & Cells(3, firstCol).Address(0, 0) & "-" & Cells(3, lastCol).Address(0, 0)
No loop needed. Excel will change the relative references as needed.

Concatenating SumIfs in VBA

I'm trying to get this segment of code to execute. This is a simplified version of the code. I've included the relevant code. I'm trying to concatenate strings and named ranges into a SumIfs formula, but I get error 1004 "Application-defined or Object-defined error." I have a working line of code above this problem section that is similar with the exception of doing a sum function, instead of sumif. Any idea how to get this code to execute? Thank you.
Dim wb As Workbook
Dim ara As Worksheet
Dim inv As Worksheet
Dim ARBlock As Range
Dim Invoices As Range
Dim AgedDays As Range
Set wb = ThisWorkbook
Set ara = wb.Sheets("AR Aging")
Set inv = wb.Sheets("Invoices")
Set ARBlock = ara.Range("a6")
Set Invoices = inv.Range("a6", inv.Range("a6").End(xlDown))
Set AgedDays = Invoices.Offset(0, 6)
'Populate A/R age buckets
For i = 6 To ARBlock.Rows.Count + 6
With ARBlock(i - 5, 1).Offset(0, 3)
.Value = "=SumIfs(" & Invoices.Offset(0, 4).Address & "," & _
Invoices.Address & "," & ARBlock(i - 5, 1).Value & "," & _
Invoices.Offset(0, 6).Address & ","" <= "" & &O30)"
End With
Next i
End Sub
The line beginning with ".value" is where I'm getting the error message. P.S.: I need the cell to contain the concatenated formula, as opposed to the output value.
UPDATE 1:
As some suggested I updated the .value line to:
.Offset(0, 3).Formula = "=SumIfs(Invoices.Offset(0, 4).Address,Invoices.Address,ARBlock.cells(i - 5, 1).Value)"
I'm still getting the same error. Some auditing I've done:
Removing the "=" before "Sumifs" allows the code to run fine; pasting in the formula into the target cell as text. In this form, my output for i=1 goes to ARBlock.cells(1,1), as it should.
I also used Debug.Print to view all of the components of the formula:
Debug.Print ARBlock.Cells(i - 5, 1).Address
'output $A$6
Debug.Print ARBlock.Cells(i - 5, 1).Value
' output International Business Machines
Debug.Print Invoices.Offset(0, 4).Address
'output $E$6:$E$255
Debug.Print Invoices.Address
'output $A$6:$A$255
I suspected the issue might be that the range dimensions might have been off, but this is not the case. My next suspicion is that the output International Business Machines needs to be in " " for the formula to read it correctly. I hardcoded in
""International Business Machines""
to see if this would fix the formula, but I keep getting the same error once I add the "=" back in. The formula syntax is correct, the dimensions are the same between the sum range and criteria range. Anyone else have any ideas?
.Offset(0, 3).Formula = "=SumIfs(Invoices.Offset(0, 4).Address,Invoices.Address,ARBlock.cells(i - 5, 1).Value)"
Change to:
.Offset(0, 3).Formula = "=SumIfs(" & Invoices.Offset(0, 4).Address & ", " & Invoices.Address & ", " & chr(34) & ARBlock.Cells(i - 5, 1).Value & chr(34) & ")"
EDIT: Added quotes chr(34) around your string!
Your ARBlock(i - 5, 1).Value most likely is an empty cell, which messes the SUMIFS formula as it builds it with to consecutive commas

selecting an entire row based on a variable excel vba

I am trying to select an entire row in a different sheet and then copy the row to the sheet I am currently in with a macro. The code works fine if the Rows() sub is passed integers hardcoded but when I put a variable I get the "Select method of Range class failed" error. here is the code I have:
Sheets("BOM").Select
Rows(copyFromRow & ":" & copyFromRow).Select
Selection.Copy
Sheets("Proposal").Select
Rows(copyToRow & ":" & copyToRow).Select
ActiveSheet.Paste
copyToRow = copyToRow + 1
Rows(copyToRow & ":" & copyToRow).Select
Application.CutCopyMode = False
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
if instead i used :
Rows("52:52").Select
Selection.Copy
it works fine, but when the variable is there, the error occurs.
Thanks
I just tested the code at the bottom and it prints 16384 twice (I'm on Excel 2010) and the first row gets selected. Your problem seems to be somewhere else.
Have you tried to get rid of the selects:
Sheets("BOM").Rows(copyFromRow).Copy
With Sheets("Proposal")
.Paste Destination:=.Rows(copyToRow)
copyToRow = copyToRow + 1
Application.CutCopyMode = False
.Rows(copyToRow).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
Test code to get convinced that the problem does not seem to be what you think it is.
Sub test()
Dim r
Dim i As Long
i = 1
r = Rows(i & ":" & i)
Debug.Print UBound(r, 2)
r = Rows(i)
Debug.Print UBound(r, 2)
Rows(i).Select
End Sub
I solved the problem for me by addressing also the worksheet first:
ws.rows(x & ":" & y).Select
without the reference to the worksheet (ws) I got an error.
Saw this answer on another site and it works for me as well!
Posted by Shawn on October 14, 2001 1:24 PM
var1 = 1
var2 = 5
Rows(var1 & ":" & var2).Select
That worked for me, looks like you just have to keep the variables outside the quotes and add the and statement (&)
-Shawn
The key is in the quotes around the colon and &, i.e. rows(variable & ":" & variable).select
Adapt this:
Rows(x & ":" & y).select
where x and y are your variables.
Some other examples that may help you understand
Rows(x & ":" & x).select
Or
Rows((x+1) & ":" (x*3)).select
Or
Rows((x+2) & ":" & (y-3)).select
Hopefully you get the idea.
You need to add quotes. VBA is translating
Rows(copyToRow & ":" & copyToRow).Select`
into
Rows(52:52).Select
Try changing
Rows(""" & copyToRow & ":" & copyToRow & """).Select
One needs to make sure the space between the variables and '&' sign.
Check the image. (Red one showing invalid commands)
The correct solution is
Dim copyToRow: copyToRow = 5
Rows(copyToRow & ":" & copyToRow).Select
mycell = ActiveCell
r = mycell.Row
c = mycell.Column
Range(Cells(r, c), Cells(r + 100, c)).Select

Resources