9

OpenXML を使用して Word 文書に埋め込まれた CheckBox コントロールへのハンドルを取得するにはどうすればよいですか?

Paragraph.ControlPropertiesPart または Paragraph.Descendents() のいずれかが何かを達成すると思うかもしれませんが、すべてのケースで null 型が返されます。

実際の XML 構造を使用してドキュメント ツリーをたどることはできますが、これは面倒に思えます。

提案を歓迎します。

4

1 に答える 1

12

次のコードは、ドキュメントDecendants<CheckBox>()の本文のメソッドを使用して、Word ドキュメント内のすべてのチェックボックスを列挙する方法を示しています。

using (WordprocessingDocument doc = WordprocessingDocument.Open("c:\\temp\\checkbox.docx", true))
{
  foreach (CheckBox cb in doc.MainDocumentPart.Document.Body.Descendants<CheckBox>())
  {
    Console.Out.WriteLine(cb.LocalName);

    FormFieldName cbName = cb.Parent.ChildElements.First<FormFieldName>();
    Console.Out.WriteLine(cbName.Val);

    DefaultCheckBoxFormFieldState defaultState = cb.GetFirstChild<DefaultCheckBoxFormFieldState>();
    Checked state = cb.GetFirstChild<Checked>();

    Console.Out.WriteLine(defaultState.Val.ToString());

    if (state.Val == null) // In case checkbox is checked the val attribute is null
    {
      Console.Out.WriteLine("CHECKED");
    }
    else
    {
      Console.Out.WriteLine(state.Val.ToString());
    }
  }
}

特定のチェックボックス入力要素の名前を決定するに Parentは、インスタンスのプロパティにアクセスしCheckBoxて要素を検索する必要がありFormFieldNameます (チェックボックスに名前を割り当てるには、Microsoft Word の [プロパティ] ダイアログを使用します)。

このDefaultCheckBoxFormFieldState Valプロパティは、チェックボックスのデフォルト状態を保持します。さらに、要素のValプロパティはChecked、インスタンスの実際のチェック状態を保持しCheckBoxます。Microsoft Word 2007 のnull場合、Val プロパティはチェックボックスがオンの場合です。

編集開始

答えを広げたいと思います。実際、MS Word の開発者タブには、従来のチェックボックスと ActiveX コントロールのチェックボックスの 2 種類のチェックボックス コントロールがあります。上記のコードを使用して、Word 文書内のレガシー チェックボックスを列挙できます (レガシー チェックボックスの作成方法については、この記事を参照してください)。

私の知る限り、OpenXML SDK を使用して ActiveX チェックボックスの値を取得/設定することはできません。ただし、次のコードを使用して ActiveX コントロールを列挙できます。

foreach (Control ctrl in doc.MainDocumentPart.Document.Body.Descendants<Control>())
{
   Console.Out.WriteLine(ctrl.Id);
   Console.Out.WriteLine(ctrl.Name);
   Console.Out.WriteLine(ctrl.ShapeId);
}

指定された がチェックボックスかどうかを判断するにControlは、 のクラス ID を確認する必要がありますControl。チェックボックスのクラス ID は{8BD21D40-EC42-11CE-9E0D-00AA006002F3}. クラス ID を取得するコード サンプルを次に示します (もっと簡単な方法があるかどうかはわかりません...)。

OpenXmlPart part = doc.MainDocumentPart.GetPartById(ctrl.Id);
OpenXmlReader re = OpenXmlReader.Create(part.GetStream());
re.Read();
OpenXmlElement el = re.LoadCurrentElement();          
if(el.GetAttribute("classid", el.NamespaceUri).Value == "{8BD21D40-EC42-11CE-9E0D-00AA006002F3}")
{
  Console.WriteLine("Checkbox found...");
}
re.Close();

編集終了

編集2

Word 2010 に新しいチェックボックス コントロールがあることを知りませんでした (Dennis Palmer のおかげです)。

これらの新しいチェックボックス コントロールを列挙するには、次のコードを使用できます。

using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true))
{
   MainDocumentPart mp = doc.MainDocumentPart;

   foreach(SdtContentCheckBox cb in mp.Document.Body.Descendants<SdtContentCheckBox>())
   {         
     if(cb.Checked.Val == "1");
     {
       Console.Out.WriteLine("CHECKED");  
     }           
   }
}

編集終了 2

お役に立てれば。

于 2011-12-04T13:47:29.390 に答える