You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用VBA提取MS Project中资源每月工作可用时长?

提取MS Project资源每月可用工作时长的VBA方法

要提取资源每月的可用工作时长,核心是利用MS Project对象模型中的资源日历(Resource.Calendar)和可用性集合(Resource.Availability),以下是具体实现方法和代码示例:

方法1:基于资源日历计算每月可用工时

通过资源的日历对象,调用WorkingHours方法计算指定月份的总工作时长,该方法会自动考虑日历的工作日设置、例外日期等规则。

示例代码(扩展你的现有代码)

Sub ExtractResourceMonthlyAvailability()
    Dim ws As Worksheet
    Dim res As Resource
    Dim ligne As Integer
    Dim startDate As Date, endDate As Date
    Dim currentMonthStart As Date, currentMonthEnd As Date
    Dim totalMonths As Integer, i As Integer
    
    ' 设置输出工作表
    Set ws = Sheets(1)
    ws.Cells.Clear
    
    ' 写入表头:资源名称、组,以及各月份列
    ws.Cells(1, 1).Value = "Nom"
    ws.Cells(1, 2).Value = "Groupe"
    
    ' 定义时间范围(可根据项目实际调整)
    startDate = ActiveProject.Start
    endDate = ActiveProject.Finish
    
    ' 计算总月份数并生成月份表头
    totalMonths = DateDiff("m", startDate, endDate) + 1
    currentMonthStart = DateSerial(Year(startDate), Month(startDate), 1)
    For i = 1 To totalMonths
        ws.Cells(1, 2 + i).Value = Format(currentMonthStart, "yyyy-mm")
        currentMonthStart = DateAdd("m", 1, currentMonthStart)
    Next i
    
    ligne = 2
    ' 遍历每个资源
    For Each res In ActiveProject.Resources
        If Not res Is Nothing And Trim(res.Code) <> "" Then
            ' 写入资源基本信息
            ws.Cells(ligne, 1).Value = res.Name
            ws.Cells(ligne, 2).Value = res.Group
            
            ' 计算每个月的可用工时
            currentMonthStart = DateSerial(Year(startDate), Month(startDate), 1)
            For i = 1 To totalMonths
                ' 获取当月最后一天
                currentMonthEnd = DateSerial(Year(currentMonthStart), Month(currentMonthStart) + 1, 0)
                ' 确保不超过项目结束日期
                If currentMonthEnd > endDate Then currentMonthEnd = endDate
                
                ' 计算该月可用工时(单位:小时)
                ws.Cells(ligne, 2 + i).Value = res.Calendar.WorkingHours(currentMonthStart, currentMonthEnd)
                
                currentMonthStart = DateAdd("m", 1, currentMonthStart)
            Next i
            
            ligne = ligne + 1
        End If
    Next res
End Sub

方法2:基于Resource.Availability集合

如果资源有自定义的可用性时间段(比如部分时间可用、阶段性可用),可以直接遍历Resource.Availability集合,将每个时间段拆分到对应月份计算时长:

核心代码片段

' 遍历资源的可用性时间段
For Each avail In res.Availability
    Dim availStart As Date, availFinish As Date
    availStart = avail.Start
    availFinish = avail.Finish
    
    ' 拆分时间段到每个月
    Dim monthStart As Date, monthEnd As Date
    monthStart = DateSerial(Year(availStart), Month(availStart), 1)
    Do While monthStart <= availFinish
        monthEnd = DateSerial(Year(monthStart), Month(monthStart) + 1, 0)
        If monthEnd > availFinish Then monthEnd = availFinish
        If monthStart < availStart Then monthStart = availStart
        
        ' 计算该时间段在当月的时长(小时)
        Dim monthlyHours As Double
        monthlyHours = DateDiff("n", monthStart, monthEnd) / 60 * avail.Available
        
        ' 将结果写入对应月份列(需自行匹配月份列的位置)
        ' ws.Cells(ligne, colIndex).Value = monthlyHours
        
        monthStart = DateAdd("m", 1, monthStart)
    Loop
Next avail

关键说明

  • WorkingHours方法返回的是总工作小时数,已排除非工作日和例外日期。
  • Availability.Available属性是资源在该时间段的可用比例(比如0.5表示50%可用),需乘以实际时长得到有效可用工时。
  • 若资源使用的是项目基准日历,res.Calendar会继承基准日历的设置;若有单独的资源日历,则优先使用资源自身的日历。

内容的提问来源于stack exchange,提问作者jca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 08:52:44