0

As a complete beginner to VBA Excel, I would like to be able to do the following:

I want to find the first value larger than 0 in a row, and then sum over the following 4 cells in the same row. So

Animal1    0    0    1    2    3    0    1
Animal2    3    3    0    1    4    2    0
Animal3    0    0    0    0    0    1    0

Results in

Animal1    7
Animal2    11
Animal3    1

Is this possible?

tkoz_dk
  • 239
  • 1
  • 4
  • 13
  • yes, that is possible. show us the code you have written so far, and give more information as to where the results should be written to (new sheet/same sheet, ...) - so we might be able to help – Cee McSharpface Jan 15 '16 at 13:18
  • 1
    It's possible to do it with just formulas as well - you don't need VBA – Kritz Jan 15 '16 at 13:33
  • 1
    Your examples don't match your description. Why not 6 in the first row and 7 in the second? Also -- by "after" do you mean strictly after or after and including? – John Coleman Jan 15 '16 at 13:52

3 Answers3

2

(Your problem description didn't match your examples. I interpreted the problem as one of summing the 4 elements in a row which begin with the first number which is greater than 0. If my interpretation is wrong -- the following code would need to be tweaked.)

You could do it with a user-defined function (i.e. a UDF -- a VBA function designed to be used as a spreadsheet function):

Function SumAfter(R As Range, n As Long) As Variant
    'Sums the (at most) n elements beginning with the first occurence of
    'a strictly positive number in the range R,
    'which is assumed to be 1-dimensional.
    'If all numbers are zero or negative -- returns a #VALUE! error

    Dim i As Long, j As Long, m As Long
    Dim total As Variant

    m = R.Cells.Count
    For i = 1 To m
        If R.Cells(i).Value > 0 Then
            For j = i To Application.Min(m, i + n - 1)
                total = total + R.Cells(j)
            Next j
            SumAfter = total
            Exit Function
        End If
    Next i
    'error condition if you reach here
     SumAfter = CVErr(xlErrValue)
End Function

If your sample data is in A1:H3 then putting the formula =SumAfter(B1:H1,4) in I1 and copying down will work as intended. Note that the code is slightly more general than your problem description. If you are going to use VBA, you might as well make your subs/functions as flexible as possible. Also note that if you are writing a UDF, it is a good idea to think of what type of error you want to return if the input violates expectations. See this for an excellent discussion (from Chip Pearson's site - which is an excellent resource for Excel VBA programmers).

ON EDIT: If you want the first cell greater than 0 added to the next 4 (for a total of 5 cells in the sum) then the function I gave works as is, but using =SumAfter(B1:H1,5) instead of =SumAfter(B1:H1,4).

Community
  • 1
  • 1
John Coleman
  • 51,337
  • 7
  • 54
  • 119
  • Great way to fix it - I didn't know about UDF's, but I will definitely look more into that in the future. Thank you. – tkoz_dk Jan 18 '16 at 07:56
2

This is the one of the variants of how you can achieve required result:

 Sub test()
        Dim cl As Range, cl2 As Range, k, Dic As Object, i%: i = 1
        Set Dic = CreateObject("Scripting.Dictionary")
        For Each cl In ActiveSheet.UsedRange.Columns(1).Cells
            For Each cl2 In Range(Cells(cl.Row, 2), Cells(cl.Row, 8))
                If cl2.Value2 > 0 Then
                    Dic.Add i, cl.Value2 & "|" & Application.Sum(Range(cl2, cl2.Offset(, 4)))
                    i = i + 1
                    Exit For
                End If
        Next cl2, cl
        Workbooks.Add: i = 1
        For Each k In Dic
            Cells(i, "A").Value2 = Split(Dic(k), "|")(0)
            Cells(i, "b").Value2 = CDec(Split(Dic(k), "|")(1))
            i = i + 1
        Next k
    End Sub

enter image description here

Vasily
  • 5,707
  • 3
  • 19
  • 34
  • You seem to be summing over the entire row, retaining the sums if they exceed 0. It doesn't seem to match the problem description (e.g. -- it doesn't involve the number 4). On the other hand -- it isn't clear exactly what OP has in mind. – John Coleman Jan 15 '16 at 15:54
  • @JohnColeman, yes, you are right, I didn't recognized the real OP need untill you have comented, thank you, post has been updated – Vasily Jan 15 '16 at 15:59
  • Your output matches the OP's examples but not the OP's description. It seems that OP want's to add the first nonzero value + the next 4, for a total of 5 cells. In any event, your solution is nice and the 4 vs. 5 question is easily tweaked after OP clarifies. – John Coleman Jan 15 '16 at 16:19
1

Here is what I would use, I dont know any of the cell placement you have used so you will need to change that yourself.

Future reference this isnt a code writing site for you, if you are new to VBA i suggest doing simple stuff first, make a message box appear, use code to move to different cells, try a few if statments and/or loops. When your comftable with that start using varibles(Booleans, string , intergers and such) and you will see how far you can go. As i like to say , "if you can do it in excel, code can do it better"

If the code doesnt work or doesnt suit your needs then change it so it does, it worked for me when i used it but im not you nor do i have your spread sheet

paste it into your vba and use F8 to go through it step by step see how it works and if you want to use it.

Sub test()

[A1].Select ' assuming it starts in column A1

'loops till it reachs the end of the cells or till it hits a blank cell
Do Until ActiveCell.Value = ""

ActiveCell.Offset(0, 1).Select

'adds up the value of the cells going right and removes the previous cell to clean up
Do Until ActiveCell.Value = ""
x = x + ActiveCell.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Offset(0, -1).ClearContents
Loop

'goes back to the begining and ends tallyed up value
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 1).Value = x

'moves down one to next row
ActiveCell.Offset(1, 0).Select

Loop

End Sub
Vasily
  • 5,707
  • 3
  • 19
  • 34
Mr.Burns
  • 690
  • 1
  • 10
  • 24
  • the usage of `.select` method is a bad practice, all tasks in vba can be completed without usage of it, with more shorter and more readable code. http://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros – Vasily Jan 15 '16 at 13:47
  • I will look into what you have sent me however I will be keeping my code the same as I havent used that method before, should I be able to make my code more efficient then I will use this method and then update the code I have posted. – Mr.Burns Jan 15 '16 at 14:02
  • Sorry if it sounded like I took offense to what you said, I didn't mean any it to, also if you critize it, i will take it as constructive critizim(not spelt right i know) and it means i have more room to improve which is what I would love to do with VBA. Also I would rather you didn't remove your comment as it has a useful link to how to not use .select which may or may not be useful for others if they stumble across this post. Hope this clears up any misunderstanding. – Mr.Burns Jan 15 '16 at 15:46