VC操作MPP文件

1. 背景簡介

因需要對Office系列進行程序操作,特需要使用COM編程。

Microsoft Project生成進度計劃,office家族軟件,文件後綴爲.mpp。

具體信息見維基百科http://zh.wikipedia.org/wiki/Microsoft_Project


讀取MPP文件,網絡上示例基本爲C#,因爲我所使用的是VC,C#代碼只能做參考了。

因爲COM組件是通用的,跨語言的(微軟系),既然C#能做,那麼VC也能做。


開發環境:

Project版本:Microsoft Project 2010。

VS版本:VS2005。


源碼下載


2. VC示例程序

1、  創建MFC工程,工程名爲MyMPP。


創建一個對話框工程。


2、  增加COM接口包裝類。

COM接口的調用,可以通過MFC添加進來。

右鍵Add->Class


選擇MFC Class From TypeLib


選擇MS Project COM組件,並生成包裝類。


Microsoft Project 14.0 Object Library:本機安裝的project 2010所提供的com組件。

Generated classes:爲所需要用到的包裝類,包裝Interfaces中的接口。


最後,會生成五個頭文件。

CIProjectDoc.h、CMSProject.h、CProjects.h、CTask.h、CTasks.h。


3、  COM頭文件調整。

將(CIProjectDoc.h、CMSProject.h、CProjects.h、CTask.h、CTasks.h)

頭文件中代碼替換。

#import "C:\\Program Files\\MicrosoftOffice\\Office14\\MSPRJ.OLB" no_namespace替換爲#pragma once


CIProjectDoc.h、CMSProject.h中使用了很多沒有生成的類,會導致編譯不通過。

解決方法:將出現T*的地方替換爲LPDISPATCH。

例:

Application* GetApplication()
{
    Application* result;
    GetProperty(0xfff4, VT_DISPATCH, (void*)&result);
    return result;
}
調整爲:
LPDISPATCH GetApplication()
{
    LPDISPATCH result;
    GetProperty(0xfff4, VT_DISPATCH, (void*)&result);
    return result;
}

4、  MPP讀取代碼。

添加一個按鈕,按鈕響應代碼如下。

#include "comdef.h"
#include "CMSProject.h"
#include "CProjects.h"
#include "CIProjectDoc.h"
#include "CTasks.h"
#include "CTask.h"

void CMyMPPDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
    CString strFilter = _T("");
    strFilter += _T("MS Project文件(*.mpp)|*.mpp||");
    CFileDialog fileDlg(TRUE, _T("*.mpp"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter);
    if (fileDlg.DoModal() != IDOK )
    {
        return;
    }

    CString strFilePath = fileDlg.GetPathName();

    ::CoInitialize(NULL);
    ReadMppInfo(strFilePath);
    ::CoUninitialize();
}

void CMyMPPDlg::ReadMppInfo(const CString& strFilePath)
{
    CString strTipInfo = _T("");
    try
    {
        CMSProject app;
        if (!app.CreateDispatch(_T("MSProject.Application")))
        {
            MessageBox(_T("Office Project未安裝"));
            return;
        }

        app.SetVisible(FALSE);
        BOOL openRes = app.FileOpen(_variant_t(strFilePath),
            _variant_t(true), vtMissing, vtMissing,
            vtMissing, vtMissing, vtMissing,
            vtMissing, vtMissing, vtMissing, vtMissing,
            1, vtMissing, vtMissing,
            vtMissing, vtMissing);
        if (!openRes)
        {
            MessageBox(_T("Office Project打開失敗!"));
            return;
        }

        CProjects projs;
        projs = app.GetProjects();
        int nProjCount = projs.get_Count();
        for (int i = 1; i <= nProjCount; i++)
        {
            CIProjectDoc projDoc;
            projDoc = projs.get_Item(_variant_t(i));

            CTasks tasks;
            tasks = projDoc.get_Tasks();
            long nTaskCount = tasks.get_Count();
            for (int j = 1; j <= nTaskCount; j++)
            {
                CTask task;
                task = tasks.get_Item(_variant_t(j));

                CString strLevel = IntToCString(task.get_OutlineLevel());
                CString strName = task.get_Name();
                CString strStart = OleDateToStr(task.get_Start().date);
                CString strFinish = OleDateToStr(task.get_Finish().date);
                int nDays = GetTimeSpan(task.get_Start().date, task.get_Finish().date);
                CString strDays = IntToCString(nDays);

                strTipInfo += strLevel;
                strTipInfo += _T("|");
                strTipInfo += strName;
                strTipInfo += _T("|");
                strTipInfo += strDays;
                strTipInfo += _T("|");
                strTipInfo += strStart;
                strTipInfo += _T("|");
                strTipInfo += strFinish;
                strTipInfo += _T("\r\n");
            }
        }

        app.FileClose(0, _variant_t(false));
    }
    catch(_com_error &e)
    {
        MessageBox((LPWSTR)e.Description());
    }

    if (!strTipInfo.IsEmpty())
    {
        MessageBox(strTipInfo);
    }
}

int CMyMPPDlg::GetTimeSpan(const COleDateTime& dtStart, const COleDateTime& dtFinish)
{
    COleDateTimeSpan timeSpan = dtFinish - dtStart;
    int nDays = timeSpan.GetDays();
    if (nDays < 0)
    {
        nDays -= 1;
    }
    else
    {
        nDays += 1;
    }

    return nDays;
}

CString CMyMPPDlg::OleDateToStr(COleDateTime oleDate)
{
    return oleDate.Format(_T("%Y-%m-%d"));
}

CString CMyMPPDlg::IntToCString(int nInput)
{
    CString strInput = _T("");
    strInput.Format(_T("%d"), nInput);
    return strInput;
}

5、  運行結果。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章