いつも参考にさせて頂いております。
私、松岡と申します。
現在、ラベルで表を作成していますが
スクロールバーの使い方がいまいち分かりません。
そこで、皆様のお知恵を拝借できればと思った次第であります。
私が行っているのは
とあるフレーム上で
以下のような表を
コントロール配列にしたラベルで作成することです。(VB5.0)
|社員番号 |社員氏名 |担当地区 |
|00001 |松岡 |関東 |
|00002 |山田 |北海道 |
|社員番号 |社員氏名 |担当地区 |
|label1(0)|label2(0)|label3(0)|
|label1(1)|label2(1)|label3(1)|
表までは作成できたものの
社員数が多くなると
下部の表示が出来なくなります。
そこでスクロールバーを使って
下部の表示を行いたいのですが
ラベルとスクロールバーの関連付けができません。
(そもそも、関連付けられるかどうかも分かっていません)
どなたか、御存知の方がいらっしゃいましたら
教えて頂けると幸いです。
以上、よろしくお願い致します。
> 現在、ラベルで表を作成していますが
コントロール数が増えてくると、処理が重くなりますよ。
表形式に表示させたいなら、MSHFlexGrid等のコントロールを使った方が楽かと。
> ラベルとスクロールバーの関連付けができません。
スクロールバーのChageイベント、およびScrollイベントに、
各ラベルの内容を書きかえるようなコードを書いてください。
えっと、かなり力技ですが。
まず、ラベル配列貼り付け用フレーム(Frame1)を用意します。
このフレームはRow移動用です。
>|label1(0)|label2(0)|label3(0)|
>|label1(1)|label2(1)|label3(1)|
などを貼り付けてください。
ヘッダとしているラベルまで貼るとスクロール時に消えるので注意。
さて動的にラベル数は増減するのでしょうから、
ラベルのHeightは予め測っておきましょう。
Row数×ラベルのHeight = Frame1.Height としましょう。
(実際はぴったりではないです。60程度一定の差があるようです)
次に、表示域用フレーム(Frame2)を用意します。
お好きなRow数表示できるように調節してください。
次に表示域用フレームと同じ高さにスクロールバー(VScroll1)を用意します。
特に関連性はないです。
最後に先ほどラベル配列を貼り付けたフレームを切取り、表示用フレームに貼り付けます。
もちろん表示用フレームの表示域の方が狭いでしょうから全ては表示しないことでしょう。
位置を合わせるために、ラベル配列貼り付け用フレームのTop=0としましょう。
準備はこれで終了です。
以下は、ラベル配列貼り付け用フレームのHeight = 1695
表示域用フレームのHeight = 1215とした場合の設定方法です。
Private Sub Form_Load()
VScroll1.Max = 1695 - 1215
End Sub
Private Sub VScroll1_Change()
Frame1.Top = - VScroll1.Value
End Sub
これでOKです。あとはお好みで、
VScroll1.LargeChange
VScroll1.SmallChange
など設定すればきれいに動くでしょう。
魔界の仮面弁士さん、ファリンファリンさん
ありがとうございます。
お二人のご意見を参考に、試行錯誤していたら
レスが遅くなってしまいました。
申し訳ありません。
ファリンファリンさんが教えて下さった方法は
私には高度すぎて・・・出来ませんでした。
また、各種サイズを直接指定するとなると
のちにフレームサイズの変更などあったら悲しいと思いまして・・・
申し訳ありません。
魔界の仮面弁士さんへ
> コントロール数が増えてくると、処理が重くなりますよ。
> 表形式に表示させたいなら、MSHFlexGrid等のコントロールを使った方が楽かと。
私のPCだけかもしれないのですが
MSHFlexGridの表示って遅くないですか?
一つ一つの項目が表示され行く様が
どーにも気になりまして・・・
それで、なんとかラベルで頑張ろうと思っていました。
が、最終的には利便性等を考えて
MSHFlexGridでやろうかと思います。
表示するスピードは諦めるとして
処理してる間は画面から隠しておきたいんです。
(別の画像を表示したいのが本音ですが)
と言うわけで、MSHFlexGrid.Visibleをfalseにして
値を入れているのですが
画面に表示されたままなんですよね・・・。
値を入れちゃうと
Visible=falseは効果なくなっちゃうんですか?
重ね重ね申し訳ありませんが
以上、よろしくお願い致します。
MSHFlexGridでやることに決めたんですね。
多分、それが一番普通です。
>と言うわけで、MSHFlexGrid.Visibleをfalseにして
>値を入れているのですが
>画面に表示されたままなんですよね・・・。
>値を入れちゃうと
>Visible=falseは効果なくなっちゃうんですか?
えっと、MSHFlexGridに値を入れるためにぐりぐり処理を回してるのかと
思いますが、ぐりぐり回すと再描画が間に合わないんです。
これは何でも言えます。なので、Visible=falseの後かつ、ぐりぐり処理の前に
Me.Refresh (Form.Refresh)
というのを入れてみたらどうでしょうか?
再描画をしますので、多分消えます。
#Formだと本当はやりすぎ(重い)なんです。普通は最小範囲を再描画かけます。
>Me.Refresh (Form.Refresh)
って書きましたけど、()は引数ではありません。
Me.Refresh 又は、Form.Refresh と言う意味で書いたんです。
勘違いするような書き方ですみませんでした。修正します。
ファリンファリンさん
ご説明ありがとうございます!
再描画が間に合わないせいで
消えてくれないんですね・・・納得です。
試しにやってみたものの
全て処理の後にRefreshを書くことになっちゃいました・・・。
さすがにそれもどうかと思うので
表示の遅さは我慢することにします!
本当に、ありがとうございました。
う〜ん。表示、そんなに遅いですか?
こちらで試してみたところ、セル数が2万あった場合でも、
0.3秒程度で出力されましたけれども…。
Option Explicit
Private Sub Form_Load()
'20列1000行の表を作成
With Me.MSHFlexGrid1
.Cols = 21
.Rows = 1000
.FixedCols = 1
.FixedRows = 0
End With
End Sub
Private Sub Command1_Click()
Dim T As Single
Dim Row As Long
Dim Col As Long
Dim Data As Object
Dim LineData(20) As String
Me.MSHFlexGrid1.Clear
T = Timer '計測開始
'表示用のダミーデータ作成
Set Data = CreateObject("Scripting.Dictionary")
For Row = 1 To 1000
LineData(0) = CStr(Row) & "行目"
For Col = 1 To 20
LineData(Col) = CStr(Row) & "-" & CStr(Col)
Next
Data(Row) = Join(LineData, vbTab)
Next
'MSHFlexGridへの出力
With Me.MSHFlexGrid1
.Redraw = False
.Row = 0
.Col = 0
.RowSel = 999
.ColSel = 20
.Clip = Join(Data.Items(), vbCr)
.Row = 0
.Col = 1
.Redraw = True
End With
Set Data = Nothing
'計測完了
Debug.Print FormatNumber(Timer - T); "秒"
End Sub
ツイート | ![]() |