none
Word2010で作成したテキストボックスの中をC#で変更する方法がわかりません RRS feed

  • 質問

  • VisualStudio2017を使用して、コーディング上にMicrosoft.Office.Interop.Wordを追加し、C#の

    ロジックを作っています。

    すでに作成しているWord文書の中にテキストボックスがありまして、その中の「YYYY-MM-DD」の個所を当日の

    年月日「2018-4-1」に変更したいのですが、まずはテキストボックスをさがすことがわかりません。

    以上のようなことについて、一連のサンプルコーディングをご教示ください。

    いろいろとWeb上をさがしたのですが、何分にも知識が薄いため、以上の内容を見つけることができませんでした。

    大変失礼とは思いますが、ご協力をお願いします。  [以上]

    2018年4月1日 5:33

回答

  • テキストボックスにはあらかじめプロパティダイアログで分かりやすい名前(オブジェクト名)を付けておきます。

    あとは名前をもとにMicrosoft.Office.Interop.Word.Document.Shapesから検索します。

    static void ReplaceDateInShapeText(Document doc, string name, DateTime date)
    {
    	foreach (Shape shape in doc.Shapes)
    	{
    		if (shape.Name == name)
    		{
    			shape.TextFrame.ContainingRange.Text.Replace("YYYY-MM-DD", date.ToString("yyyy-MM-dd"));
    			return;
    		}
    	}
    }


    • 編集済み sygh 2018年4月1日 6:27
    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 6:25
  • Range::TextはString型を返し、String::Replaceは「自身は置換せず、置換した文字列を返す」って仕様なので、置き換えられた文字列を代入し直す必要がありますね。

    var range = shape.TextFrame.ContainingRange;
    range.Text = range.Text.Replace(...);
    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 14:18
  • sygh様 ご教示ありがとうございます。

    ご教示いただきましたコーディングの内容を当方でアレンジして、実施しました。 その結果、テキストボックスを見つけることが

    できました。 次に「YYYY-MM-DD」の文字列を本日の日付「2018-04-01」にReplaceしたところ、残念ながら本日の

    日付に変更できません。 このロジックを実行したときの内容と当方がアレンジしたコーディングの内容をお届けしますので。

    何が問題なのかご指摘ください。

    コーディング↓

    string year = DateTime.Now.Year.ToString( "0000" );
    string month = DateTime.Now.Month.ToString( "00" );
    string day = DateTime.Now.Day.ToString( "00" );
    string today = year + "-" + month + "-" + day;
    Debug.WriteLine( "today={0}", today );
    foreach( Word.Shape shape in wordDoc.Shapes )
    {
    Debug.WriteLine( "shape.Name={0}", shape.Name );

    if( shape.Name == "Text Box 1" )
    {
    Debug.WriteLine( "shape.Name={0}, {1}", shape.Name, "ok" );
    shape.TextFrame.ContainingRange.Text.Replace( "YYYY-MM-DD", today );
    int wSharpLen = shape.TextFrame.ContainingRange.Text.Length;
    Debug.WriteLine( "wShapeLen={0}", wSharpLen );
    string wShape = shape.TextFrame.ContainingRange.Text;
    Debug.WriteLine( "wShape={0}", wShape );
    break;
    }
    }

    実行したときの内容(Debug.WriteLine

    2018-04-01: today={0}
    Text Box 1: shape.Name={0}
    shape.Name=Text Box 1, ok
    wShapeLen=11
    YYYY-MM-DD
    : wShape={0}

    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 12:46

すべての返信

  • テキストボックスにはあらかじめプロパティダイアログで分かりやすい名前(オブジェクト名)を付けておきます。

    あとは名前をもとにMicrosoft.Office.Interop.Word.Document.Shapesから検索します。

    static void ReplaceDateInShapeText(Document doc, string name, DateTime date)
    {
    	foreach (Shape shape in doc.Shapes)
    	{
    		if (shape.Name == name)
    		{
    			shape.TextFrame.ContainingRange.Text.Replace("YYYY-MM-DD", date.ToString("yyyy-MM-dd"));
    			return;
    		}
    	}
    }


    • 編集済み sygh 2018年4月1日 6:27
    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 6:25
  • sygh様 ご教示ありがとうございます。

    ご教示いただきましたコーディングの内容を当方でアレンジして、実施しました。 その結果、テキストボックスを見つけることが

    できました。 次に「YYYY-MM-DD」の文字列を本日の日付「2018-04-01」にReplaceしたところ、残念ながら本日の

    日付に変更できません。 このロジックを実行したときの内容と当方がアレンジしたコーディングの内容をお届けしますので。

    何が問題なのかご指摘ください。

    コーディング↓

    string year = DateTime.Now.Year.ToString( "0000" );
    string month = DateTime.Now.Month.ToString( "00" );
    string day = DateTime.Now.Day.ToString( "00" );
    string today = year + "-" + month + "-" + day;
    Debug.WriteLine( "today={0}", today );
    foreach( Word.Shape shape in wordDoc.Shapes )
    {
    Debug.WriteLine( "shape.Name={0}", shape.Name );

    if( shape.Name == "Text Box 1" )
    {
    Debug.WriteLine( "shape.Name={0}, {1}", shape.Name, "ok" );
    shape.TextFrame.ContainingRange.Text.Replace( "YYYY-MM-DD", today );
    int wSharpLen = shape.TextFrame.ContainingRange.Text.Length;
    Debug.WriteLine( "wShapeLen={0}", wSharpLen );
    string wShape = shape.TextFrame.ContainingRange.Text;
    Debug.WriteLine( "wShape={0}", wShape );
    break;
    }
    }

    実行したときの内容(Debug.WriteLine

    2018-04-01: today={0}
    Text Box 1: shape.Name={0}
    shape.Name=Text Box 1, ok
    wShapeLen=11
    YYYY-MM-DD
    : wShape={0}

    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 12:46
  • Range::TextはString型を返し、String::Replaceは「自身は置換せず、置換した文字列を返す」って仕様なので、置き換えられた文字列を代入し直す必要がありますね。

    var range = shape.TextFrame.ContainingRange;
    range.Text = range.Text.Replace(...);
    • 回答としてマーク inoshishiboa 2018年4月2日 0:16
    2018年4月1日 14:18
  • 指摘があったとおり、以下のようにString.Replace()メソッドの戻り値として生成された新しいStringオブジェクトを代入する必要があります(.NETのStringはimmutableであることを失念していました)。

    static void ReplaceDateInShapeText(Document doc, string name, DateTime date)
    {
    	foreach (Shape shape in doc.Shapes)
    	{
    		if (shape.Name == name)
    		{
    			var range = shape.TextFrame.ContainingRange;
    			range.Text = range.Text.Replace("YYYY-MM-DD", date.ToString("yyyy-MM-dd"));
    			return;
    		}
    	}
    }

    なお、DateTimeオブジェクトを文字列化するのに、わざわざYear, Month, DayプロパティをそれぞれInt32.ToString()で文字列化する必要はありません。サンプルコードにて示しているように、DateTime.ToString()の書式指定文字列を使えば一発で文字列化できます。

    また、DateTime.Nowプロパティは呼び出したタイミングの日時を返します。呼び出すたびに別のオブジェクトが割り当てられます。通例、一時オブジェクトのプロパティに直接アクセスすることはせず、いったんローカル変数にコピーしてから使います。

    var now = DateTime.Now;
    System.Diagnostics.Debug.WriteLine($"Year={now.Year}, Month={now.Month}, Day={now.Day}");

    サンプルとして示したメソッドは、提示された要件であればアレンジというかわざわざ展開する必要は一切なく、適当なクラス内にメソッドを定義することでそのまま使えるはずです。まずはメソッドおよびメソッド引数、値型と参照型について学習してみてください。

    メソッド (C# プログラミング ガイド) | Microsoft Docs

    値型 (C# リファレンス) | Microsoft Docs

    参照型 (C# リファレンス) | Microsoft Docs

    • 編集済み sygh 2018年4月1日 18:56
    2018年4月1日 16:41
  • Hongliang様 ありがとうございます。

    ご指摘のようなコーディングに変更したところ、置換がうまくできました。

    知識の薄いなかで、本来のプログラムが完成に至るようです。 感謝感謝の念に堪えません。

    2018年4月1日 23:58
  • sygh様 たびたびのご教示まことにありがとうございます。

    ご指摘のようにロジックを変更して実行したところ、うまく置換ができました。

    C#および関連するところに、大変無知な知識しかない中で、無謀にもWord文書

    を編集するプログラムを作ろうとしておりますが、ご教示願いました内容を踏まえて、

    ようやく完成の目処がつきました。

    また、日付の編集につきましてご教示いただきましたことも今回のプログラムに反映さ

    せていただき、簡潔なプログラムにするようにいたします。

    最後に"本当に感謝申し上げます”

    2018年4月2日 0:15