2024/06/28

DXL Step-by-Step:#35)表の列幅の設定

前回ご紹介した通り、表の列幅は tablecolumn ノードの width 属性で設定します。今回はこの列幅を設定するプログラムを作成します。

tablecolumn ノードは table ノードの子ノードとして存在し、表の列数だけ存在しました。

これまで作成したプログラム(#32 を参照)に組み込むとすれば、表を作成する部分で設定すると簡単に実現できます。

例えば以下のサンプルでは、1 列目を固定幅(3cm)に設定しています。

Function xSetDXL_table(_
      ・・・

   '表の作成
   Set den = vddn.CreateElementNode("table")
   Set denTbl = vdenRT.AppendChild(den)

   '列定義の作成
   For iCol = 1 To viCols
      Set den = vddn.CreateElementNode("tablecolumn")
      If iCol = 1 Then
         Call den.SetAttribute("width", DXL_CMToInch(3))
      End If

      Call denTbl.AppendChild(den)
   Next

   '行の作成
      ・・・
End Function

このプログラムで 1 列目の tablecolumn ノードは次のようになります。

<tablecolumn width='1.1811in' />


tablecolumn ノードを取得するには

ただ、この方法だと、表を新規で作成(=列を新規で作成)するタイミングでしか設定できません。そこで、今回は、別途作成した表や既存の表に対して列幅を設定する方法を考えます。

必要となる機能は、

  1. table ノードの子ノードから tablecolumn ノードを探す
  2. 特定の列(n 番目)の tablecolumn ノードを取得する

となります。


NotesDOMElementNode クラスには GetElementsByTagName メソッドが定義されています。このメソッドを使えばノード名称で配下のノードを検索できます。ただ、この命令は子ノードだけでなく、孫ノードなど配下のすべてのサブノードが対象となります。そこで子ノードだけを対象にした関数 GetChildByName_Nth を自作します(lsDXL ライブラリに作成)。

引数は 3 つで、検索するノード(親ノード)、ノードの名称、何個目か となっています。発見できたらそのノード、見つからない場合は Nothing を返します。

Public Function GetChildByName_Nth(_
               vdenParent As NotesDOMElementNode, _
               ByVal vsNodeName As String, _
               ByVal viIndex As Integer) As NotesDOMElementNode
   Dim i As Integer
   Dim dn As NotesDOMNode

   Set GetChildByName_Nth = Nothing

   i = 0
   Set dn = vdenParent.FirstChild
   Do Until dn.Isnull
      If dn.NodeType = DOMNODETYPE_ELEMENT_NODE Then
         If dn.NodeName = vsNodeName Then
            i = i + 1
            If i = viIndex Then
               Set GetChildByName_Nth = dn
               Exit Function
            End If
         End If
      End If
      Set dn = dn.NextSibling
   Loop
End Function

仕組みは単純で FirstChild と NextSibling プロパティを使用して子ノードを順に取得してチェックしているだけです。万一、子ノードが textnode など NotesDOMElementNode でない場合に備え、汎用的な NotesDOMNode のオブジェクト変数を使用しています。


既存の列幅の設定

GetChildByName_Nth 関数の準備ができたら、これを使用して列幅を設定する関数を作成します。引数は 3 つで table ノード、列番号、列幅の設定となっています(エージェント内に作成)。

Function xSetDXL_colwidth(vdenTbl As NotesDOMElementNode, _
                                        ByVal viCol As Integer, ByVal vsWidth As String)
   Dim denCol As NotesDOMElementNode

   Set denCol = GetChildByName_Nth(vdenTbl, "tablecolumn", viCol)
   If Not(denCol Is Nothing) Then
      Call denCol.SetAttribute("width", vsWidth)
   End If
End Function

関数内では指定した列番号の tablecolumn ノードを取得。取得できたら列幅 width 属性をセットします。


メインルーチンを修正して、列幅を設定します。今回は、1 列目を 3cm で固定、2 列目を 70%、3 列目を 30% としています。

Function xSetDXL(vdprs As NotesDOMParser)
            ・・・
   '表の追加
   Set denTbl = xSetDXL_table(ddn, denRT, 3, 3)

   '間隔の設定
   Call xSetDXL_table_spcing(denTbl, 0.2, 0.5)

   '列幅の設定
   Call xSetDXL_colwidth(denTbl, 1, DXL_CMToInch(3))
   Call xSetDXL_colwidth(denTbl, 2, "70%")
   Call xSetDXL_colwidth(denTbl, 3, "30%")


   '表後の段落追加
   Call xSetDXL_par(ddn, denRT)
End Function

なお、今回のプログラムでは列の設定効果がわかりやすいよう作成する表を 3 列に変更しています。ご注意ください。


実行すると列の幅が設定された表が作成されます。実行結果と生成される DXL は以下の通りです。



前回 DXL Step-by-Step 次回


0 件のコメント:

コメントを投稿