ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 398|回复: 8

[求助] VBA 计算一行不为零的中位数

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-1-27 16:43 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
QZ.jpg

QZ.rar

52.1 KB, 下载次数: 16

TA的精华主题

TA的得分主题

发表于 2024-1-27 16:46 | 显示全部楼层
用公式就行了呗,用VBA写起来也麻烦。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-27 17:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
ykcbf1100 发表于 2024-1-27 16:46
用公式就行了呗,用VBA写起来也麻烦。

数据量大,公式运行太慢啊

TA的精华主题

TA的得分主题

发表于 2024-1-27 18:23 | 显示全部楼层
  1. Sub test1()
  2.   Dim ar, i As Long, j As Long, k As Long, p As Long
  3.   
  4.   ar = Range("W21:FM34").Value
  5.   
  6.   For i = 1 To UBound(ar)
  7.     k = UBound(ar, 2)
  8.     BubbleSort ar, i, i, 1, UBound(ar, 2), i
  9.     For j = UBound(ar, 2) To 1 Step -1
  10.       If ar(i, j) <= 0 Then k = k - 1 Else Exit For
  11.     Next
  12.     If k Then
  13.       p = -Int(-k / 2)
  14.       If k Mod 2 Then ar(i, 1) = ar(i, p) Else ar(i, 1) = (ar(i, p) + ar(i, p + 1)) / 2
  15.     Else
  16.       ar(i, 1) = ""
  17.     End If
  18.   Next
  19.   Range("FP21").Resize(UBound(ar), 1) = ar
  20. End Sub

  21. Function BubbleSort(ar, u As Long, d As Long, l As Long, r As Long, p As Long)
  22.   Dim i As Long, j As Long, x As Long, y As Long, Flag As Boolean, Swap As Double
  23.   For j = l To r - 1
  24.     Flag = True
  25.     For x = l To r + l - 1 - j
  26.       If ar(p, x) < ar(p, x + 1) Then
  27.         Flag = False
  28.         For y = u To d
  29.           Swap = ar(y, x)
  30.           ar(y, x) = ar(y, x + 1)
  31.           ar(y, x + 1) = Swap
  32.         Next
  33.       End If
  34.     Next
  35.     If Flag = True Then Exit For
  36.   Next
  37. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-27 21:03 | 显示全部楼层
参与一下:

image.jpg
  1. Sub 计算除零以外的中位数()
  2.     Dim arr, brr(), numbers() As Double
  3.     arr = Range("W21").CurrentRegion
  4.     ReDim brr(1 To UBound(arr, 1))
  5.    
  6.     Dim count As Long
  7.     Dim i As Long, j As Long
  8.     For i = 1 To UBound(arr, 1)
  9.             count = 0
  10.             ' 收集每一行中不为0的数值
  11.         For j = 1 To UBound(arr, 2)
  12.             If arr(i, j) <> 0 Then
  13.                 count = count + 1
  14.                 ReDim Preserve numbers(1 To count)
  15.                 numbers(count) = arr(i, j)
  16.             End If
  17.         Next j
  18.         brr(i) = CalculateMedianFromArray(numbers)
  19.     Next i
  20.     i = 1
  21.     For Each rn In Range("FN21:FN34")
  22.         rn.Value = brr(i)
  23.         i = i + 1
  24.     Next
  25. End Sub
  26. ' 中位数计算函数
  27. Function CalculateMedianFromArray(numbers() As Double) As Double
  28.     Dim count As Long
  29.     count = UBound(numbers) - LBound(numbers) + 1
  30.    
  31.     ' 对数值数组进行排序
  32.     Call QuickSort(numbers, LBound(numbers), UBound(numbers))
  33.    
  34.     ' 计算中位数
  35.     If count Mod 2 = 0 Then
  36.         CalculateMedianFromArray = (numbers(count / 2) + numbers(count / 2 + 1)) / 2
  37.     Else
  38.         CalculateMedianFromArray = numbers(count \ 2 + 1)
  39.     End If
  40. End Function

  41. ' 快速排序算法
  42. Sub QuickSort(arr() As Double, low As Long, high As Long)
  43.     Dim i As Long, j As Long
  44.     Dim pivot As Double, temp As Double
  45.    
  46.     i = low
  47.     j = high
  48.     pivot = arr((low + high) \ 2)
  49.    
  50.     Do While i <= j
  51.         Do While arr(i) < pivot
  52.             i = i + 1
  53.         Loop
  54.         Do While arr(j) > pivot
  55.             j = j - 1
  56.         Loop
  57.         If i <= j Then
  58.             temp = arr(i)
  59.             arr(i) = arr(j)
  60.             arr(j) = temp
  61.             i = i + 1
  62.             j = j - 1
  63.         End If
  64.     Loop
  65.    
  66.     If low < j Then QuickSort arr, low, j
  67.     If i < high Then QuickSort arr, i, high
  68. End Sub
复制代码


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-27 21:31 | 显示全部楼层
用ChatGPT花了1分钟写了一段代码,已验证测试,效果非常不错,请查收!

QZ1.rar

35.22 KB, 下载次数: 5

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-27 22:36 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 wfywc81 于 2024-1-27 22:39 编辑






附:ChatGPT的prompt

编写一段VBA代码以执行以下任务:在Excel的"Sheet1"工作表上,从第21行开始,针对每一行,计算从"W"列起所有非零元素的中位数。然后,将这些中位数值显示在相应行的"FN"列中。为提高代码执行的效率,请在处理数据时采用数组。最后,请确保每个中位数结果在"FN"列中以红色加粗字体展示。此外,代码应能够测量并显示整个宏执行所需的时间。

附:所有非零元素的中位数计算步骤

要计算上述数据不为零的中位数,我们首先需要从给出的数据中排除所有的零值,然后对剩余的数据进行排序。排序后,我们可以找到中位数,即位于排序后列表中间的数字。如果数据集中有奇数个数字,中位数就是中间的数字;如果数据集中有偶数个数字,则中位数是中间两个数字的平均值。

下面是计算步骤:

1.移除所有的零值。

2.将剩余的数据按从小到大的顺序排序。

3.如果数据集的数量是奇数,则中位数是中间的数值。

4.如果数据集的数量是偶数,则中位数是中间两个数值的平均值。

附:VBA代码执行过程

要在Excel中自动化计算"Sheet1"的每行数据(从第21行起,从"W"列开始)中非零元素的中位数,并将结果以红色加粗字体在"FN"列显示,同时跟踪并展示宏的执行时间,你可以按照以下步骤编写和执行一个VBA宏:

1、初始化和设置环境:在VBA编辑器中,创建一个新的宏,首先设置目标工作表为"Sheet1",并初始化所有必要的变量,包括计时器变量、数据存储数组、行列计数器等。

2、启动计时器:使用Timer函数开始记录宏的执行时间,以便于最后计算整个宏运行所需的时间。

3、定义数据范围:确定数据的起始点为第21行的"W"列,并找到从这一点开始到最后一行以及最右边有数据的列的范围。

4、数组处理:将选定范围的数据读入到一个数组中,以提高数据处理的效率和速度。

5、中位数计算:

遍历数组的每一行,为每行创建一个临时数组以存储非零元素。

将非零元素收集到临时数组后,进行排序。

根据临时数组的元素数量,计算中位数。对于偶数个元素的数组,中位数是中间两个数的平均值;对于奇数个元素的数组,中位数是中间的数。

结果展示:将每行计算出的中位数写入对应的"FN"列,并设置字体颜色为红色且加粗,以便结果清晰可见。

6、计时结束和展示:在所有计算完成后,再次使用Timer函数记录时间,并计算总的执行时间。通过消息框展示给用户,告知宏的运行时间。













评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-28 00:22 | 显示全部楼层
  1. Sub Main()
  2.     For r = 21 To 34
  3.         ar = Range("W" & r & ":FM" & r).Value
  4.         myMedian ar, Cells(r, "FP")
  5.     Next
  6. End Sub
  7. Function myMedian(arr, rng As Range)
  8.     For i = 1 To UBound(arr, 2) - 1
  9.         For j = i + 1 To UBound(arr, 2)
  10.             If arr(1, j) > arr(1, i) Then
  11.                 x = arr(1, i)
  12.                 arr(1, i) = arr(1, j)
  13.                 arr(1, j) = x
  14.             End If
  15.         Next
  16.         If VBA.Len(arr(1, i)) = 0 Then Exit For
  17.     Next
  18.     If i Mod 2 Then
  19.         rng.Value = (arr(1, i \ 2) + arr(1, i \ 2 + 1)) / 2
  20.     Else
  21.         rng.Value = arr(1, i \ 2)
  22.     End If
  23. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-28 09:58 | 显示全部楼层
中位数是啥都不知道了,哎,忘记完了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-6-23 11:18 , Processed in 0.046530 second(s), 20 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表