简体   繁体   English

VBA宏添加列

[英]VBA Macro to add columns

Trying to create a VBA Macro, that adds the sum on a Column, then when the button is pressed again, proceeds to add the sum of the next column. 尝试创建一个VBA宏,该宏将一个列的总和相加,然后再次按下该按钮时,将继续添加下一列的和。

I have the following Code below. 我下面有以下代码。 Currently It will add the first column, but then seems to lose the Integer values and just overwrites itself. 当前,它将添加第一列,但随后似乎丢失了Integer值,并且只会覆盖自身。

Also I am having issues figuring out how I would save the Column Letter instead of the Number for the column. 另外,我在解决如何保存列字母而不是数字时遇到问题。 Any help would be great! 任何帮助将是巨大的!

Sub Button1_Click()
Dim vStartRow As Integer
Dim vEndRow As Integer
Dim vStartCol As Integer
Dim vEndCol As Integer

Range("A2").Select
ActiveCell.End(xlDown).Select
MsgBox vStartCol
vStartRow = 2 'Row 2
vStartCol = ActiveCell.Column

ActiveCell.End(xlToRight).Select
vEndRow = ActiveCell.Row 'Row 7

MsgBox vStartCol
Cells(vEndRow + 1, vStartCol + 1).Formula = "=SUM(" & vStartCol & vStartRow & ":" & vStartCol & vEndRow & ")"
Cells(vEndRow, vStartCol + 1).Select
vStartCol = vStartCol + 1
MsgBox vStartCol

End Sub

The data table looks like: 数据表如下所示:

      Year 1    Year 2  Year 3
Chris   1         4       6
Jimmy   1         2       7
John    1         2       1
Frank   1         5       3
Fred    1         4       7
Jodie   1         2       6

What you have here is a really good start. 您在这里拥有的是一个很好的开始。

Something like the following, which is very close to what you've started with, should do the trick: 类似于以下内容(与您的开始非常相似)应该可以解决问题:

Sub Button1_Click()
    Dim vStartRow As Integer
    Dim vEndRow As Integer
    Dim rngCell As Range

    'get start and end rows for your sum
    vStartRow = 2 'Row 2
    vEndRow = Range("A2").End(xlDown).Row()

    'determine which column already has a sum by iterating through the cells in your vEndRow
    For Each rngCell In Rows(vEndRow + 1).Cells
        'Does the rngCell (the cell in the first empty row) have a value already (assuming it's not column 1, which we can't sum anyway)
        If rngCell.Value = "" And rngCell.Column <> 1 Then 'we have an empty cell and it's not column 1.
            'Since the value of rngCell has been determined we can exit the loop and it will stay set to this cell
            Exit For
        End If
    Next rngCell

    'finally set the formula for our empty column's total row
    rngCell.Formula = "=SUM(" & Cells(vStartRow, rngCell.Column()).Address & ":" & Cells(vEndRow, rngCell.Column()).Address & ")"

End Sub

A couple of things happening here: 这里发生了几件事:

First: The For Each loop. 首先: For Each循环。 In VBA we have objects that can be Ranges, Worksheets, Workbooks, etc.. Many Objects have collections of other objects. 在VBA中,我们的对象可以是范围,工作表,工作簿等。许多对象都有其他对象的集合。 For instance, Ranges have a collection of Rows, A workbook has a collection of sheets. 例如,范围具有行的集合,工作簿具有工作表的集合。 We can iterate through Each of the items in a collection with the For Each loop. 我们可以通过遍历Each物品的集合与For Each循环。

An example of looping through each each sheet in a workbook: 遍历工作簿中每个工作表的示例:

Sub test()
    Dim sht as Worksheet

    For Each sht in ThisWorkbook.Sheets
        msgbox(sht.name)
    Next sht
End Sub

Second: Instead of selecting a cell, then getting a property of that cell (like it's row) you can just go straight to the property. 第二:不用选择一个单元格,而是获取该单元格的属性(例如它的行),就可以直接转到该属性。

So instead of: 所以代替:

Cells(1,2).Select
myVar = Selection.Row

You can do: 你可以做:

myVar = Cells(1,2).Row

If you find your self using .Select or .Activate then you are probably doing something wrong. 如果使用.Select.Activate找到自己,则可能是您做错了。 Humans .Select and .Activate , but the computer doesn't need to. 人类.Select.Activate ,但计算机不需要。 It's wasteful and will lead to some strange behavior in your code. 这很浪费,并且会在您的代码中导致某些奇怪的行为。 Although... sometimes it makes sense. 虽然...有时候很有意义。 If your requirement was: 如果您的要求是:

"I want to sum up all of the numbers in the row that the user has selected when the push the button" “我想总结用户在按下按钮时选择的行中的所有数字”

Then a selectedCell = Selection would make a lot of sense. 然后, selectedCell = Selection非常有意义。

Or, conversely if you requirement was: 或者,相反,如果您的要求是:

"When the subroutine is finished, I want cell A1 to be selected" “子程序完成后,我希望选择单元格A1”

Then Sheet1.Range("A1").Select is the way to go. 然后Sheet1.Range("A1").Select But, you can see in both instances it was due to our need to interact with the user that we utilized the Selection property and the Select() method of the Range object. 但是,您可以看到在这两种情况下,都是由于我们需要与用户进行交互,因此我们利用了Range对象的Selection属性和Select()方法。

Third: You can get the address of a range object by accessing it's .Address property. 第三:您可以通过访问范围对象的.Address属性来获取它的.Address So no need to monkey with column letters. 因此,无需胡闹输入列字母。 Just hit the .Address and it will figure it out. 只需点击.Address解决。

Fourth: I'm adding this after submitting, but it's important and confusing. 第四:我在提交后添加此内容,但这很重要而且令人困惑。 Cells , Ranges , Rows , and Columns all are synonyms of a Range . CellsRangesRowsColumns都是Range同义词。 So.. you can iterate through each of the cells in a row , or each of the rows in a column or each of the columns in a range . 所以..你可以通过每个迭代的cellsrow ,或每次的rowscolumn或每个的columns在一个range In this solution we iterate through the cells in a row where the cell is just a range() that is... a single a cell. 在此方案中,我们通过迭代cellsrowcell只是一个range()这是...单一的单元格。 Generally when you use a For Each loop on a range, you'll find yourself iterating a range's rows or a row's cells. 通常,当您在范围上使用For Each循环时,会发现自己遍历了范围的行或行的单元格。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM