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
うーん、これは予想しない(困った)結果に・・・
通報 ...
どうやら
CurrentSectionTop
はセクションの高さに応じて補正が入るようです。今回得られた補正量は高さに応じてこれは、一見ばらばらのようですが「15」単位で四捨五入されています
ACCESSは各セクションの高さをTwipで保持していますが、画面の表示はPixel単位でなければなりません。windowsの標準dpiは96なので、Pixel単位(
1Pixel=15Twip
)で四捨五入されているわけですね>> 9のずれるパターンもこの計算を当てはめれば
正しく結果が得られます
以上のことから
のように、正しく補正を入れれば間違いのない答えが得られます
この方法の問題点
dpiによって結果が変わる
ほぼ決め打ちでも問題ないところですが、正確を期すならdpiの取得が必要です。そこまでするとACCESSの埒外になってしまいます・・・
または、実際にレコードを移動させてCurrentSectionTopを取得し、差を吸収するような仕組み(表示上の詳細セクションの高さを求める仕組み)が必要でしょう
>> 15の回避策は大雑把ながら見どころの有る方法だと思います
96dpi(1Pixel=15Twip)の場合のずれは±7で20レコードあれば最大140Twipずれる可能性があるということになります。このとき、詳細セクションの高さが300Twip程度あれば140Twipずれても四捨五入で欲しいレコードの位置を求めることができます
Macのdpiは72だそうです(古い情報ですが)。この場合同様に考えるとずれは最大±10で20レコードだと200Twipずれる可能性があり、高さが300Twipの場合、高さの半分以上の誤差がでるので四捨五入すると1レコード以上の差になってしまいます。しかしながら、この計算でも14レコードまでであれば正確なレコード数になります
限定された範囲では確からしいことが保証できるので
のような感じで対応してしまうのも無くはないかなと思います
カレントレコードが変わる
コード以前の問題ですが、CurrentSectionTopの仕様としてカレントレコードが表示エリア内に存在しないとちゃんとした数値が得られません。カレントレコードを変えたくない場合(編集中の場合・レコード移動時イベントを不用意に発生させたくない場合)や、またはカレントレコードを元に戻す手間などが問題になるかもしれません
windows apiを使った手法はこの問題に悩むことがないのもいいですね