Concatenating SumIfs in VBA - excel

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

Related

vba Sumif with variables and R1C1

I'm trying to run the below code and it gives me
Run-Time Error "1004"
Application-defined or Object-defined error
Every Single Time!!
Attached is a snippet of the code, any suggestions what's wrong? (The numbers in the Range(Cells( * ) sections are actually mostly variables in my overall macro, it's pretty complex but I've taken them out for simplicity here)
Code:
'Declare variables
Dim CriteriaRng As String
Dim SumRng As String
Dim Criteria As String
'Set a variable for each of the 3 parts of the SUMIF Formula
CriteriaRng = "'" & Sheets(1).Name & "'!" & Range(Cells(2, 4), Cells(88, 4)).Address
SumRng = "'" & Sheets(1).Name & "'!" & Range(Cells(2, 3), Cells(88, 3)).Address
Criteria = Chr(34) & "=" & Chr(34) & " & RC[-1]"
'Here goes the SUMIF Formula
With Sheets(2).Range(Cells(4, 13), Cells(9, 13))
Debug.Print "So the Whole Formula Should be:" & Chr(13) & "= SUMIF(" & CriteriaRng & ", " & Criteria & ", " & SumRng & ")"
'That was a vain attempt to find out what was wrong with the formula; didn't work though.
.FormulaR1C1 = "= SUMIF(" & CriteriaRng & ", " & Criteria & "," & SumRng & ")"
'Then adds NumberFormat and stuff here, but that isn't relevant to this question.
End With
The error always hits on the line where it's putting in the .FormulaR1C1 = .
Yes, I know I could get the same result using a nested loop, but that would return just the value without the SUMIF formula - I need that formula so the sheet updates when edited (without needing a macro - I'm sending the sheet on to other people who won't have or want any macros, but might need to edit the data).
Can anyone point out to me what is wrong? I'm prepared for it to be something pretty basic - only last week I spent 2 hours figuring out a problem from misspelling 'Columns' !!!
Any and all advice welcome - Many Thanks in advance.

Excel VBA For Loop writing Formula in cells depending on the number in the loop

I am trying to write a Forumla in cells (from cell A2 to AI, where I is the number in the For Loop).
The formula to be written must correspond to Cell M2 to MI, also where I is the number in the For Loop.
I am able to write the sheet-reference by itself:
ws.Cells(1 + I, KolonneForX + 1).Formula = " ='" & ws.Name & "'"
which gives me the formula ='Ark1' (by it self) in the cells i want.
And also the right name of cell to read:
ws.Cells(1 + I, KolonneForX + 2).Formula = "=CONCATENATE(""M"",TEXT(" & I & "+1,""0""))"
which gives me the formula MI (by it self, with the corresponing number for I) in the cells i want.
But when I try to put the two of them togheter, I can't get it to run and refer to the right cells.
This is the code I have been trying to run:
Sub OppretteKnutepunkt()
Dim ws As Worksheet
Set ws = Worksheets("Ark1")
Dim KolonneForX As Integer
For I = 1 To 5
ws.Cells(1 + I, KolonneForX + 2).Formula = "='" & ws.Name & "'!CONCATENATE(""M"",TEXT(" & I & "+1,""0""))"
Next I
End Sub
I want the Cell A2 to have the following formula:
='Ark1'!M2
I want the Cell A3 to have the following formula:
='Ark1'!M3
and so on.
Any suggestions?
You can achieve this without looping
Dim I as Long
I = 7
With ws.Range("A2:A" & I)
.Formula = "='" & .Parent.Name & "'!M2"
End With
With is a shorthand way of using the same prefix on a block of code. The VBA compiler prefixes everything that begins with a . with whatever is declared by the With block
The equivalent of the above would be:
ws.Range("A2:A" & I).Formula = "='" & ws.Range("A2:A" & I).Parent.Name & "'!M2"

Adding freshly created formula into new module

I've just created a brand new macro. Took function down below from internet (all credits goes to trumpexcel.com), code down below
Function CONCATENATEMULTIPLE(Ref As Range, Separator As String) As String
Dim Cell As Range
Dim Result As String
For Each Cell In Ref
Result = Result & Cell.Value & Separator
Next Cell
CONCATENATEMULTIPLE = Left(Result, Len(Result) - 1)
End Function
Then I proceed to extract data from various columns and into the one (my table is 20 rows x 10 columns)
Sub conact_data()
Dim i As Integer
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Cells(i, "M").Value = Cells(i, "A").Value & " " & _
Cells(i, "B").Value & " / " & Cells(i, "D").Value & "; "
Next i
End Sub
Thanks to that I've got combined data from column A, B and D, so its 20 rows. All I want to do now is to concatenate data from M2:M21 using CONCATENATEMULTIPLE function therefore I try various approach (I want this huge line in P2 cell) like :
Cells(2, 16).Value = CONCATENATEMULTIPLE (M2:M21, " ")
or
Range("P2") = "CONCATENATEMULTIPLE (M2:M21, " ")"
I don't really know how to apply that
Secondly, I'd like withdraw the Cells(i, "B").Value as percentage. Can I do that in one line like Cells(i, "B").NumberFormat="0.00%".Value (which is not working for me obviously) else I need to copy column B into another column with number format and then combine the new column, properly formatted instead of column B?
Thanks in advance
Percent format: Range("B" & i).NumberFormat = "0.00%"
CONCATENATEMULTIPLE
In VBA, CHR(32) = " "
In Excel, CHAR(32) = " "
With that being said...
'Value
Range("P2").Value = CONCATENATEMULTIPLE(Range("M2:M21"), CHR(32))
'Formula
Range("P2").Formula = "=CONCATENATEMULTIPLE(M2:M21, CHAR(32))"
You should really qualify all of your ranges with a worksheet
Say your workbook has 10 sheets. When you say Range("P2"), how do we (VBE) know what sheet you mean? Objects need to be properly qualified. Sometimes this is not a huge issue, but when you are working across multiple sheets, not qualifying ranges can lead to some unexpected results.
You can qualify with a worksheet a few ways.
Directly: ThisWorkbook.Sheets("Sheet1").Range("P2").Copy
Or use a variable like so
Dim ws as Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("P2").Copy
Now there is no room for ambiguity (potential errors) as to the exact location of Range("P2")
First of all, remove your ConcatenateMultiple() code, and instead use Excel worksheet function CONCAT(), which takes a range and a delimiter as parameters.
Here is how you can handle the percentage issue and supply a default for non-numeric items. I've also cleaned up the way you reference your data range.
Sub concat_data()
Dim rngRow As Range, vResult As Variant
Const DEFAULT = 0 'Can also be set to a text value, eg. "Missing"
For Each rngRow In [A2].CurrentRegion.Rows
If IsNumeric(rngRow.Cells(, 4)) Then vResult = rngRow.Cells(, 4) * 100 & "%" Else vResult = DEFAULT
Range("M" & rngRow.Row) = rngRow.Cells(, 1) & rngRow.Cells(, 2) & "/" & vResult & ";"
Next
[M2].End(xlDown).Offset(1).Formula = "=CONCAT(M2:M" & [M2].End(xlDown).Row & ",TRUE,"" "")"
End Sub
I'm not a fan of hard-coding range references, like the [A2] or Range("M"), but will leave that for another time.

VBA Excel: Run-time error 13 type mismatch due to too many characters

I'm working on a 'dashboard' in excel where the user can select a commodity and then presses the run button, so the code then prints out all suppliers linked to that commodity. (Several commodities and supplier names are listed on other tabs in the same workbook, and the code goes over all tabs to collect the right supplier names)
EDIT: the issue is due to a supplier name being longer than 255 characters.
The debugger focuses on this code in particular:
If Application.Evaluate("COUNTIF(" & myDataRng.Address & "," & cell.Address & ")") > 1 Then
cell.Offset(0, 0).Font.Color = vbRed
End If
This code is part of the bigger set below. The code highlights all suppliernames that are listed under the chosen category in different tabs (hence they would be printed out multiple times, I want to highlight the duplicate values).
'##### Find duplicates in commodity column and highlight them ######
Dim myDataRng As Range
Dim cell As Range
Set myDataRng = Range("E10:E" & Cells(Rows.Count, "E").End(xlUp).Row)
For Each cell In myDataRng
cell.Offset(0, 0).Font.Color = vbBlack
If Application.Evaluate("COUNTIF(" & myDataRng.Address & "," & cell.Address & ")") > 1 Then
cell.Offset(0, 0).Font.Color = vbRed
End If
Next cell
Any idea what it could be?
The error is not immediately obvious. I made a few tweaks to the code, however this should allow you to see what's being evaluated. Typically you'd get this error from the formula not being entered with the correct format, but it works on my end.
I removed the Offset(0,0) as it is superfluous at present with no offset applied, as well as placing the vbBlack formatting in an Else block for performance/clarity.
However seeing the Debug.Print statement should be critical for understanding when the code is not functioning. The only other thought I have, is you may want to clarify which sheet this Countif is being completed on.
Update
I've revised my answer to use SumProduct instead of CountIf to workaround the issue of 255 characters being the limit for CountIf.
Public Sub TestSub()
Dim myDataRng As Range
Dim cell As Range
Dim EvalStr As String
Set myDataRng = Range("E10:E" & Cells(Rows.Count, "E").End(xlUp).Row)
For Each cell In myDataRng
EvalStr = "SumProduct((" & myDataRng.Address & "=" & cell.Address & ")+0)"
If Application.Evaluate(EvalStr) > 1 Then
cell.Font.Color = vbRed
Else
cell.Font.Color = vbBlack
End If
Next cell
End Sub
Change your line:
If Application.Evaluate("COUNTIF(" & myDataRng.Address & "," & cell.Address & ")") > 1 Then
With:
If Application.Evaluate("COUNTIF(" & myDataRng.Address & "," & cell.Address & " > 1 )") Then

Excel VBA code mid function

I have the following string "123 - 456789". What I am trying to do is find a way to only capture the remaining characters after the second space - "456789" - regardless the length of the string.
I have the follow set of code:
For leftLoop = 2 To leftNumberOfCells
Range("A" & iRow) = Split(Range("B" & iRow).Value, " ")
Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)
iRow = iRow + 1
Next leftLoop
The code line "Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)" is what I tried, among other ways (from searching online, but I can't seem to get it to work.
I have two questions:
Does someone know what the correct code should be? and...
Can I reference the cell where the string is located and replace it in that same cell after doing the mid function without having to temporarily put it into another cell and copy and paste it back? For example, my string "123 - 456789" is in cell B2, is there a way to code it so I can reference cell B2 and simultaneous replace the cell B2 with "456789" and not having to place it in another cell then copy and paste it back into B2. I hope you get what i'm asking.
Thanks for you help!
This addresses part 2.
Sub strings()
Dim replace As String
Dim bCell As Range
For leftLoop = 2 To leftNumberOfCells
Set bCell = Range("B" & iRow)
replace = Mid(bCell, InStr(bCell, "-") + 2, 100)
Range("B" & iRow) = replace
iRow = iRow + 1
Next leftLoop
End Sub
Try this:
result = Split(TextToSplit, " ", 3)(2)
Split(TextToSplit, " ", 3) will split the text on spaces, returning a zero-based array. The last argument 3 limits the splitting to 3 portions: before the first space, between the first and second space, and everything else. The (2) at the end of the statement returns the last element of the array.
Hope that helps

Resources