Varying ranges in sum and criteria range for IF statments - vba

Hey guys I need help with my novice skills at VBA code writing. I would like to modify the code below to accommodate the varying ranges of data rows for my sum range and criteria range in a SUMIF statment.
Sub sumifstate ()
Set critRange = Range("K2", Selection.End(xlUp).Offset(-1, 0)).Select
Set sumRange = Range("L2", Selection.End(xlUp).Offset(-1, 0)).Select
Set critRange2 = Range("M2", Selection.End(xlUp).Offset(-1, 0)).Select
Set sumRange2 = Range("N2", Selection.End(xlUp).Offset(-1, 0)).Select
Range("K41").Select
ActiveCell.FormulaR1C1 = _
"= (SUMIF("critRange",""*DF*"","sumRange")+SUMIF("critRange2,""*DF*"","sumRange2")"
End Sub ()
I hope I was specific enough if not let me know what other information you might need. Thank you!

There is no guarantee that all four of those columns have data in the same last row. However, each SUMIF requires that all ranges have the same size. Use the same formula for each of the pairs. You are also not evaluating hte formula within VBA, merely constructing a string together. You can use the ranges' addresses as strings for this.
Sub sumifstate()
Dim lr As Long, critRange As String, sumRange As String, critRange2 As String, sumRange2 As String
lr = Cells(Rows.Count, "L").End(xlUp).Row
critRange = Range("K2:K" & lr).Address
sumRange = Range("L2:L" & lr).Address
lr = Cells(Rows.Count, "N").End(xlUp).Row
critRange2 = Range("M2:M" & lr).Address
sumRange2 = Range("N2:N" & lr).Address
Range("K41").Formula = _
"=SUMIF(" & critRange & ", ""*DF*"", " & sumRange & ")+SUMIF(" & critRange2 & ", ""*DF*"", " & sumRange2 & ")"
End Sub
The formula produced will be dynamic but in this format.
=SUMIF($K$2:$K$10, "*DF*", $L$2:$L$10)+SUMIF($M$2:$M$10, "*DF*", $N$2:$N$10)

Hi,
So where you've got R[-39] or R[-3], you want to insert a variable for your actual calculated rows?
intStartRow = GetStartRow() ' i.e. however you define it, set a variable
intEndRow = GetEndRow()
Then replace where needed:
ActiveCell.FormulaR1C1 = _
"=(SUMIF(R[" & intStartRow & "]C:R[" & intEndRow & "]C, ...
i.e. use concatenate symbol "&",
Either that or use "=Offset" formula combined with Counta: that allows you to have "growing/shrinking" ranges without having to rerun your code

Related

VBA Sumifs to paste result as values

Would like to know how to code properly a SUMIFS formula and paste the results as value only.
Is it also possible to just have the formula loop only on blank cells? I tried running the code and it seems that is pastes the formula for all cells.
I've attached a sample code which I only got from other forums for reference. Would really appreciate your help guys!
Option Explicit
Sub SumGroups()
Dim lastCode As Long, lastFiltCode As Long
'Determine Last Row in Column O (Unfiltered Codes)
With Worksheets("Database")
lastCode = .Range("O" & .Rows.Count).End(xlUp).Row
End With
With Worksheets("Sheet3")
'Determine last Row in Column A (Filtered Codes)
lastFiltCode = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:K" & lastFiltCode).Formula = _
"=SUMIFS(Database!$M$2:$M$" & lastCode & ",Database!$O$2:$O$" & lastCode & ",$A2,Database!$I$2:$I$" & lastCode & ",B$1)"
End With
End Sub
You just have to have the work occur in VBA:
cells(1,1).value = Application.SumIfs(Range(Cells(1,1),Cells(10,1)),Range(Cells(1,2),Cells(10,2)), "<0")
Or, you can do this AFTER you have shown the formulas, so the value of the formula is pasted in place of the formula:
cells(1,1).value = cells(1,1).value
Edit1:
To point out why your code is entering the formula, by using .Formula = "", you are telling the system to display within the defined range that exact information. These each enter whatever is within the quotations to the cell:
cells(1,1).value = "Cat"
cells(1,1).formula = "=A1+B1"
cells(1,1).formula = "=A" & i & "+B" & i 'where i is a variable

VBA Testing two values, if one is different, copy

I am having a fair amount of trouble with the code below:
Sub TestEmail()
Dim i As Long
Dim LastRow As Long
Dim a As Worksheet
Dim b As Worksheet
Dim strText
Dim ObjData As New MSForms.DataObject
Set a = Workbooks("Book2").Worksheets(1)
Set b = Workbooks("Book1").Worksheets(1)
LastRow = a.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To LastRow
If Not IsError(Application.Match(a.Cells(i, 7).Value, b.Columns(3), 0)) And IsError(Application.Match(a.Cells(i, 4).Value, b.Columns(11), 0)) Then
a.Range("D" & i).Copy
ObjData.GetFromClipboard
strText = Replace(ObjData.GetText(), Chr(10), "")
b.Range("K" & ).Value = b.Range("K" & ).Value & " / " & strText
End If
Next i
End Sub
I face two problems, one has me stumped and the other is due to lack of knowledge:
The line after IF is supposed to check if two values (numbers) in both workbooks match, and if two other values (text) don't match. If all true, then it must copy a value from Book2 and add it to a cell in book1.
The problems are:
-The macro doesn't seem to recognise when the values match or not.
-In the last line before "End If", I don't know how to tell excel to copy the text into the cell that didn't match in the second check.
I am sorry if I am not clear enough, this is hard to explain.
I'm hoping one of the experts knows how to make this work.
Thanks in advance
You are using If Not condition 1 And condition 2, so you are saying that if it doesn't match both conditions, Then you run the code. What you want to make are Nested If Statements However, one is If and the other If Not
To copy you are missing the i After "K"&: b.Range("K" & i) = b.Range("K" & i).Value & " / " & strText
The Address of the Cells are inside the Range Function, which in your case would be:
//It is the cell of the email from the first Workbook tou are copying, where you input the column D
a.Range("D" & i).Copy
//Add to Workbook b in column K the value from Cell K#/value copied
b.Range("K" & i) = b.Range("K" & i).Value & " / " & strText
You can also make it like this: b.Range("K" & i) = b.Range("K" & i).Value & " / " & a.Range("D" & i)
This way you are matching lines, so only if the IDs are on the same rows on both Workbooks it will work. If they aren't, you will have to use Nesting Loops or .Find Function
EDIT:
If I understood it, the code below might work if you make some changes for your application, because i didn't have the data to test and columns, etc. Try to implement it.
LastRowa = a.Cells(Rows.Count, "A").End(xlUp).Row
LastRowb = b.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To LastRowa
'Address of String to look for
LookForString = a.Worksheets(1).Cells(i, 4) '4 is the COLUMN_INDEX
'Range to look on Workbook a
With a.Worksheets(1).Range("D1:D" & LastRowa) 'choose column to look
'Function .Find String on book a
Set mail_a = .Find(LookForString, LookIn:=xlValues)
If Not mail_a Is Nothing Then
FirstAddress = mail_a.Address
Do ' Actions here
'Range to look on Workbook b
With b.Worksheets(1).Range("K1:K" & LastRowb) 'choose column to look
'Function .Find on Workbook b
Set mail_b = .Find(LookForString, LookIn:=xlValues)
If Not mail_b Is Nothing Then
FirstAddress = mail_b.Address
Do 'Actions
'Verify if two other values (text) don't match
If Not WRITE_MATCH_CONDITION_HERE Then
'No need to verify of they are equal because the .Find function used the same reference
'I will use .Cells with .Row and .Column just to show another way to do it and make it dynamic
b.Cells(mail_b.Adress.Row, mail_b.Adress.Column) = b.Cells(mail_b.Adress.Row, mail_b.Adress.Column).Value & " / " & a.Cells(mail_a.Adress.Row, mail_a.Adress.Column) 'choose columns
End If
Set mail_b = .FindNext(mail_b)
Loop While Not mail_b Is Nothing And mail_b.Address <> FirstAddress
End If
End With
Set mail_a = .FindNext(mail_a)
Loop While Not mail_a Is Nothing And mail_a.Address <> FirstAddress
End If
End With
Next i
End Sub
p.s.: The <> is missing on mail_a.Address <> FirstAddress and mail_b.Address <> FirstAddress, when i posted with

VBA : Sumif function not working

Hi I am writing a code for sum the data based on criteria. The below code working perfectly but it not return value. The code works on the excel like this (= SUMIF($B$1:$DC$1,p,B2:DD2). The reason is Criteria P Need double quotation.how to add the double quotation to P and any suggestion would be appreciated
Sub ashok()
Dim LR As Long
Dim Rg, Rg1 As Range
ActiveSheet.Range("a1").Select
LR = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
ActiveCell.Columns("A:A").EntireColumn.Select
Selection.NumberFormat = "0"
ActiveSheet.Range("a1").Select
Set Rg = Range("b1", ActiveSheet.Range("A1").End(xlToRight))
Set Rg1 = Range("b2", ActiveSheet.Range("A2").End(xlToRight))
Range("a1").End(xlToRight).Select
With ActiveCell.Offset(1, 1).Resize(LR)
.Formula = "= SumIf(" & Rg.Address(True, True) & "," & "P" & "," & Rg1.Address(False, False) & ")"
End With
End Sub
The answer to your question is use Chr(34):
.Formula = "= SumIf(" & Rg.Address(True, True) & "," & Chr(34) & "P" & Chr(34) & "," & Rg1.Address(False, False) & ")"
However, you have way too much (unnecessary and should stay away from) use of Select, ActiveSheet, ActiveCell and Selection.
An example of how your code could look if you use fully qualified objects:
With Sheets("Sheet3") ' <-- replace with your sheet's name
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
.Columns("A:A").EntireColumn.NumberFormat = "0"
Set Rg = .Range("B1", .Range("A1").End(xlToRight)) '<-- NOT SURE this make sense !
Set Rg1 = .Range("B2", .Range("A2").End(xlToRight)) '<-- NOT SURE this make sense !
' etc. etc.
End With ' closing the With

concatenate range of cells in RC style notation vba macros

I am performing a linear interpolation for my class project. I have created an interpolation function and have to perform calculation dynamically, as the number of column varies for each problem. So, I have retrieved the value for last column(ltr) and trying to concatenate it with R1C1 format. But it doesn’t work. Could you please suggest some idea, how do workaround for this issue.
Please find below the following code:
Private Sub TrialCheck_Click()
Dim lrt As Double
With ActiveSheet
'retrives last column i.e lrt = 447
lrt = .Cells(.Rows.Count, "F").End(xlUp).Row
End With
Range("I3").Value = Range("F3").Value * Range("B3").Value
Range("I58").Value = Range("F" & lrt).Value * Range("B58").Value
'MacroR
'following works as 447 is hardcoded
'Range("I4").Value = _
"=(LinInterp(RC[-8],R4C[-4]:R447C[-4],R4C[-3]:R447C[-3])*RC[-7])"
'following code doesn't concatenate value of lrt
Range("I4").Value = _
"=(LinInterp(RC[-8],R4C[-4]:R&lrt&C[-4],R4C[-3]:R&lrt&C[-3])*RC[-7])"
Range("J4").Select
Range("I4").AutoFill Destination:=Range("I4:I57"), Type:=xlFillDefault
Range("I4:I57").Select
End Sub
you have to do string concatenation
"string" & lrt & "string" & lrt & "string"
Range("I4").Value = _
"=(LinInterp(RC[-8],R4C[-4]:R" & lrt & "C[-4],R4C[-3]:R" & lrt & "C[-3])*RC[-7])"

countif outputting "true" or "false" rather than number vba

I have been trying to code a countif function into a loop, however, I am having a little trouble with the outputs. Instead of reading a number when the computation occurs, the function keeps outputting "true" or "false". Maybe there is an error in my code, but I have used many countif functions in the past without experiencing a problem such as this. As you can see below, I tried to write the function in two different ways, but both either didn't work or outputted "true" or "false".
Please Help.
Sub CorrectSets()
Dim Cell As Range
Range("B100000").End(xlUp).Select
LastRow = ActiveCell.Row
For Each Cell In Range("S2:S" & LastRow)
StartTime = Cell.Offset(0, -12)
Shift = Cell.Offset(0, -14)
SortedOp = Cell.Offset(0, -17)
DOW = Cell.Offset(0, -5)
'Cell.Value = CountIF(E2:E & LastRow, Shift, N2:N & LastRow ,DOW, B2:B & LastRow,SortedOp, G2:G & LastRow, " < " & StartTime)
Cell.Value = "=CountIF(E2:E" & LastRow & ", " & Shift & ", N2:N" & LastRow & "," & DOW & ", B2:B" & LastRow & "," & SortedOp & ", G2:G" & LastRow & ", " < " " & StartTime & ")"
Next Cell
If you want to put a countif() Formula in Cell then:
Cell.Formula = "=CountIF(E2:E &...............
If you want to put the formula's result in Cell then:
Cell.Value = Application.Worksheetfunction.CountIF(E2:E &....................
You should use
Cell.Formula = "=CountIFs..."
or
Cell.Value = WorksheetFunction.CountIfs...
See official documentation.
Plus:
To find the last row containing data in a column (B in this case) use
Dim ws as Worksheet
Set ws = ActiveSheet
Dim LastRow as Long
LastRow = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
ws is a reference to the Worksheet of interest (ActiveSheet in my example).
See this answer.
You'd rather fully qualify your ranges, and avoid using Select unless it is strictly needed.
With the code posted above,
Range("B100000").End(xlUp).Select
might not be needed.
If using Cell.Formula = "=CountIFs...", it might be convenient to use
Dim frm as String
frm = "=CountIFs..."
Cell.Formula = frm
for easier debugging.