VBA宏添加列

时间:2016-11-16 11:11:23

标签: excel

尝试创建一个VBA宏,在列上添加总和,然后再次按下该按钮时,继续添加下一列的总和。

我在下面有以下代码。目前它将添加第一列,但似乎失去了整数值,只是覆盖了自己。

此外,我在解决如何保存列字母而不是列的编号时遇到问题。任何帮助都会很棒!

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

数据表如下:

      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

1 个答案:

答案 0 :(得分:3)

你在这里有一个非常好的开始。

以下内容非常接近您应该采用的技巧:

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

这里发生了一些事情:

首先: For Each循环。在VBA中,我们有对象可以是Ranges,Worksheets,Workbooks等。许多对象都有其他对象的集合。例如,Ranges有一组Rows,一个工作簿有一组工作表。我们可以使用Each循环遍历集合中For Each个项目。

循环遍历工作簿中每个工作表的示例:

Sub test()
    Dim sht as Worksheet

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

第二:您可以直接前往酒店,而不是选择一个单元格,然后获取该单元格的属性(就像它的行一样)。

所以而不是:

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

你可以这样做:

myVar = Cells(1,2).Row

如果您发现自己使用.Select.Activate,那么您可能做错了什么。人类.Select.Activate,但计算机不需要。这很浪费,会导致代码中出现一些奇怪的行为。虽然......有时它是有道理的。如果您的要求是:

  

“我想总结用户所拥有的行中的所有数字   按下按钮“

时选择

然后selectedCell = Selection会很有意义。

或者,相反,如果您的要求是:

  

“子程序完成后,我希望选择单元格A1”

然后Sheet1.Range("A1").Select即可。但是,您可以在两个实例中看到,由于我们需要与用户进行交互,我们使用Selection属性和Select()对象的Range方法。

第三:您可以通过访问范围对象的.Address属性来获取范围对象的地址。所以不需要用列字母来表达。只需点击.Address,就可以解决问题。

第四:我在提交后添加此内容,但这很重要且令人困惑。 CellsRangesRowsColumns都是Range的同义词。所以..你可以遍历cells中的row,或rows中的每个columncolumns中的每一个rangecells。在此解决方案中,我们遍历row中的cell range(),其中For Each只是template <bool... args> unsigned long func1() { std::array<bool, sizeof...(args)> ar{args...}; // the piece specific for my task std::bitset<sizeof...(args)> bs; for(std::size_t i = 0; i < ar.size(); ++i) { bs[i] = ar[i]; } // ... processing ... return bs.to_ulong(); } ,即...单个单元格。通常,当您在范围上使用select de - sysdate as newde from deinfo; 循环时,您会发现自己迭代范围的行或行的单元格。