0

まず最初に、COM参照を使用した経験がほとんどないので、Microsoft.Office.Interop.Wordをいじってみてください。コードが少し誇張されているように見える場合は、この点に注意してください。基本的に、文字列またはオブジェクトをデータベースに入れて解析するか、C#で直接オブジェクトに対してロジックを実行し、それらの一部をデータベースに入れたいと考えています。

問題の本質は、ライブラリを使用して、特定の段落参照の現在のフォームフィールドをどのように反復するかがわからないことです。以下のコードを調べて、何か提案があれば教えてください。コードを完成させるのに役立つ反復を与えるための適切なプロパティまたはメソッドがわからないと思います。

基本的に、Wordアプリを作成し、Wordアプリを開くことを参照するWord Docを作成し、ドキュメント内の段落を繰り返し処理し、ブロックを文字配列に分割します。私のコードでは、21に相当するASCII文字が表示されたときに、それが解析したいフォームボックスの一種であることがわかります。ただし、intのスコープをどこに設定し、インクリメントを設定してもスコープが変更されない場合でも、反復を正常にインクリメントすることはできません。これは奇妙なことです。したがって、私は途方に暮れていて、自分がやっていることをもっとうまくやる方法があるかどうか興味がありました。私がしていることをするもっと簡単な方法があるかもしれません。この問題を解決するために、段落オブジェクトとは別にFormオブジェクトを返すメソッドを作成できる可能性があることを知っています。しかし、それは私には奇妙に思えるので、私は尋ねると思いました。

.NET 4.5を使用しており、Office 2013にアップグレードしたときに、何らかの理由でMicrosoft.Office.Interop.Word ver 15のDLLを手動で参照として追加する必要がありましたが、VSで参照が直接更新されませんでした。これが私のかなり厄介なコードです:

public static string ReadTest(string loc)
        {
            Word._Application wordApp = new Word.Application();
            Word._Document Doc = wordApp.Documents.Open(loc, ReadOnly: true);

            try
            {
                sb = "";

                // This will get me JUST THE FORMS info
                //foreach (Word.FormField form in Doc.FormFields)
                //{
                //    sb += form.Result + "\n";
                //}


                int x = 1;

                foreach (Word.Paragraph objParagraph in Doc.Paragraphs)
                {
                    string st = "";

                    try
                    {
                        foreach (char c in objParagraph.Range.Text)
                        {
                            if (((int)c) != 21)
                            {
                                st += c;
                            }
                            else
                            {
                                st += Doc.FormFields.get_Item(x).Result;
                            }
                        }

                        sb += st + "\n";

                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }

                    x += 1;

                }

            }
            catch (COMException) { }
            finally
            {
                //FileInfo finfo = new FileInfo(loc);
                //finfo.IsReadOnly = false;

                if (Doc != null)
                {
                    Doc.Close();
                    Doc = null;
                }
                if (wordApp != null)
                {
                    wordApp.Quit(Word.WdSaveOptions.wdDoNotSaveChanges);
                    wordApp = null;
                }
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();

            return sb;
        }
4

1 に答える 1

1

確かに、x増分の正しい位置は、フォームフィールドにアクセスしている行の直後の行です。

                        else
                        {
                            st += Doc.FormFields.get_Item(x).Result;
                            x++;
                        }

すでにそこに配置しようとしたかどうかはわかりませんが、投稿したコードは、ドキュメントに段落ごとに1つのフォームフィールドがある場合にのみ機能します。

実際、複数のフィールドがある場合、2番目、3番目などを見つけたときに、21文字のxはまだインクリメントされていないため、常に同じフィールドを読み取ることになります。

たとえば、最初の段落にフィールドがあり、3番目の段落に別のフィールドがある場合、コードは最初のフィールドを見つけ、xをインクリメントして、21文字を見つけずにx=2で2番目の段落を読み取ります。次に、xがもう一度インクリメントされ、フィールドが2つしかない場合はx = 3で3番目の段落の文字をスキャンします。したがって、21文字を取得すると、そうでないフィールド(3番目の文字)を探します。存在。

PSサンプルドキュメントでの作業を支援する方がはるかに簡単です

于 2013-02-04T17:51:51.327 に答える