Microsoft Access 掲示板

縦スクロールバーをマウスでつかむときに表示される レコード:13/44 の値を取得したい / 16

19 コメント
views
4 フォロー
16
hiroton 2022/02/24 (木) 08:49:05 3cb46@f966d

下記コードにて検証してみました

Dim curHeight As Long
Dim curTop As Long
Dim oldHeight As Long
Dim oldCurTop As Long

curHeight = IIf(Me.Section(acHeader).Visible, Me.Section(acHeader).Height, 0)
curTop = 0
oldHeight = curHeight
oldCurTop = 0

Debug.Print curTop; curHeight

Me.AllowAdditions = True
DoCmd.GoToRecord , , acFirst
Do Until Me.NewRecord
    curHeight = Me.Section(acDetail).Height
    curTop = Me.CurrentSectionTop
    
    Debug.Print curTop; curHeight; curTop - oldCurTop; curTop - oldCurTop - oldHeight
    
    oldHeight = curHeight
    oldCurTop = curTop
    
    If Me.NewRecord Then Exit Do
    DoCmd.GoToRecord , , acNext
Loop

ヘッダー無し、詳細高さ1.575cmの場合

 0  0 
 0  893  0  0 
 900  893  900  7 
 1800  893  900  7 
 2700  893  900  7 
 3600  893  900  7 

ヘッダー高さ0.975cm、詳細高さ1.575cmの場合

 0  553 
 555  893  555  2 
 1455  893  900  7 
 2355  893  900  7 
 3255  893  900  7 
 4155  893  900  7 

ヘッダー高さ0.6cm、詳細高さ1.575cmの場合

 0  340 
 345  893  345  5 
 1245  893  900  7 
 2145  893  900  7 
 3045  893  900  7 
 3945  893  900  7 

ヘッダー高さ0.801cm、詳細高さ1.575cmの場合

 0  454 
 450  893  450 -4 
 1350  893  900  7 
 2250  893  900  7 
 3150  893  900  7 
 4050  893  900  7 

ヘッダー高さ0.6cm、詳細高さ2cmの場合

 0  340 
 345  1134  345  5 
 1485  1134  1140  6 
 2625  1134  1140  6 
 3765  1134  1140  6 
 4905  1134  1140  6 

ヘッダー高さ0.801cm、詳細高さ2cmの場合

 0  454 
 450  1134  450 -4 
 1590  1134  1140  6 
 2730  1134  1140  6 
 3870  1134  1140  6 
 5010  1134  1140  6 

ヘッダー高さ0.801cm、詳細高さ0.801cmの場合

 0  454 
 450  454  450 -4 
 900  454  450 -4 
 1350  454  450 -4 
 1800  454  450 -4 
 2250  454  450 -4 

うーん、これは予想しない(困った)結果に・・・

通報 ...
  • 17

    どうやらCurrentSectionTopはセクションの高さに応じて補正が入るようです。今回得られた補正量は高さに応じて

    セクション高さ実際の高さ補正量
    340345+5
    454450-4
    553555+2
    893900+7

    これは、一見ばらばらのようですが「15」単位で四捨五入されています
    ACCESSは各セクションの高さをTwipで保持していますが、画面の表示はPixel単位でなければなりません。windowsの標準dpiは96なので、Pixel単位(1Pixel=15Twip)で四捨五入されているわけですね

    >> 9のずれるパターンもこの計算を当てはめれば

    ツールチップの値:9/100
    実際に見える先頭レコードの番号:9
    curRecNum = Me.CurrentRecord      '値:17
    curTop = Me.CurrentSectionTop      '値: 3570
    Me.Section("フォームヘッダー").Height  '値:454
    Me.Section("詳細").Height        '値: 397
    
    (3570 - Int(454 / 15 + 0.5) * 15) / Int(397 / 15 + 0.5) * 15 = 8
    17 - 8 = 9
    

    正しく結果が得られます


    以上のことから

    Dim TPP As Long 'Twip/Pixel
    TPP = 15 'dpiによって変化する
    
    描画ヘッダ高さ = Int(ヘッダ高さ / TPP + 0.5) * TPP
    描画詳細高さ = Int(詳細高さ / TPP + 0.5) * TPP
    
    先頭レコード = (描画詳細高さ * 現在レコード - (curTop - 描画ヘッダ高さ)) / 描画詳細高さ
    

    のように、正しく補正を入れれば間違いのない答えが得られます

  • 18

    この方法の問題点

    dpiによって結果が変わる

    ほぼ決め打ちでも問題ないところですが、正確を期すならdpiの取得が必要です。そこまでするとACCESSの埒外になってしまいます・・・

    または、実際にレコードを移動させてCurrentSectionTopを取得し、差を吸収するような仕組み(表示上の詳細セクションの高さを求める仕組み)が必要でしょう

    >> 15の回避策は大雑把ながら見どころの有る方法だと思います

    96dpi(1Pixel=15Twip)の場合のずれは±7で20レコードあれば最大140Twipずれる可能性があるということになります。このとき、詳細セクションの高さが300Twip程度あれば140Twipずれても四捨五入で欲しいレコードの位置を求めることができます

    Macのdpiは72だそうです(古い情報ですが)。この場合同様に考えるとずれは最大±10で20レコードだと200Twipずれる可能性があり、高さが300Twipの場合、高さの半分以上の誤差がでるので四捨五入すると1レコード以上の差になってしまいます。しかしながら、この計算でも14レコードまでであれば正確なレコード数になります

    限定された範囲では確からしいことが保証できるので

    まるめ = Int(先頭レコード + 0.5) '表示が15レコードくらいまでなら大丈夫
    

    のような感じで対応してしまうのも無くはないかなと思います

    カレントレコードが変わる

    コード以前の問題ですが、CurrentSectionTopの仕様としてカレントレコードが表示エリア内に存在しないとちゃんとした数値が得られません。カレントレコードを変えたくない場合(編集中の場合・レコード移動時イベントを不用意に発生させたくない場合)や、またはカレントレコードを元に戻す手間などが問題になるかもしれません

    windows apiを使った手法はこの問題に悩むことがないのもいいですね