アプリケーションからMS Wordを苦しめる

各アプリケーション開発者は、遅かれ早かれ、自分のアプリケーションから別のアプリケーションにデータをエクスポートするタスクに直面します。 だから彼女は再び私の前に立った:私は配布用のメッセージ(郵便配達員が着るメール)を生成する必要があった。 文字はWord形式で保存する必要があります。 タスクは簡単なように見えますが、いくつかの微妙な点があります。 インターネットでは、サードパーティのアプリケーションからCOM呼び出しを介してWordを操作する例がかなりありますが、そのほとんどは「Hello world!」レベルの例であるか、特定のタスクに合わせて調整されています。 気付いていなかったので、次のバイクに精通することを提案します。



タスクの説明



サブスクライバーに関する情報を含むデータベースがあります。 紙の手紙を購読者に送る必要があります。 手紙(テンプレート)のテキストは、非常に遠い(弁護士、マーケティング担当者、およびその他の寄生虫)ITの人々によって作成されますが、何らかの形で単語を使用する方法を知っている(ときどき、非常によく)。 つまり キーワードをテキストに挿入する方法を説明することは非常に可能ですが、より複雑な要件により、認知的不協和が生じます。



2番目のポイントは、印刷する前に必要に応じていくつかの文字を手動検証および編集( UPD )し、同じファイル内にある必要があることです(これは、さらなる転送のメカニズムによるものです)。 つまり 形成の場所で彼らは準備するだけです(そして時々印刷します)。



.Netは歴史的に起こりましたが、データベースを操作するための主要なインターフェースがそこに書かれています。 実際、ユーザーが彼を通して電話をかけることは非常に合理的です。 セキュリティ上の理由とセットアップの複雑さのために、オフィスマクロの使用を放棄しなければなりませんでした。



不適切であることが判明した正面ソリューション



タスクは3ペニーのように単純であるように見えました。テンプレートを取得し、それを出力ドキュメントに挿入し、キーワードを置換し、エントリの最後まで繰り返します。 乗り物ではありません。 レターには複数のページを含めることができます。このアプローチでは、ドキュメントの量が増えるとWordが停止し、30文字のメーリングリストが最大1時間かかることがあります。 私は頭をオンにして考えなければなりませんでした。



どうした



まず、テンプレートを開いて、その中にあるキーワードの出現を探し、その位置を記憶します。

//

string [] keyWords = { "FNAME" , "LNAME" , "DEBT" , "MR" };

//

List<keyWordEntry> keyWordEntries= new List<keyWordEntry>();

for ( int i=0; i<sdoc.Words.Count;i++)

{

foreach ( string keyWord in keyWords)

{

if (sdoc.Words[i+1].Text.Trim()==keyWord)

{

keyWordEntries.Add( new keyWordEntry(keyWord,i+1,sdoc.Words[i+1].Text.Remove(0,keyWord.Length)));

};

};

};



* This source code was highlighted with Source Code Highlighter .






Wordでの作業の最初のジョークはすぐに発見されます(より正確には、このテキストでは最初ですが、研究プロセスではほとんど最後でした)。ドキュメント要素の配列(Word、Paragraphs、ETS) 単語に続くスペース、単語は単語の一部と簡単に考えることができます-私はそれらの保存の論理を書かなければなりませんでした。



テンプレートに基づいて出力ドキュメントを作成するので、適切なページレイアウト、フッター、スタイルなどを備えたドキュメントを作成できます。

_Document ddoc = word.Documents.Add( ref template, ref oMissing, ref oMissing, ref oMissing);

//

ddoc.Range( ref oMissing, ref oMissing).Delete( ref oMissing, ref oMissing);


* This source code was highlighted with Source Code Highlighter .






リクエスト内のレコードの数に応じて段落を埋めます:

for ( int i = 0; i < rowCount; i++)

{

ddoc.Range( ref oMissing, ref oMissing).InsertParagraphAfter();

};


* This source code was highlighted with Source Code Highlighter .






そして、私たちは、スピードを劇的に向上させるよりも、終わりから始めまでいっぱいになり始めます。 段落のインデックスを参照し、毎回ドキュメントの終わりを探すわけではありません。 記入自体は次のとおりです(sdocは値を代入する一時的なドキュメントで、ddocはうまくいくはずです):

for ( int i = rowCount; i > 0; i--)

{

if (i < rowCount)

{

ddoc.Paragraphs[i].Range.InsertParagraphAfter();

ddoc.Paragraphs[i + 1].Range.InsertBreak( ref pageBreak);

};

//

foreach (keyWordEntry ke in keyWordEntries)

{

string replaceWith = "" ;

switch (ke.keyword)

{

//

default :

replaceWith = ke.keyword+ke.spacesAfter;

break ;

};

sdoc.Words[ke.position].Text = replaceWith;

};

sdoc.Range( ref oMissing, ref oMissing).Copy();

ddoc.Paragraphs[i].Range.Paste();

}



* This source code was highlighted with Source Code Highlighter .






基本的にはすべて、受信したドキュメントを保存し、Wordプロセスを正しく完了することが残ります。



追いつくためのいくつかの単語:文字 '。'、 '、'、 '*'そして、残りのすべての単語は別の単語と見なされます。たとえば、日付を挿入する必要がある場合、ロジックは少し複雑になります。



サンプルコードはここからダウンロードできます。



All Articles