ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

代码无法运行,一直报错

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-10-29 22:25 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本人想使用VBA推出关键路径,代码一直报错,代码如下
image.png



Sub CalculateAndOutputCriticalPath()
    Dim ws As Worksheet
    Set ws = ActiveSheet
   
    ' 假设WBS表从第二行开始,且第一行为标题行
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
   
    ' 创建字典来存储每个任务的最早开始时间、最晚开始时间、持续时间和前置依赖
    Dim taskDict As Object
    Set taskDict = CreateObject("Scripting.Dictionary")
   
    Dim i As Long
    For i = 2 To lastRow
        Dim wbs As String
        wbs = ws.Cells(i, 1).Value
        Dim taskName As String
        taskName = ws.Cells(i, 2).Value
        Dim duration As Double
        duration = ws.Cells(i, 3).Value
        Dim dependencies As String
        dependencies = ws.Cells(i, 4).Value
        
        ' 将任务添加到字典中,其中wbs是键
        taskDict(wbs) = Array(taskName, duration, dependencies)
    Next i
   
    ' 初始化最早开始时间为0
    Dim earlyStart As Double
    earlyStart = 0
   
    ' 计算最早开始时间
    For Each wbs In taskDict.Keys
        Dim duration As Double
        duration = taskDict(wbs)(1)
        Dim dependencies As String
        dependencies = taskDict(wbs)(2)
        
        Dim maxEarly As Double
        maxEarly = earlyStart
        
        Dim dependency As Variant
        For Each dependency In Split(dependencies, ",")
            If taskDict.Exists(dependency) Then
                maxEarly = Application.Max(maxEarly, taskDict(dependency)(1))
            End If
        Next dependency
        
        ' 更新字典中任务的最早开始时间
        taskDict(wbs)(1) = maxEarly + duration
        ' 更新最早开始时间
        earlyStart = maxEarly
    Next wbs
   
    ' 初始化最晚开始时间为最大值
    Dim lateStart As Double
    lateStart = 0
   
    ' 计算最晚开始时间
    For Each wbs In taskDict.Keys
        Dim duration As Double
        duration = taskDict(wbs)(1)
        Dim dependencies As String
        dependencies = taskDict(wbs)(2)
        
        Dim minLate As Double
        minLate = lateStart
        
        Dim dependency As Variant
        For Each dependency In Split(dependencies, ",")
            If taskDict.Exists(dependency) Then
                minLate = Application.Min(minLate, taskDict(dependency)(1))
            End If
        Next dependency
        
        ' 更新字典中任务的最晚开始时间
        taskDict(wbs)(3) = minLate - duration
        ' 更新最晚开始时间
        lateStart = minLate - duration
    Next wbs
   
    ' 确定关键链
    Dim criticalPath As Collection
    Set criticalPath = New Collection
    For Each wbs In taskDict.Keys
        If taskDict(wbs)(1) = taskDict(wbs)(3) Then
            ' 将WBS和任务名称添加到关键链集合中
            criticalPath.Add wbs & " - " & taskDict(wbs)(0)
        End If
    Next wbs
   
    ' 输出关键链
    Dim outputRow As Long
    outputRow = lastRow + 2
    ws.Cells(outputRow, 1).Value = "关键链:"
    For Each wbs In criticalPath
        outputRow = outputRow + 1
        ws.Cells(outputRow, 1).Value = wbs
    Next wbs
End Sub
有老师能帮忙指导一下吗?求求了


TA的精华主题

TA的得分主题

发表于 2024-10-30 09:17 | 显示全部楼层
变量重复声明
taskDict(wbs)(1) = maxEarly + duration
这个你想投机取巧,可惜,字典Item为数组时,不支持这么改,要取出再修改,然后再放入对应Key的item

TA的精华主题

TA的得分主题

发表于 2024-10-30 09:43 | 显示全部楼层
xlj310 发表于 2024-10-30 09:17
变量重复声明
taskDict(wbs)(1) = maxEarly + duration
这个你想投机取巧,可惜,字典Item为数组时,不支 ...

temp = 任务Dic(wbs)
temp(1) = 最早开始 + 持续时间
任务Dic(wbs) = temp

TA的精华主题

TA的得分主题

发表于 2024-10-30 09:45 | 显示全部楼层
VBA是支持中文变量的,能用中文的地方,尽量用中文,可读性比你用英文变量强很多。
帮你大致改了一下,至少可以运行起来了,结果如果不正确,你自己再打断点调试一下:
Sub CalculateAndOutputCriticalPath()
    Set 工作表 = ThisWorkbook.Worksheets(1)
    最行 = 工作表.Cells(工作表.Rows.Count, "A").End(xlUp).Row
    Set 任务Dic = CreateObject("Scripting.Dictionary")
    For i = 2 To 最行
        wbs = CStr(工作表.Cells(i, 1).Value)
        任务名称 = 工作表.Cells(i, 2).Value
        持续时间 = 工作表.Cells(i, 3).Value
        前置依赖 = 工作表.Cells(i, 4).Value
        任务Dic(wbs) = Array(任务名称, 持续时间, 前置依赖) ' 将任务添加到字典中,其中wbs是键
    Next i
    最早开始 = 0 ' 初始化最早开始时间为0
    For Each wbs In 任务Dic.Keys
        持续时间 = 任务Dic(wbs)(1)
        前置依赖 = 任务Dic(wbs)(2)
        For Each 前置依赖 In Split(前置依赖, ",")
            If 任务Dic.Exists(前置依赖) Then
                最早开始 = Application.Max(最早开始, 任务Dic(前置依赖)(1))
            End If
        Next 前置依赖
        temp = 任务Dic(wbs)
        temp(1) = 最早开始 + 持续时间
        任务Dic(wbs) = temp
    Next wbs
    最晚开始 = 0 ' 初始化最晚开始时间为最大值
    For Each wbs In 任务Dic.Keys ' 计算最晚开始时间
        持续时间 = 任务Dic(wbs)(1)
        前置依赖 = 任务Dic(wbs)(2)
        For Each 前置依赖 In Split(前置依赖, ",")
            If 任务Dic.Exists(前置依赖) Then
                最晚开始 = Application.Min(最晚开始, 任务Dic(前置依赖)(1))
            End If
        Next 前置依赖
        temp = 任务Dic(wbs)
        temp(2) = 持续时间 - 最晚开始
        任务Dic(wbs) = temp
    Next wbs
    Dim 关键路径 As Collection
    Set 关键路径 = New Collection ' 确定关键链
    For Each wbs In 任务Dic.Keys
        If 任务Dic(wbs)(1) = 任务Dic(wbs)(2) Then
            关键路径.Add wbs & " - " & 任务Dic(wbs)(0) ' 将WBS和任务名称添加到关键链集合中
        End If
    Next wbs
    输出行 = 最行 + 2
    工作表.Cells(输出行, 1).Value = "关键链:" ' 输出关键链
    For Each wbs In 关键路径
        输出行 = 输出行 + 1
        工作表.Cells(输出行, 1).Value = wbs
    Next wbs
End Sub
image.png
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-24 13:12 , Processed in 0.036642 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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