tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: VB6 MSHFlexGridについて
投稿日: 2011/01/27(Thu) 11:44
投稿者魔界の仮面弁士
> VB6 MSHFlexGridについてですが、階層を持たせるとデフォルトで展開した状態になると
> 思いますが、それをたたんだ状態にすることは可能でしょうか?
一括で折りたたむなら CollapseAll メソッド、展開するときは ExpandAll メソッド、
個別に制御する場合は、RowExpanded プロパティです。


> それと、DataEnvironmentを使えば楽に階層データをセットできますが、
使わなくてもセットできます。使った方が楽ですけれどね。


> Recordsetで階層を持たせるにはどのようにコードを記述したらよいのでしょうか?
階層化には SHAPE コマンドを利用します。
DataEnvironment で階層構造のレコードセットを作った場合は、
内部でこれらの SHAPE コマンドが自動的に生成されています。

MDAC SDK より:
http://msdn.microsoft.com/ja-jp/library/cc408253.aspx

MSKB より:
http://support.microsoft.com/kb/189657/en-us
http://support.microsoft.com/kb/185425/
http://support.microsoft.com/kb/308045/ja

DataEnvironment を使った場合には集計元のデータベースが必要ですが、
これは DataEnvironment 側の制限です。
http://support.microsoft.com/kb/193347/ja

SHAPE コマンドを直接作りこんだ場合、データベース無しで階層化することもできます。
とはいえ通常は、データベースと DataEnvironment を使った方が楽ですけれどね。


なお下記では DB 無しで実行できるよう、自前でレコードセットを構築しています。

Option Explicit
Private WithEvents mrs As ADODB.Recordset

Private Sub Form_Load()
    Set mrs = CreateDummy()
    MSHFlexGrid1.AllowUserResizing = flexResizeColumns
    MSHFlexGrid1.BandDisplay = flexBandDisplayHorizontal
    Set MSHFlexGrid1.DataSource = mrs

    '第1バンド("所属"シェイプ)は表示しない
    MSHFlexGrid1.BandExpandable(1) = False
    MSHFlexGrid1.ColWidth(-1, 1) = 0
    
    '"所属名"列の幅を 150 ピクセルにする
    MSHFlexGrid1.ColWidth(2, 0) = 150 * Screen.TwipsPerPixelX
    
    
    '第0バンド(最上位階層)をすべて折りたたむ
    MSHFlexGrid1.CollapseAll 0

    '4行目、2行目のデータを開く
    MSHFlexGrid1.Row = 4
    MSHFlexGrid1.RowExpanded = True
    
    MSHFlexGrid1.Row = 2
    MSHFlexGrid1.RowExpanded = True
    
    '「展開・折り畳み」が行われると、その分だけ
    'Col/Row/ColSel/RowSelの指定がずれる点に注意。
End Sub

'Offline で階層Recordsetを作成
Private Function CreateDummy() As ADODB.Recordset
    Dim cn As ADODB.Connection
    Set cn = New ADODB.Connection
    cn.Provider = "MSDataShape"
    cn.Properties("Data Provider").Value = "none"
    cn.Open
    
    Dim rs1 As ADODB.Recordset
    Dim rs2 As ADODB.Recordset
    Dim rs3 As ADODB.Recordset
    
    Set rs1 = New ADODB.Recordset
    rs1.Open GetSampleQuery(), cn, adOpenStatic, adLockBatchOptimistic
    rs1.AddNew
    Set rs2 = rs1.Collect("所属")
    rs2.AddNew
    Set rs3 = rs2.Collect("社員")
    rs2.CancelUpdate
    rs1.CancelUpdate
    
    rs1.AddNew Array("部署ID", "部署名"), Array(3000, "総務部")
    rs1.AddNew Array("部署ID", "部署名"), Array(3100, "総務部庶務課")
    rs1.AddNew Array("部署ID", "部署名"), Array(3101, "総務部庶務課庶務係")
    rs1.AddNew Array("部署ID", "部署名"), Array(3102, "総務部庶務課広報係")
    rs1.AddNew Array("部署ID", "部署名"), Array(3200, "総務部経理課")
    rs1.AddNew Array("部署ID", "部署名"), Array(3201, "総務部経理課予算係")
    rs1.AddNew Array("部署ID", "部署名"), Array(3202, "総務部経理課会計係")
    rs1.AddNew Array("部署ID", "部署名"), Array(3203, "総務部経理課財務係")

    rs2.AddNew Array("部署ID", "社員ID"), Array(3100, 1000)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3101, 1000)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3101, 1001)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3101, 1002)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3101, 1003)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3102, 1000)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3102, 1004)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3102, 1005)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3102, 1006)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3102, 1007)
    rs2.AddNew Array("部署ID", "社員ID"), Array(3200, 1010)

    rs3.AddNew Array("社員ID", "社員名"), Array(1000, "円谷課長")
    rs3.AddNew Array("社員ID", "社員名"), Array(1001, "朝井係長")
    rs3.AddNew Array("社員ID", "社員名"), Array(1002, "亀井")
    rs3.AddNew Array("社員ID", "社員名"), Array(1003, "東野")
    rs3.AddNew Array("社員ID", "社員名"), Array(1004, "長野係長")
    rs3.AddNew Array("社員ID", "社員名"), Array(1005, "仲澤")
    rs3.AddNew Array("社員ID", "社員名"), Array(1006, "大道")
    rs3.AddNew Array("社員ID", "社員名"), Array(1007, "寺内")
    rs3.AddNew Array("社員ID", "社員名"), Array(1010, "星野課長")
    
    rs1.MoveFirst
    Set CreateDummy = rs1
End Function

Private Function GetSampleQuery() As String
    Dim S As String
    S = ""
    S = S & vbCrLf & "SHAPE APPEND"
    S = S & vbCrLf & "  New adInteger AS 部署ID,"
    S = S & vbCrLf & "  New adChar(25) AS 部署名,"
    S = S & vbCrLf & "  ("
    S = S & vbCrLf & "    (SHAPE APPEND"
    S = S & vbCrLf & "      NEW adInteger AS 部署ID,"
    S = S & vbCrLf & "      NEW adInteger AS 社員ID,"
    S = S & vbCrLf & "      ("
    S = S & vbCrLf & "        (SHAPE APPEND"
    S = S & vbCrLf & "          NEW adInteger AS 社員ID,"
    S = S & vbCrLf & "          NEW adChar(20) AS 社員名"
    S = S & vbCrLf & "        ) AS 社員 RELATE 社員ID TO 社員ID"
    S = S & vbCrLf & "      )"
    S = S & vbCrLf & "    ) AS 所属 RELATE 部署ID TO 部署ID"
    S = S & vbCrLf & "  ),"
    S = S & vbCrLf & "  COUNT(所属.社員ID) AS 配属人数"
    GetSampleQuery = S
End Function


> ここで、FilterをかけるのとRecordsetのWHERE句を変えて接続しなおすのとどちらが確実なのでしょうか。
他のユーザーによって元データが変更される可能性がある場合は、
再度問い合わせた方が良いでしょう。切断している場合は再接続も必要です。
http://support.microsoft.com/kb/213856/ja

データの変更が無い場合は、Filter によるクライアント側の処理だけでも十分ですが
Filter をかけなおす場合は、経験則的に
 『Filter解除 → 最上位階層をMoveFirst → Filter再設定』
という手順を踏んだ方が安全なようです。

# 多くの場合はそのままセットするだけで反映されるのですが、何故か MoveFirst
# してからでないと反映されない状況を経験しています。原因は不明ですが。


> 以前DataGridを使用した際データの更新がうまくいかなかったので
> おそらくこのControlでも同じなのではないかと思うのですが。
そもそも MS(H)FlexGrid は更新機能を備えていません。表示専用のコントロールです。

プログラムからセルの内容を書き換えたとしても 階層 Recodset の内容は変更しませんし、
バインド後に階層 Recodset の内容を書き換えても MSHFlexGrid の表示は変化しません。

Recodset の内容が変化した場合は、DataSource を再度セットする必要があります。
(構造が変化する場合は、ClearStructure の呼び出しも必要です)


> お分かりになる方いらっしゃいましたらご教授のほど、よろしくお願いします
http://www.tt.rim.or.jp/~rudyard/torii009.html

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。