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

求助:如何在Microsoft Project的Timescale中读写任务工时数据?

问题解决:Microsoft Project工时刻度(Timescale)数据的Python读写方案

问题背景

无法在Microsoft Project任务使用视图的工时刻度中提取或写入数据,现有1000+任务需批量导入员工工时表数据,避免手动操作。尝试编写的Python代码逻辑看似正确,但始终无法运行。

原代码的潜在问题

  1. 枚举常量值错误:原代码中pjAssignmentTimescaledWork和pjTimescaleDays的数值与MS Project COM对象的实际枚举值不匹配,导致无法正确调用TimescaleData方法。
  2. COM初始化不严谨:未处理初始化失败的情况,且未确保Project实例正确激活,易引发调用异常。
  3. 缺少写入逻辑:原代码仅实现读取,未覆盖批量写入工时数据的核心需求。
  4. 边界检查不足:未处理任务无资源分配、日期为空等特殊场景,易触发报错。

修正后的代码(支持读写)

import pythoncom
import win32com.client
from win32com.client import constants as ms_const
import datetime

def init_ms_project():
    # 初始化COM环境
    pythoncom.CoInitialize()
    # 创建Project实例
    ms_project = win32com.client.Dispatch('MSProject.Application')
    ms_project.Visible = True
    return ms_project

def open_project(ms_project, file_path):
    # 关闭已有项目,避免冲突
    if ms_project.Projects.Count > 0:
        ms_project.FileCloseEx(0)  # 0 = pjDoNotSave
    ms_project.FileOpen(file_path)
    return ms_project.ActiveProject

def read_timescale_data(task):
    """读取任务分配的工时刻度数据"""
    print(f"任务: {task.Name}")
    if task.Assignments.Count == 0:
        print("  无资源分配")
        return
    for assignment in task.Assignments:
        print(f"  资源: {assignment.ResourceName}")
        try:
            # 使用官方枚举常量,避免数值错误
            timephased_data = assignment.TimescaleData(
                StartDate=task.Start,
                EndDate=task.Finish,
                TimeScaleUnit=ms_const.pjTimescaleDays,
                Type=ms_const.pjAssignmentTimescaledWork
            )
            for idx, data in enumerate(timephased_data):
                print(f"    时间段{idx+1}: {data.StartDate} - {data.EndDate}, 工时: {data.Value}小时")
        except Exception as e:
            print(f"  读取失败: {str(e)}")

def write_timescale_data(assignment, date_work_dict):
    """批量写入工时刻度数据:date_work_dict为{日期: 工时(小时)}"""
    try:
        # 获取任务全周期的工时刻度集合
        timephased_data = assignment.TimescaleData(
            StartDate=assignment.Task.Start,
            EndDate=assignment.Task.Finish,
            TimeScaleUnit=ms_const.pjTimescaleDays,
            Type=ms_const.pjAssignmentTimescaledWork
        )
        # 遍历时间段,匹配日期并设置工时(MS Project工时单位为分钟,需转换)
        for data in timephased_data:
            target_date = data.StartDate.date()
            if target_date in date_work_dict:
                data.Value = date_work_dict[target_date] * 60
        print(f"  资源{assignment.ResourceName}工时写入完成")
    except Exception as e:
        print(f"  写入失败: {str(e)}")

if __name__ == "__main__":
    file_path = r"D:\Manufacturing Resourcing\Test Folder\Test.mpp"
    # 示例工时数据:替换为实际员工提交的工时表数据
    sample_work_data = {
        datetime.date(2024, 5, 1): 8,
        datetime.date(2024, 5, 2): 7.5,
        datetime.date(2024, 5, 3): 8
    }

    ms_project = init_ms_project()
    project = open_project(ms_project, file_path)

    # 遍历任务,读取并写入数据
    for task in project.Tasks:
        if task is None or not task.Start or not task.Finish:
            continue
        read_timescale_data(task)
        # 针对有资源分配的任务写入数据(示例:给第一个分配写入数据)
        if task.Assignments.Count > 0:
            write_timescale_data(task.Assignments(1), sample_work_data)

    # 保存项目
    ms_project.FileSave()
    # 清理COM环境
    pythoncom.CoUninitialize()

关键注意事项

  • 依赖安装:确保已安装pywin32库,执行pip install pywin32完成安装
  • 版本兼容:代码适用于Microsoft Project 2016及以上版本,不同版本需确认枚举值一致性
  • 单位转换:MS Project中工时存储单位为分钟,写入时需将小时转换为分钟
  • 权限问题:运行代码时需以管理员权限启动Python,避免COM调用权限不足
  • 实例冲突:运行前关闭所有Microsoft Project窗口,避免实例冲突导致文件打开失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:53:18