Excel VBA程序开发

fugb-2010 Lv.6

关注
求助:多条件统计,SUMPRODUCT改为VBA统计,数据达5W行时公式慢了
求助1.png
求助2.png
求助3.png

多条件公式改VBA求助.zip   2025-11-9 16:43 上传

861.66 KB, 下载次数: 17

405阅读
10回复 倒序

ykcbf1100 Lv.7 2楼

改代码比较费劲,还是用公式吧。

逍遥爱迪生 Lv.4 3楼

5万行也不多吧,尽量用代码处理

飞天篮球猪 Lv.4 4楼

本帖最后由 飞天篮球猪 于 2025-11-9 22:41 编辑

你那工资也不好挣,命名那么多名称,都是全表遍历,数据源设计那么宽的表.....输出就是3张数据透视表,有数据透视功能的会方便一些。以下仅供参考,插件解法,几十万行性能还是有保障的。
2025-11-09_222108.png

romecyf Lv.2 5楼

Sub romecyf()
Dim i, j, k, arr, brr, dic As Object
Set dic = CreateObject("scripting.dictionary")
Sheet2.Range("c5:m29").ClearContents
Sheet2.Range("c31:m55").ClearContents
Sheet2.Range("c57:m81").ClearContents
Row = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
arr = Sheet1.Range("a2:bv" & Row)
brr = Sheet2.Range("a3:m81")
satime = Sheet2.Range("e2")
edtime = Sheet2.Range("j2")
hhhh = edtime + 1
For i = 3 To UBound(arr)
   If arr(i, 70) <> "" Then
      发现时间 = DateValue(Split(arr(i, 70), " ")(0))
   Else
      发现时间 = DateValue(Split(arr(i, 27), " ")(0))
   End If
   If arr(i, 72) <> "" Then
      消缺时间 = DateValue(Split(arr(i, 72), " ")(0))
   Else
      If arr(i, 37) = "" Then
           消缺时间 = DateValue("2525-12-30")
      Else
          消缺时间 = DateValue(Split(arr(i, 37), " ")(0))
      End If
   End If
   If arr(i, 73) = "" Then
      终止时间 = DateValue("2525-12-30")
   Else
      终止时间 = DateValue(Split(arr(i, 73), " ")(0))
   End If
  If 发现时间 < satime And 消缺时间 >= satime And edtime <= 终止时间 Then
     aa = "遗留本期缺陷" & arr(i, 2) & arr(i, 5) & arr(i, 10)
     bb = "遗留本期合计" & arr(i, 2)
      dic(aa) = dic(aa) + 1
      dic(bb) = dic(bb) + 1
  End If
  If 发现时间 >= satime And 发现时间 < edtime + 1 And edtime <= 终止时间 Then
     aa = "本期新增缺陷" & arr(i, 2) & arr(i, 5) & arr(i, 10)
     bb = "本期新增合计" & arr(i, 2)
      dic(aa) = dic(aa) + 1
      dic(bb) = dic(bb) + 1
  End If
  If 消缺时间 >= satime And 消缺时间 < edtime + 1 And edtime <= 终止时间 Then
     aa = "本期消缺缺陷" & arr(i, 2) & arr(i, 5) & arr(i, 10)
      bb = "本期消缺合计" & arr(i, 2)
      dic(aa) = dic(aa) + 1
      dic(bb) = dic(bb) + 1
  End If
Next i
For i = 2 To UBound(brr)
     If InStr(brr(i, 1), "缺陷") Then st = brr(i, 1): GoTo 99
     If InStr(brr(i, 1), "合计") Then
       For j = 3 To UBound(brr, 2)
        brr(i, j) = dic(brr(i, 1) & brr(1, j))
       Next j
       GoTo 99
     End If
   For j = 3 To UBound(brr, 2)
     aa = st & brr(1, j) & brr(i, 2) & brr(i, 1)
     If dic.exists(aa) Then brr(i, j) = dic(aa)
   Next j
99
Next i
Sheet2.Range("a3").Resize(UBound(brr), UBound(brr, 2)) = brr
End Sub

quqiyuan Lv.7 6楼

本帖最后由 quqiyuan 于 2025-11-9 23:00 编辑

条件太多,看得有点累,只写了第一个,其他两个道理一样,楼主自己修改一下就差不多了。。。
缺陷汇总查询工作表计算区域数据需要清除。。。,不清除也行,代码需要改一下而与
vba 快多了,
image.png

image.png


多条件公式改VBA求助 2025-11-09 22-59-53.zip   2025-11-9 23:00 上传

951.06 KB, 下载次数: 4

quqiyuan Lv.7 7楼

代码如下。。。
Sub test()
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    tm = Timer
    Dim wb As Workbook, sht As Worksheet, sh As Worksheet
    Set wb = ThisWorkbook
    Set sht = wb.Sheets("缺陷数据")
    Set sh = wb.Sheets("缺陷汇总查询")
    r = sht.Cells(Rows.Count, 1).End(3).Row
    dizhi = sh.[c3:m3]
    x = sh.[e2]: y = sh.[j2]
    brr = sh.[a5:m28]
    Set d = CreateObject("scripting.dictionary")
    For i = 1 To UBound(brr)
        s = brr(i, 1) & "|" & brr(i, 2)
        For j = 1 To UBound(dizhi, 2)
            d(s & "|" & dizhi(1, j)) = i & "|" & j
        Next
    Next
    arr = sht.[a2].Resize(r - 1, 74)
    For i = 4 To UBound(arr)
        s = arr(i, 10) & "|" & arr(i, 5) & "|" & arr(i, 2)
        If d.exists(s) Then
            If IIf(arr(i, 70) <> "", arr(i, 70), CDate(arr(i, 27))) < x Then
                If IIf(arr(i, 72) <> "", arr(i, 72), IIf(arr(i, 37) <> "", CDate(arr(i, 37)), 90000)) >= x Then
                    If y <= IIf(arr(i, 73) <> "", arr(i, 73), 90000) Then
                        Z = Split(d(s), "|")
                        brr(Z(0), Z(1) + 2) = brr(Z(0), Z(1) + 2) + 1
                    End If
                End If
            End If
        End If
    Next
    Sheets("sheet1").[a5:m28] = brr
    Set d = Nothing
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    MsgBox "共耗时:" & Format(Timer - tm, "0.0000") & " 秒!!!", 64
End Sub

romecyf Lv.2 8楼

随便试一下

多条件公式改VBA求助.zip   2025-11-9 23:19 上传

915.16 KB, 下载次数: 7

wrynata Lv.3 9楼

引用: ykcbf1100 发表于 2025-11-9 18:09
改代码比较费劲,还是用公式吧。

他想表达通过VBA解决慢问题(配合ACCESS库SQL应该可以提高运行速度)

ykcbf1100 Lv.7 10楼

引用: wrynata 发表于 2025-11-10 09:36
他想表达通过VBA解决慢问题(配合ACCESS库SQL应该可以提高运行速度)

公式多,公式复杂,写代码也费时的。
加载更多