ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] FOR循环+多条件的提速方法,数组或是其他?

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-9-13 09:30 | 显示全部楼层 |阅读模式
N列=L列-M列,但是有个条件就是
如果J列单元格为以下4种内容的一种的话,那么L列的值始终为0,N列=M列的值,
请问各位大侠这个怎么做呢,我只会用最简单的FOR循环运行实在太慢,求比较快的方法,谢谢。。。
Production Open;
Production Partial;
Supply Eligible;
Supply Partial;


文件2.rar

1.05 MB, 下载次数: 19

TA的精华主题

TA的得分主题

发表于 2015-9-13 10:28 | 显示全部楼层
数组+循环应该是最快的方法了
先把单元格数据保存到数组,再用for循环判并把结果写入数组,最后把结果数组写到表里
因为需求很简单,也没办法从算法上去提速,所以最简单的方法,往往是速度最快的

TA的精华主题

TA的得分主题

发表于 2015-9-13 10:53 | 显示全部楼层
你这个用公式就可以自动生成了,一定要用vba?

附件是我用公式给你做的

文件2.zip

1.11 MB, 下载次数: 17

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-9-13 11:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
五音 发表于 2015-9-13 10:28
数组+循环应该是最快的方法了
先把单元格数据保存到数组,再用for循环判并把结果写入数组,最后把结果数组 ...

是的 要求的确是很简单,只是单单求出N列的值,M L列的值都是本来就存在的
问题是偶目前刚开始学数组,觉得蛮难的,所以来论坛请教各位,如果用数组的方法会怎样,如果用简单的FOR循环语句运行比较慢,数据源行数每天都会变 而且不止这些...

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-9-13 11:53 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
ghb1997 发表于 2015-9-13 10:53
你这个用公式就可以自动生成了,一定要用vba?

附件是我用公式给你做的

灰常感谢ghb1997,
用find函数也是要用两步吗,先用find将M列有要求的单元格改为0,然后需要清除所有筛选之后用公式
N列=M列-L列,这样子
我之所以要用VBA,是因为我目前正在学习VBA,这个只是我需要做的报表的很小的一部分,想用VBA编写整个代码,不想中间中断,不过还是非常谢谢你这边提供函数find公式,您这边可以用VBA代码帮忙写吗?最好是数组字典啥的,速度会快很多呵呵,

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-9-13 13:36 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
果然沉下来了,没办法再顶一下。。。

TA的精华主题

TA的得分主题

发表于 2015-9-13 14:40 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. Sub test()
  2.     Dim arrRng As Variant, arrDiffer(), i As Long
  3.     Const strStatus As String = "Production Open|Production Partial|Supply Eligible|Supply Partial"
  4.     With ThisWorkbook.Worksheets("处理前")
  5.         arrRng = .Range("J2:M" & .Range("A65535").End(xlUp).Row).Value
  6.     End With
  7.     ReDim arrDiffer(1 To UBound(arrRng))
  8.     For i = 1 To UBound(arrRng)
  9.         If InStr(strStatus, arrRng(i, 1)) > 0 Then
  10.             arrDiffer(i) = arrRng(i, 4)
  11.         Else
  12.             arrDiffer(i) = arrRng(i, 3) - arrRng(i, 4)
  13.         End If
  14.     Next i
  15.    
  16.     ThisWorkbook.Worksheets("处理前").Range("M2").Resize(UBound(arrDiffer), 1) = Application.Transpose(arrDiffer)
  17.    
  18. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2015-9-13 15:07 | 显示全部楼层
特殊判断不是很多,用循环应该已经很快了。我觉得这个数量的处理,没有必要特别追求速度;简单可读才是关键.
  1. Public arrSP
  2. Sub TZ_20150913_1()
  3. Dim arr
  4. Dim i As Long, j As Long
  5. Dim D As Object
  6. Dim t
  7. t = Time
  8. Call SP
  9. Set D = CreateObject("Scripting.Dictionary")
  10. arr = Sheet2.UsedRange

  11. For j = 1 To UBound(arrSP)
  12.    If Not D.Exists(arrSP(1)) Then D(arrSP(1)) = 0
  13.    'SPECIAL STATUS INTO DICTIONARY
  14. Next j
  15. For i = 2 To UBound(arr)
  16.    If D.Exists(arr(i, 10)) Then
  17.       'SPECIAL STATUS
  18.       arr(i, 14) = 0   'D(arr(i, 10))
  19.       'VALUE=0
  20.    Else
  21.       arr(i, 14) = arr(i, 12) - arr(i, 13)
  22.       'VALUE=QTY-QTY_REQ
  23.    End If
  24. Next i
  25. Sheet1.[A2].Resize(UBound(arr), UBound(arr, 2)) = arr
  26. Sheet1.[A1] = (Time - t) * 100000
  27. MsgBox ("DONE")
  28. End Sub

  29. Sub TZ_20150913_2()
  30. Dim arr
  31. Dim i As Long, j As Long
  32. Dim t
  33. t = Time
  34. Call SP
  35. arr = Sheet2.UsedRange
  36. For i = 2 To UBound(arr)
  37.    If funSP(arr(i, 10)) Then
  38.       'SPECIAL STATUS
  39.       arr(i, 14) = 0   'D(arr(i, 10))
  40.       'VALUE=0
  41.    Else
  42.       arr(i, 14) = arr(i, 12) - arr(i, 13)
  43.       'VALUE=QTY-QTY_REQ
  44.    End If
  45. Next i
  46. Sheet1.[A2].Resize(UBound(arr), UBound(arr, 2)) = arr
  47. Sheet1.[A1] = (Time - t) * 100000
  48. MsgBox ("DONE")
  49. End Sub
  50. Function funSP(data) As Boolean
  51.   For i = 1 To UBound(arrSP)
  52.       If data = arrSP(i) Then
  53.          funSP = True
  54.          Exit Function
  55.       End If
  56.   Next i
  57. End Function

  58. Sub SP()
  59.     ReDim arrSP(1 To 4)
  60.     arrSP(1) = "Production Open"
  61.     arrSP(2) = "Production Partial"
  62.     arrSP(3) = "Supply Eligible"
  63.     arrSP(4) = "Supply Partial"
  64. End Sub
复制代码

文件2.zip

609.69 KB, 下载次数: 11

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-9-13 21:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

非常感谢五音老师,由于相减结果要放在N列并且0值是需要显示出来,所以在老师代码基础上自己稍稍做了下调整,完美运行,非常感谢!
Sub test()
    Dim arrRng As Variant, arrDiffer(), i As Long
    Const strStatus As String = "Production Open|Production Partial|Supply Eligible|Supply Partial"
    With Worksheets("处理前")
        arrRng = .Range("J2:N" & .Range("A65535").End(xlUp).Row).Value
    End With
    ReDim arrDiffer(1 To UBound(arrRng), 1)
    For i = 1 To UBound(arrRng)
        If InStr(strStatus, arrRng(i, 1)) > 0 Then
'            arrDiffer(i) = arrRng(i, 5)
                arrDiffer(i, 0) = 0
                arrDiffer(i, 1) = arrRng(i, 3)
        Else
            arrDiffer(i, 1) = arrRng(i, 3) - arrRng(i, 4)
            arrDiffer(i, 0) = arrRng(i, 4)
        End If
    Next i
    Worksheets("处理前").Range("M2").Resize(UBound(arrDiffer), 2) = arrDiffer
    End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-9-13 22:04 | 显示全部楼层
zhenghui13 发表于 2015-9-13 15:07
特殊判断不是很多,用循环应该已经很快了。我觉得这个数量的处理,没有必要特别追求速度;简单可读才是关键.
...

老师,这个是自定义函数吗?感觉高大上,但是看不懂额。。。不过非常感谢,等我继续学习钻研,以后一定弄懂它,到时候有问题会继续提的,呵呵。。。  
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2025-1-6 14:54 , Processed in 0.025678 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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