尝试创建一个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
答案 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
,就可以解决问题。
第四:我在提交后添加此内容,但这很重要且令人困惑。 Cells
,Ranges
,Rows
和Columns
都是Range
的同义词。所以..你可以遍历cells
中的row
,或rows
中的每个column
或columns
中的每一个range
。 cells
。在此解决方案中,我们遍历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;
循环时,您会发现自己迭代范围的行或行的单元格。