简体   繁体   English

Excel VBA-计算具有动态列数的数据平均值

[英]Excel vba - calculate average of data with a dynamic number of columns

I'm new to excel VBA, I want to calculate the average of each column that has data 我是excel VBA的新手,我想计算每个包含数据的列的平均值

But the number of columns can change depending on how many columns worth of data the users copy and pastes. 但是列数可以根据用户复制和粘贴多少列数据而改变。

Here's what I have so far: 这是我到目前为止的内容:

Dim lastcol As Long
Dim i As Integer

lastcol = Range("B5", Range("B5").End(xlToLeft)).Columns.Count + 1

For i = 0 To lastcol

Range(ActiveCell, ActiveCell.Offset(0, i)).Value = 
Application.WorksheetFunction.Average(Range(Range("B5").Offset(0, i), 
Range("B5").Offset(0, i).End(xlDown)))

Next i

But this seems to calculate the average of only the data in column B. I want to calculate average of each column that has data and put that value into first row without any data. 但这似乎只计算B列中数据的平均值。我想计算每个有数据列的平均值,并将该值放入没有任何数据的第一行中。

For someone new to VBA, this is a good effort, and your code just needs a couple of tweaks. 对于刚接触VBA的人来说,这是一个很大的努力,您的代码只需要进行一些调整。

Firstly, the line: 首先,该行:

lastcol = Range("B5", Range("B5").End(xlToLeft)).Columns.Count + 1

will basically find the left end of the region of Range "B5" - most likely "A5"- so lastcol will always equal 3. 基本上会找到范围“ B5”(最可能是“ A5”)区域的左端,因此lastcol将始终等于3。

Secondly, the line: 第二行:

Range(ActiveCell, ActiveCell.Offset(0, i)).Value = ...

defines the range beginning at the ActiveCell and ending at the offset value from that cell. 定义范围从ActiveCell开始,到该单元格的偏移值结束。 In other words, you'll have a number of cells within the range depending on the value of i but the ActiveCell will always be the first cell in the range. 换句话说,根据i的值,您将在该范围内有多个单元格,但ActiveCell将始终是该范围内的第一个单元格。 Given that your output value is a double and not an array, your code will write that value to every cell in the range. 假设您的输出值是double精度值而不是数组,那么您的代码会将值写入范围内的每个单元格。 So your previous calculations are always being overwritten. 因此,您以前的计算总是会被覆盖。

A point of note also is that you should always qualify your ranges with the sheet object. 还有一点需要注意的是,您应该始终使用图纸对象限定范围。 In your code there is a risk of the wrong worksheet being processed. 在您的代码中,存在处理错误工作表的风险。 I'd also steer away from using the ActiveCell property, as one wrong selection and the whole sheet can be messed up. 我还会避免使用ActiveCell属性,因为一个错误的选择可能会弄乱整个工作表。

It's worth stepping through your code with F8, as you can see the values that are assigned to the variables. 值得使用F8逐步遍历代码,因为您可以看到分配给变量的值。 I also like to select my ranges during testing in order to see what cells are being identified. 我还喜欢在测试期间选择我的范围,以查看正在识别哪些单元格。 Perhaps you could adopt these practices in future development. 也许您可以在将来的开发中采用这些做法。

All in all, then, your code could look something like this: 总而言之,您的代码可能看起来像这样:

Dim lastCol As Long, i As Long
Dim rng As Range

'Find the last column.
'Assumes the relevant column is the last one with data in row 5.
With Sheet1
    lastCol = .Cells(5, .Columns.Count).End(xlToLeft).Column
End With

'Iterate the columns from 1 (ie "A") to the last.
For i = 1 To lastCol
    With Sheet1
        'Define the data range for this column.
        'Assumes last cell from bottom of sheet is the end of data.
        Set rng = .Range(.Cells(5, i), .Cells(.Rows.Count, i).End(xlUp))
        'Write the average to the cell above.
        .Cells(4, i) = WorksheetFunction.Average(rng)
    End With
Next

Well, first of all you can use a for each loop to go through the cells and the used cells you can get with the usedRange property. 好吧,首先,您可以为每个循环使用a来遍历单元格以及可以使用usedRange属性获得的二手单元格。

usedRange 使用范围

For Each 对于每个

I linked the Microsoft Docs to them, with a combination of them you should be able to navigate to every cell with content. 我将Microsoft Docs链接到它们,结合使用它们,您应该能够导航到包含内容的每个单元格。

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

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