C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C#からWORD文書内のブックマークへ書き込み /S.Kos (20/12/21(Mon) 11:16) #96571
Re[1]: C#からWORD文書内のブックマークへ書き込み /ニケ (20/12/22(Tue) 09:20) #96580
  └ Re[2]: C#からWORD文書内のブックマークへ書き込み /S.Kos (21/01/05(Tue) 10:42) #96642
    └ Re[3]: C#からWORD文書内のブックマークへ書き込み /Hongliang (21/01/05(Tue) 13:30) #96645
      └ Re[4]: C#からWORD文書内のブックマークへ書き込み /S.Kos (21/01/05(Tue) 14:36) #96647
        └ Re[5]: C#からWORD文書内のブックマークへ書き込み /Hongliang (21/01/05(Tue) 14:42) #96648
          └ Re[6]: C#からWORD文書内のブックマークへ書き込み /S.Kos (21/01/05(Tue) 15:57) #96653
            └ Re[7]: C#からWORD文書内のブックマークへ書き込み /魔界の仮面弁士 (21/01/05(Tue) 16:47) #96656
              └ Re[8]: C#からWORD文書内のブックマークへ書き込み /S.Kos (21/01/06(Wed) 16:15) #96660 解決済み


親記事 / ▼[ 96580 ]
■96571 / 親階層)  C#からWORD文書内のブックマークへ書き込み
□投稿者/ S.Kos (32回)-(2020/12/21(Mon) 11:16:40)

分類:[.NET 全般] 

みなさま、こんにちは。

C#(VS2019)からWORD(365)文書に配置したブックマークに、下記の如く、
  object oBookMark = "bmSumple"; 
  if( oWordDoc.Bookmarks.Exists(oBookMark.ToString()) == true ) {
    oWordDoc.Bookmarks.get_Item(ref oBookMark).Range.Text = "書き出し文字列"; 
  }
として、書込んでいます。

これだと、書き込みむ文字列長さによって、WORD文書の形式が崩れてしまいます。
例えば「担当者__________印」の__________をブックマークしたとき、末尾「印」の位置が変わります。

現状では、書き込み位置にテキストボックスを置き、その中をブックマークしています。

WORD文書の形式を保ったまま、ブックマークに書込む方法をご教示願えれば幸いです

[ □ Tree ] 返信 編集キー/

▲[ 96571 ] / ▼[ 96642 ]
■96580 / 1階層)  Re[1]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ ニケ (4回)-(2020/12/22(Tue) 09:20:35)
No96571 (S.Kos さん) に返信
C#関係ないWordの仕様の話では?
…"書き出し文字列"を形式が崩れない長さでカットすればできます。
[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96580 ] / ▼[ 96645 ]
■96642 / 2階層)  Re[2]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ S.Kos (33回)-(2021/01/05(Tue) 10:42:50)
No96580 (ニケ さん) に返信
> C#関係ないWordの仕様の話では?
> …"書き出し文字列"を形式が崩れない長さでカットすればできます。
>
ご教示のほど感謝です。
これの意図は、最初の投稿、
>>例えば「担当者__________印」の__________をブックマークしたとき、末尾「印」の位置が変わります。
>>
に対して、
書き出す名前が「森博」または「佐々木小次郎」であるとき、書き出す側で文字長を揃えろ、とのことですよね?

そうではなく「書き出す文字長に関わらず文書の形式を保つ方法」を探しています。


ブックマークへの書き込みでは文書形式が保てない、と判ったとき、書込み位置に固有の名前を付けたテキストボックスを置いて、C#からの操作を試みました。
あちこち彷徨いましたが、その「名前を付けたテキストボックス」を、特定する方法が見つけられませんでした。

辿り着いた「当面の策」が、そのテキストボックスの中をブックマークする、という手法です。

ただこれは二度手間なので・・・・
 1 WORD文書の形式を保ったまま、ブックマークに書込む方法
 2 名前を付けたテキストボックスを特定する方法
のいずれかを探しています。


[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96642 ] / ▼[ 96647 ]
■96645 / 3階層)  Re[3]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ Hongliang (1137回)-(2021/01/05(Tue) 13:30:02)
>  2 名前を付けたテキストボックスを特定する方法
それはActiveXコントロールでしょうか?
ShapeならDocumentのShapesプロパティから特定のNameを持ったShapeを探すだけですが…。
[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96645 ] / ▼[ 96648 ]
■96647 / 4階層)  Re[4]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ S.Kos (34回)-(2021/01/05(Tue) 14:36:53)
No96645 (Hongliang さん) に返信
> ShapeならDocumentのShapesプロパティから特定のNameを持ったShapeを探すだけですが…。
>
ご教示の程、ありがとうございます。
その「DocumentのShapesプロパティから特定のName」が探せずに四苦八苦しています。

現状では以下としています。
using Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;



Word._Application oWordApp = new Word.Application();
oWordApp.Visible = false;

Word._Document oWordDoc = oWordApp.Documents.Open(‥
oWordDoc.Shapes.??

この??でテキストボックス(Shape)の名前を指定すれば…と思うのですが、その術が判りません。
oWordDoc.Shapes.Item("hoge")とできれば良いのですが、ダメですね!



[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96647 ] / ▼[ 96653 ]
■96648 / 5階層)  Re[5]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ Hongliang (1138回)-(2021/01/05(Tue) 14:42:03)
> この??でテキストボックス(Shape)の名前を指定すれば…と思うのですが、その術が判りません。
> oWordDoc.Shapes.Item("hoge")とできれば良いのですが、ダメですね!

var shape = oWordDoc.Shapes["hoge"];
なお指定した名前のShapeが存在しない場合、例外が投げられます。
[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96648 ] / ▼[ 96656 ]
■96653 / 6階層)  Re[6]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ S.Kos (35回)-(2021/01/05(Tue) 15:57:26)
No96648 (Hongliang さん) に返信
> var shape = oWordDoc.Shapes["hoge"];
>
ご教示、大感謝です!

Word.Shape tmpShape = oWordDoc.Shapes["hoge"];
tmpShape.TextFrame.TextRange.Text = "なんちゃら";
で、できました!

("hoge")はダメ、["hoge"]なら良し、この見分け(?)はどこにあるのでしょう・・
先の投稿に至るまでに、かなりの時間を掛けて、あちこち彷徨ったのですが、この[]は見つけられませんでした。

もう暫く閉じずにおきますので、重ねてご教示いただけれは幸いです。

なにはともあれ、二度手間を避けるメドが立ちました。
ありがとうございました。
[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96653 ] / ▼[ 96660 ]
■96656 / 7階層)  Re[7]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ 魔界の仮面弁士 (2944回)-(2021/01/05(Tue) 16:47:26)
2021/01/05(Tue) 17:01:36 編集(投稿者)

No96653 (S.Kos さん) に返信
> ("hoge")はダメ、["hoge"]なら良し、この見分け(?)はどこにあるのでしょう・・

C# における ["hoge"] や [1] は、インデクサー (indexer) 構文と呼ばれるものです。

VBA / Visual Basic の世界においては、丸括弧指定による
「配列のインデックス」や「引数付きデフォルトプロパティ」にあたります。

https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/indexers/
http://tki.main.jp/hata/indexer2.html



> Word.Shape tmpShape = oWordDoc.Shapes["hoge"];

VBA で [F2] キーを押してオブジェクト ブラウザーを表示してみてください。
そして左上のドロップダウンで [Word]を選択しておきます。

左側のペインで Document オブジェクトをクリックしてみると、
右側に Shapes プロパティが現れます。それを選択すると、
|
| Property Shapes As Shapes
|  読み取り専用
|  Word.Document のメンバー
|
と記載されていることを確認できます。

このことから、oWordDoc.Shapes すなわち「Word.Document オブジェクト」の
Shapes メンバーが、「0 個の引数を受け取る読取専用プロパティ」であり、
その戻り値として Word.Shapes コレクション型を返すということが分かります。


さらに、そのオブジェクト ブラウザーにて、
左側のペインから Shapes オブジェクトを選択すると、
右側に Item プロパティが(他と異なる水色を纏ったアイコンで)現れ、その定義が
|
| Function Item(Index) As Shape
|  Word.Shapes の既定メンバー
|
と記載されていることを確認できます。

これはすなわち、「Word.Shpes オブジェクト」の
Item メンバーは、「1 個の引数を必要とするデフォルト メソッド」であり、
その戻り値として Word.Shape オブジェクト型を返すということが分かります。


Visual Basic では、プロパティの引数もメソッドの引数も
どちらも (丸括弧) で指定します。
引数が 0 個の時は丸括弧も省略できます。
そのプロパティやメソッドが、オブジェクトの「デフォルトメンバー」の場合
メンバー名を省略してアクセスすることも可能です。


一方 C# は、プロパティには引数を指定できません。
また、メソッドなら丸括弧指定で引数を指定しますが、
メソッドの引数が 0 個であっても丸括弧は省略できません。
ただし、「デフォルトメンバーを持つオブジェクト」の場合には、
[角括弧] を使った「インデクサー」構文を使うことで、
デフォルトメンバーへのアクセスが可能になります。


> Word.Shape tmpShape = oWordDoc.Shapes["hoge"];

上記を VBA の構文で記す場合、
 Dim tmpShape As Word.Shape
 Set tmpShape = oWordDoc.Shapes.Item("hoge")
と書けます。ただし Item はデフォルト プロパティのため、通常は
 Set tmpShape = oWordDoc.Shapes("hoge")
と書きます。

Shapes 型と Shape 型を明確に分ける場合には、意図的に
 Set tmpShapes = oWordDoc.Shapes '引数無し読取専用プロパティ
 Set tmpShape = tmpShapes("hoge") '引数付きデフォルトプロパティ
 'Set tmpShape = tmpShapes.Item("hoge") '引数付きデフォルトプロパティ
と書くこともあります。
先のオブジェクト ブラウザーの定義と見比べてみてください。


しかし C# においては、引数付きプロパティが言語仕様としてサポートされておらず、
かわりにインデクサーで代用されるようになっています。そのため上記は、
 tmpShapes = oWordDoc.Shapes;
 tmpShape = tmpShapes["hoge"];
あるいは
 tmpShape = oWordDoc.Shapes["hoge"];
という角括弧の構文に置き換わることになる…というわけです。


蛇足ですが、お使いの C# バージョンが古い場合には、
 tmpShape = tmpShapes["hoge"];
が使えず、代わりに、隠しメンバーとなる getter メソッド経由で
 object item = "hoge";
 tmpShape = tmpShapes.get_Item(ref item);
と書かねばならないケースもあります。

とはいえ、そこまで古いバージョンの C# 環境を使うことは
今となってはそうそう無いでしょうね。
[ 親 96571 / □ Tree ] 返信 編集キー/

▲[ 96656 ] / 返信無し
■96660 / 8階層)  Re[8]: C#からWORD文書内のブックマークへ書き込み
□投稿者/ S.Kos (36回)-(2021/01/06(Wed) 16:15:49)
No96656 (魔界の仮面弁士 さん) に返信
> 2021/01/05(Tue) 17:01:36 編集(投稿者)
>
またまたお世話になります。ご教示の程、激感謝です。

このギョーカイ(笑)に対するあなたの博識には、只々感服するしかありません。
加えて、言語化と解説は、呆れかえる(失礼!)ほど適切! まさしく「弁士」ですねぇ・・!

今回いただいたご教示は、咀嚼にいくらか以上の時間がかかりそうです。

厚く御礼申し上げつつ、ここで閉じます。

みなさま、ありがとうございました。

解決済み
[ 親 96571 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -