Excel-VBA Named range row sum - vba

I have the following code
For i = 1 To DepRng.Rows.Count
For j = 1 To DepRng.Columns.Count
DepRng.Cells(i, j) = Application.Sum(KidsRng.Row(i)) //Does not work
Next j
Next i
Although I know is wrong, i have no idea how to get it to store in DepRng.Cells(i, j) the total sum of the whole KidsRng.Row[i] Any help?

The following code works ok.
Perhaps you should compare it with yours:
Sub a()
Dim DepRng As Range
Dim kidsrng As Range
Set DepRng = Range("B1:B2")
Set kidsrng = Range("C1:F2")
For i = 1 To DepRng.Rows.Count
DepRng.Cells(i, 1) = Application.Sum(kidsrng.Rows(i))
Next i
End Sub
Just fill the range C1:F2 with numbers and the totals per row will appear in B1:B2 upon execution of the macro.

Sorted, thanks all for ur help
DepRng.Cells(i, j) = Application.Sum(KidsRng.Rows(i)) //just needed to add the "s" in rows

There may be a better way than this, but this is my solution which depends on the internal Excel formula engine though, it might be sufficient enough for what you're doing... It determines the full address of KidsRng.Row(i), and feeds it into a =SUM() formula string and evaluated by Application.Evaluate.
For i = 1 To DepRng.Rows.Count
For j = 1 To DepRng.Columns.Count
DepRng.Cells(i, j).Value = Application.Evaluate("=SUM(" & KidsRng.Row(i).Address(True, True, xlA1, True) & ")")
Next j
Next i
updated it to work if kidsrng existed in a different sheet/book
updated to use Application.Evaluate

Related

In excel If test passes when value typed manually but fail from a cell

Using excel VBA, I have constructed a dictionary and populated it. I did my tests and it's well done.
After that, in a loop I had to test if a key exists to do some operations:
For i3 = 2 To n 'n is the the number of rows
If dicos.Exists(ActiveSheet.Range("T" & i3)) Then
ActiveSheet.Range("N" & i3) = dicos(ActiveSheet.Range("T" & i3)) + 1
Else
ActiveSheet.Range("N" & i3) = 1
End If
Next
It doesn't work and I have 1 in all the column N. I tried to test with some values from the column T manually and it finds it!
Can anyone explain to me what I have done wrong and why the test is positive when I type the value manually and it is negative when the program has to take it from a cell (column T)?
Thank you very much.
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim dicos As Dictionary
Set dicos = new Dictionary
'Populate dicos....
For i = 2 To n 'n is the the number of rows
If dicos.Exists(ws.Cells(i, 20).Value) Then
ws.Cells(i, 14) = dicos.Item(ws.Cells(i, 20).Value) + 1
Else
ws.Cells(i, 14) = 1
End If
Next
I believe the problem was that you didn't use .Value on the additive line, thus it was just putting 1 in there. When I tested your code as-posted I changed the +1 to a +4 and got 4 in cells(i,14) instead of 1.

Excel range subtraction, overlooking errors in some cells possible?

I am having trouble figuring out how to subtract two ranges from each other, some cells in range H:H have "#N/A" while in range D:D there are no errors. I know in Excel it's a simple "=H2-D2" and drag that down but I'm in the process of recording a Macro and wanted to automate the subtraction as well. So far this is what I have:
Dim quantity1, quantity2, rIntersect, Qdiff, x As Range
Set quantity1 = Range("D:D")
Set quantity2 = Range("H:H")
Set rIntersect = Intersect(quantity1, quantity2)
For Each x In quantity1
If Intersect(rIntersect, x) Is Nothing Then
If Qdiff Is Nothing Then
Set Qdiff = x
Else
Set Qdiff = Application.Union(Qdiff, x)
End If
End If
Next x
Range("J2").Select
Dim lastRowJ As Long
lastRowJ = Range("A" & Rows.Count).End(xlUp).Row
Range("J2").AutoFill Destination:=Range("J2:J" & lastRowJ)
Place this procedure in a standard code module:
Public Sub Subtract()
[j2:j99] = [h2:h99-d2:d99]
End Sub
If you like how that works, I'm happy to embellish it so that it is not hard-coded for 98 rows only. Let me know.
UPDATE
Here is a version that will deal with any number of rows. It keys off of column D. So if there are 567 numbers in column D, then you will get 567 corresponding (subtracted) results in column J.
This assumes that the data start in row 2, and that there are no blank cells until the numbers in column D end.
If you are going to call this from the Macro Dialog then you should keep it Public. If on the other hand you are going to call it from another procedure in the same module, then you can make it Private.
Here is the enhanced solution:
Public Sub Subtract()
Dim k&
Const F = "iferror(h2:h[]-d2:d[],0)"
k = [count(d:d)]
[j2].Resize(k) = Evaluate(Replace(F, "[]", k + 1))
End Sub
Note that the routine now handles the errors and places a ZERO value in column J when the corresponding value in column H is an error. If you would prefer to have something other than a ZERO (like a blank for instance) when there are errors in column H, just let me know and I'll update to whatever you want.
UPDATE 2
Here is how to handle displaying blanks instead of zeroes:
Public Sub Subtract()
Dim k&
Const F = "iferror(if(h2:h[]-d2:d[]=0,"""",h2:h[]-d2:d[]),0)"
k = [count(d:d)]
[k2].Resize(k) = Evaluate(Replace(F, "[]", k + 1))
End Sub

Delete rows based on range possible mistake

I'm trying to delete rows on one worksheet based on a range in another worksheet. I think the problem here is probably something simple based on my limited VBA experience. Here is the code I've written:
Sub LimitedElements()
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
If Sheets("test").Cells(j, 1).Value = Sheets("Limited Elements").Range("A1:A10") Then
Rows(i).EntireRow.Delete
End If
Next i
End Sub
I get a message saying "Application-defined or object-defined error".
Can anyone tell me what I'm doing wrong? Or if this is just a dumb way to do this and I should be doing it differently?
Please see if below works for you:
Sub LimitedElements()
Dim imax As Integer
Dim a As Variant
Dim b As Range
Dim c As Object
Dim d As Integer
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
a = Sheets("test").Cells(i, 1).Value
Set b = Sheets("Limited Elements").Range("A1:A10")
Set c = b.Find(What:=a, LookIn:=xlValues)
If Not c Is Nothing Then
Sheets("test").Rows(i).EntireRow.Delete
i = i - 1
imax = imax - 1
End If
Next i
End Sub
Noted that it is not fine tuned and is intended to give you an understanding on how to approach the solution.
I added code to decrement i. I think I understand that the code can't tell which worksheet I'm specifying for deleting the row but I'm not sure what to do about it. I tried changing "Rows(i).EntireRow.Delete" to "Sheets("test").Rows(i).EntireRow.Delete" but I'm not sure if that's the right thing to do or not.
Some extra details to make things clearer:
Sheet "test" has about 1000 rows with unique numbers in column A. Sheet "Limited Elements" has about 100 rows with unique numbers column A. I want it it delete the rows in "test" that have values in column A that match the column A values in "Limited Elements".
Sub LimitedElements()
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
If Sheets("test").Cells(i, 1).Value = Sheets("Limited Elements").Range("A1:A10") Then
Sheets("test").Rows(i).EntireRow.Delete
i = i - 1
imax = imax - 1
End If
Next i
End Sub
I think the original problem was that I had Cells(j,1) instead of cells(i,1). Now I've fixed that but it gives me a type mismatch error which I think is due to comparing a single cell to a range.
At this point I think I'm just lost. I can't figure out how to change it so it works and does what I want it to do.

redefining an integer vba

I have difficulty fixing the following problem I am facing:
Lets say I have this code
i_GroupNumberA = Application.WorksheetFunction.CountIf(Sheets("SheetX").Range("G2:G500"), "Red")
i_GroupNumberB = Application.WorksheetFunction.CountIf(Sheets("SheetX").Range("G2:G500"), "Green")
For i = 2 To LastRow
For j = 2 To LastCol
groupNumber = Sheets("Sheet1").Cells(i, j).Value
i_GroupNumberA = 35 'this number a integer that I have got from a cells.value
i_GroupNumberB = 39
If groupNumber = Sheets("Sheet1").Cells(i, j).Value Then
i_Variable = "i_" + groupNumber + "AlphabeticLetter"
MsgBox i_Variable
End If
Next j
Next i
As a result I get i_Variable as a string in a messagebox as an outcome:
i_groupNumberA
I want to have the following result:
35
What I am asking is how can I make get a new variable of a string functioning as a integer.
I am not sure if I am asking this right?
I did as #engineersmnky said, but no effect. I check sites and made some adjustments together with your code. But Still I can't get the needed number in return. So far I got this:
Dim Group As New Collection
i_GroupNumberA = Application.WorksheetFunction.CountIf(Sheets("SheetX").Range("G2:G500"), "Red") 'lets assume it is an number 35
i_GroupNumberB = Application.WorksheetFunction.CountIf(Sheets("SheetX").Range("G2:G500"), "Green") 'lets assume it is an number 39
Group.Add i_GroupNumberA
Group.Add i_GroupNumberB
For i = 2 To LastRow
For j = 2 To LastCol
groupNumber = Sheets("Sheet1").Cells(i, j).Value
i_Variable = "i_" + groupNumber + "AlphabeticLetter"
Group(i_Variable)
Next j
Next i
Group(i_variable) I cant figure it out? for some reason it is not working.
Since you cannot get a variable value from a string in vba I would suggest creating a Collection Object or a Dictionary if you need something more diverse
dim groups AS New Collection
'Value, Key
groups.Add 35, "i_GroupNumberA"
groups.Add 39, "i_GroupNumberB"
Then in your loop instead of the message box you can use
groups(i_Variable)
This will return 35 for "i_GroupNumberA"
Update Collections use an Item and Key structure for Collection(Key) to return the value you want you must specify the key
You may have to build a collection dynamically with your needed group numbers as I am unsure what these are e.g.
Function buildCollection(val As Variant,alpha AS String) AS Collection
Dim groups As New Collection
For i = 2 To LastRow
For j = 2 To LastCol
groupNumber = Sheets("Sheet1").Cells(i, j).Value
i_Variable = "i_" & CStr(groupNumber) & alpha
groups.Add val, i_Variable
Next j
Next i
set buildCollection = groups
End
But without more info about your structure I can't really help beyond basic examples. What is group number? Is it an actual integer? What is A vs B? Please advise as this may be simpler than I originally thought. If you put some sample data or something I am sure I could get this working for you seems like a fairly simple loop. Although you are looping through all the cells and stating that they are all group numbers which seems confusing to me.

Interpreting VBA code for moving averages

While I roughly understood my coding at the time of writing it awhile back, I have since forgotten how to interpret the first few parts of it (in bold).
Why 'as long'? My understanding is that this is used when the variable is only to take larger integer values. Since the share values contain several decimals, I am not sure why I chose this over 'double'.
Why/when do we dim a variable as a 'range', and why do we use 'set' at all? My limited understanding of the purpose of the set function is to assign values to 'object' variables. Why is the 'range' an 'object'?
I have completely forgot what the line Set stockValue = Range("B5:B" & lastStockprice) is doing, especially the ampersand.
I've no idea what is going on here:
ReDim stockPrice(stockValue.Count - 1)
For Each cell In stockValue
stockPrice(cell.Row - 5) = cell.Value
Next
Sub MovingAverage()
Dim CumulSum() As Double
Dim MovingAv() As Double
RowCountA = Range("StockPrice").Rows.Count
RowCountB = Range("MovingAv").Rows.Count
ReDim CumulSum(RowCountB)
Dim stockPrice As Variant
Dim lastStockprice **As Long**
lastStockprice = Cells(Rows.Count, "B").End(xlUp).Row
Dim stockValue **As Range**
**Set stockValue = Range("B5:B" & lastStockprice)**
**ReDim stockPrice(stockValue.Count - 1)
For Each cell In stockValue
stockPrice(cell.Row - 5) = cell.Value
Next**
For i = 0 To RowCountB - 1
For k = 0 To 9
CumulSum(i) = CumulSum(i) + stockPrice(i + k)
Next k
Next i
For i = 1 To RowCountB
Range("MovingAv").Cells(i) = CumulSum(i - 1) / 10
Next i
End Sub
If someone could please explain the bolded code for me (I've a very basic knowledge of VBA that extends about as far as matrix multiplication, basic functions and double arrays), it would be greatly appreciated. :)
Dim lastStockprice **As Long**
lastStockprice = Cells(Rows.Count, "B").End(xlUp).Row
This has to be long because we are trying to find the last row in Col B. This is to make the code compatible with xl2007+ (Where there are 1048576 rows). You can see this link on how to get the last row.
Why is the 'range' an 'object'?
See this link. Also see this.
I have completely forgot what the line Set stockValue = Range("B5:B" & lastStockprice) is doing, especially the ampersand.
As mentioned earlier lastStockprice is the last row and & is used to concatenate so that we can set our range. Let's say the last row is 20 then the above code can be written as
Set stockValue = Range("B5:B" & 20)
'OR
Set stockValue = Range("B5:B20")
I've no idea what is going on here: ReDim stockPrice(stockValue.Count - 1)
What the code is trying to do is dynamically increase the size of the array so that it can store more values to it. REDIM (Re-Dimension) I would recommend seeing this link
FOLLOWUP (From comments)
I understand all of it now except this part: For Each cell In stockValue stockPrice(cell.Row - 5) = cell.Value Next**
What that piece of code is doing is looping through every cell in the range stockvalue and then storing the cell value in the array stockPrice
Ex: Let's say we have a range, A1:B2
When we say For each cell in Range("A1:B2"), we are telling the code to loop through every cell in that range (A1, A2, B1, B2)