各アプリケーション開発者は、遅かれ早かれ、自分のアプリケーションから別のアプリケーションにデータをエクスポートするタスクに直面します。 だから彼女は再び私の前に立った:私は配布用のメッセージ(郵便配達員が着るメール)を生成する必要があった。 文字は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プロセスを正しく完了することが残ります。
追いつくためのいくつかの単語:文字 '。'、 '、'、 '*'そして、残りのすべての単語は別の単語と見なされます。たとえば、日付を挿入する必要がある場合、ロジックは少し複雑になります。
サンプルコードは
ここからダウンロードでき
ます。