次の方法で共有


ワープロ ドキュメントを DOCM から DOCX ファイル形式に変換する

このトピックでは、Open XML SDK for Office のクラスを使用して、VBA コード (.docm 拡張機能を持つ) を含む Microsoft Word ドキュメントを (.docx 拡張機能を持つ) 標準ドキュメントにプログラムで変換する方法について説明します。 このタスクを示すメソッド ConvertDOCMtoDOCX 例が含まれています。

ConvertDOCMtoDOCX メソッド

ConvertDOCMtoDOCXサンプル メソッドを使用すると、VBA コード (および .docm 拡張子を持つ) を含むWordドキュメントを標準ドキュメント (.docx 拡張子を持つ) に変換できます。 このメソッドでは、マクロおよびマクロが格納されている vbaProject パーツを, .docm ファイル形式で格納されているドキュメントから削除します。 このメソッドは、変換するファイルのファイル名を示すパラメーターを 1 つだけ受け取ります。

static void ConvertDOCMtoDOCX(string fileName)

このメソッドの完全なコードについては、「サンプル コード」セクションを参照してください。

サンプル メソッドの呼び出し

サンプル メソッドを呼び出すには、変換するファイルの名前を含んだ文字列を渡します。 次のサンプル コードは例を示しています。

ConvertDOCMtoDOCX(args[0]);

パーツおよび vbaProject パーツ

.docx または .docm の拡張子を持つファイルなどのワープロ ドキュメント パッケージは、実際にはいくつかのパーツで構成される .zip ファイルです。 各パーツは外部ファイルに類似のものと考えることができます。 パーツには特定のコンテンツ タイプがあり、種類に応じて、外部 XML ファイル、バイナリ ファイル、イメージ ファイルなどのファイルに同等のコンテンツを格納できます。 Open XML ドキュメントを .zip ファイルに格納する方法を定義している標準は、Open Packaging Conventions と呼ばれています。 オープン パッケージ規則の詳細については、「 ISO/IEC 29500-2:2021」を参照してください。

ドキュメントで VBA マクロを作成して保存すると、Word は、マクロ プロジェクトの内部表現が格納された vbaProject という名前の新しいバイナリ パーツを追加します。 Open XML SDK Productivity Tool for Microsoft Office のドキュメント エクスプローラーの次の図は、マクロを含むサンプル ドキュメント内のドキュメント パーツを示しています。 vbaProject パーツが強調表示されています。

図 1. vbaProject パーツ

ドキュメント エクスプローラーに表示されている vbaProject パーツ

したがって、マクロ有効ドキュメントをマクロ有効でないドキュメントに変換する作業の大部分は、vbaProject パーツをドキュメント パッケージから削除する操作で構成されます。

コードの動作のしくみ

サンプル コードは、指定されたドキュメントに vbaProject パーツが含まれているかどうかを確認し、そのパーツを削除して、そのドキュメントを変更します。 パーツを削除した後は、ドキュメントの種類を内部的に変更し, .docx 拡張子を使用するようにドキュメントの名前を変更します。

コードは、まず、 Open メソッドを使用してドキュメントを開き、読み取り/書き込みアクセス (最後の true パラメーター) のためにドキュメントを開く必要があることを示します。 次に、コードは、ワープロ ドキュメントの MainDocumentPart プロパティを使用して、Document パーツへの参照を取得します。

bool fileChanged = false;

using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
{
    // Access the main document part.
    var docPart = document.MainDocumentPart ?? throw new ArgumentNullException("MainDocumentPart is null.");

ドキュメントからパーツを削除するだけでは不十分です。 ドキュメントの種類を内部的に変更する必要もあります。 Open XML SDK は、このタスクを実行する方法を提供します。ドキュメント ChangeDocumentType メソッドを呼び出し、新しいドキュメントの種類を示すことができます (この場合は、 WordprocessingDocumentType.Document 列挙値を指定します)。

ファイルの名前を変更する必要もあります。 ただし、ファイルを開いたまま変更することはできません。 using ブロックで、ブロックの末尾にあるファイルを閉じます。 したがって、ファイルを変更したことをブロックの後にコードに示す何らかの方法が必要です。 fileChanged ブール変数は、この情報を追跡します。

// Look for the vbaProject part. If it is there, delete it.
var vbaPart = docPart.VbaProjectPart;
if (vbaPart is not null)
{
    // Delete the vbaProject part.
    docPart.DeletePart(vbaPart);

次に、新しく変更された文書の名前を変更します。 これを行うために、コードは拡張機能を変更して新しいファイル名を作成します。は、出力ファイルが存在することを確認して削除し、最後にファイルを古いファイル名から新しいファイル名に移動します。

// If anything goes wrong in this file handling,
// the code will raise an exception back to the caller.
if (fileChanged)
{
    // Create the new .docx filename.
    var newFileName = Path.ChangeExtension(fileName, ".docx");

    // If it already exists, it will be deleted!
    if (File.Exists(newFileName))
    {
        File.Delete(newFileName);
    }

    // Rename the file.
    File.Move(fileName, newFileName);
}

サンプル コード

C# と Visual Basic の完全な ConvertDOCMtoDOCX コード サンプルを次に示します。

static void ConvertDOCMtoDOCX(string fileName)
{
    bool fileChanged = false;

    using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
    {
        // Access the main document part.
        var docPart = document.MainDocumentPart ?? throw new ArgumentNullException("MainDocumentPart is null.");

        // Look for the vbaProject part. If it is there, delete it.
        var vbaPart = docPart.VbaProjectPart;
        if (vbaPart is not null)
        {
            // Delete the vbaProject part.
            docPart.DeletePart(vbaPart);

            // Change the document type to
            // not macro-enabled.
            document.ChangeDocumentType(WordprocessingDocumentType.Document);

            // Track that the document has been changed.
            fileChanged = true;
        }
    }

    // If anything goes wrong in this file handling,
    // the code will raise an exception back to the caller.
    if (fileChanged)
    {
        // Create the new .docx filename.
        var newFileName = Path.ChangeExtension(fileName, ".docx");

        // If it already exists, it will be deleted!
        if (File.Exists(newFileName))
        {
            File.Delete(newFileName);
        }

        // Rename the file.
        File.Move(fileName, newFileName);
    }
}

関連項目