アプリ版:「スタンプのみでお礼する」機能のリリースについて

フォームにデータ一覧を決まった数ずつ表示させ、『次の10件』『前の10件』ボタンで、表示を切り替えたいのですが、構文をどう繋げてよいか理解できません。
今やっている事は、データにOutoNoを振り、まずフォームオープン時、SQL文ではじめの10件を抽出しています。その時、表示中データのOutoNoが一番小さいものにフラグを立てて変数にし、それを元に次の(又は『前の』)10件を抽出、と考えているのでが、、。
NEXT~FOR文を使うのかなと思うのですが、それをどう絡ませていけばよいのか分かりません。
データの最後が10で割った数にならないので、それもどうやって処理するか。
どうかご教授願います。

A 回答 (5件)

ソース見ました。



・毎回[Q_有給]を作りなおす
という構造ですね?

・Q_有給は固定
・Q_有給からデータを10件ずつ抽出する
という流れにした方が、良いと思います。


以下のSQL文で、クエリを作成してください。
※注意!!≪全角スペースを利用しておりますので、半角に置換してください≫

クエリ[Q_有給]
------------------------------------------------------------
SELECT
   M_社員.ナンバー
   ,T_日数.コード
   ,M_社員.氏名
   ,M_社員.入社日
   ,T_日数.有給付与日
   ,T_日数.有給日数
FROM
   M_社員
   INNER JOIN
   T_日数
   ON M_社員.コード = T_日数.コード
WHERE
   IIF((M_社員.退社日) > Date(),Null,(M_社員.退社日)) IS NULL
------------------------------------------------------------


[M_社員].[ナンバー]
がオートナンバーフィールドですよね。

オートナンバーのフィールドが
・1-10
・11-20
・21-30
と、連続しているとは限りません。
[M_社員].[退社日]の状態により、不連続なデータになります。
入力キャンセルを行った場合だけでも、不連続データが発生します。


回避するためには、表示エリアデータの起点を見つけ、その前方/後方の表示対象データのキーを取得する必要があります。


フォームの中に、以下のソースを埋め込んでください。

VBAソース
------------------------------------------------------------
Option Compare Database
Option Explicit

'定数
Private Const DEF_SQL_MAIN As String = "SELECT * FROM Q_有給" & vbCrLf   'メインのSQL文
Private Const DEF_AUTO_NO  As String = "[ナンバー]"            'クエリのメインキー
Private Const DEF_SQL_ORDER As String = "ORDER BY " & DEF_AUTO_NO & vbCrLf 'SQLのOrderBy句
Private Const DEF_MOVE_VECT As Integer = 10                 '表示量

'列挙:移動種別
Private Enum ENM_MOVE
  MV_開始
  MV_戻る
  MV_進む
End Enum

'構造体:表示領域
Private Type typ表示領域
  lng開始 As Long
  lng終了 As Long
End Type

'表示領域記憶変数
Private m表示状態 As typ表示領域

  
'イベント/ボタン/進む
Private Sub cmd進む_Click()
  Call Sub画面リフレッシュ(MV_進む)
End Sub

'イベント/ボタン/戻る
Private Sub cmd戻る_Click()
  Call Sub画面リフレッシュ(MV_戻る)
End Sub

'イベント/フォーム/開く時
Private Sub Form_Open(Cancel As Integer)
  Call Sub画面リフレッシュ(MV_開始)
End Sub

'画面のレコードソースとボタン状態の切替を行う
Private Sub Sub画面リフレッシュ( _
         ByVal p_移動方向 As ENM_MOVE _
        , Optional ByVal p_lng移動量 As Integer = DEF_MOVE_VECT _
        )
        
  'データ操作用
  Dim strSQL As String
  Dim daoDB  As DAO.Database
  Dim daoRec As DAO.Recordset
  
  'オートナンバー対策
  Dim lng基準     As Long
  Dim lng開始番号   As Long
  Dim lng終了番号   As Long
  
  'ボタン制御用フラグ
  Dim bln戻る     As Boolean
  Dim bln進む     As Boolean
  
  '基本的にボタンは使用不可とする
  bln戻る = False
  bln進む = False
  
  '基準点を得る
  Select Case p_移動方向
  Case MV_開始
    lng基準 = 0
  Case MV_戻る
    lng基準 = m表示状態.lng開始
  Case MV_進む
    lng基準 = m表示状態.lng終了
  End Select
  
  '基準点をベースにSQLを発行
  strSQL = ""
  strSQL = strSQL & DEF_SQL_MAIN
  strSQL = strSQL & "WHERE " & DEF_AUTO_NO & IIf((p_移動方向 = MV_戻る), "<=", ">=") & lng基準 & vbCrLf
  strSQL = strSQL & DEF_SQL_ORDER
  Set daoRec = CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)

  '取得できない
  If daoRec.EOF Then
    lng開始番号 = 0
    lng終了番号 = 0
    
    '終了処理へ
    GoTo PGMEND
  End If


  '取得できた
  Select Case p_移動方向
  Case MV_開始, MV_進む
    '先頭
    daoRec.MoveFirst
  
    If (p_移動方向 = MV_開始) Then
      '開始ポイントの記憶
      lng開始番号 = daoRec(DEF_AUTO_NO)
    Else
      '戻るボタン使用可能
      bln戻る = True
      
      '一個移動
      daoRec.MoveNext

      '移動し過ぎの回避
      If daoRec.EOF Then
        daoRec.MovePrevious
      End If

      '開始ポイントの記憶
      lng開始番号 = daoRec(DEF_AUTO_NO)
    End If

    '移動:表示エリア + 1
    daoRec.Move p_lng移動量
    'データの存在チェックを行い、進むボタンの使用可能状態を決める
    bln進む = Not daoRec.EOF

    '移動:表示エリアの最後
    daoRec.MovePrevious

    '終了ポイントの記憶
    lng終了番号 = daoRec(DEF_AUTO_NO)
  Case MV_戻る
    '最後
    daoRec.MoveLast
  
    '進むボタン使用可能
    bln進む = True
  
    '一個移動
    daoRec.MovePrevious

    '移動し過ぎの回避
    If daoRec.BOF Then
      daoRec.MoveNext
    End If

    '終了ポイントの記憶
    lng終了番号 = daoRec(DEF_AUTO_NO)

    '移動:表示エリア - 1
    daoRec.Move -p_lng移動量
    'データの存在チェックを行い、戻るボタンの使用可能状態を決める
    bln戻る = Not daoRec.BOF

    '移動:表示エリアの先頭
    daoRec.MoveNext

    '開始ポイントの記憶
    lng開始番号 = daoRec(DEF_AUTO_NO)
  End Select
  
'終了処理
PGMEND:
  'データセット開放
  daoRec.Close
  Set daoRec = Nothing
  
  '表示領域エリアを記憶
  m表示状態.lng開始 = lng開始番号
  m表示状態.lng終了 = lng終了番号

  '画面の入力フィールドにフォーカスを当てる
  Me.コード.SetFocus
  'ボタン状態の制御
  Me.cmd戻る.Enabled = bln戻る
  Me.cmd進む.Enabled = bln進む

  'SQLを作成
  strSQL = ""
  strSQL = strSQL & DEF_SQL_MAIN
  strSQL = strSQL & "WHERE " & DEF_AUTO_NO & " BETWEEN " & lng開始番号 & " AND " & lng終了番号 & vbCrLf
  strSQL = strSQL & DEF_SQL_ORDER

  'SQLを設定
  Me.RecordSource = strSQL
End Sub
    • good
    • 0
この回答へのお礼

できました!

別の回答で教えて頂いたように、コードを見るって勉強になりますね。
とても丁寧な解説に感謝しています。
ありがとうございました。

お礼日時:2005/09/22 21:09

指定件数単位に抽出するクエリを作成し、それを基に一覧形式のフォームを作成


出来上がったフォームをメインフォームへサブフォームとして埋め込み画面
は完了
後は、『次の10件』『前の10件』のイベントでSQL文を編集しサブフォームの基となっているクエリを変更し、画面をリフレッシュすればOK
※データ表示を一覧形式のフォームを利用すると仮定した場合

Event:NextBotton
Dim l_OutoNo = l_OutoNo + 10
SSQL = "SELECT * FROM データテーブル WHERE Between OutoNo & CStr(l_OutoNo) & " And " & CStr(l_OutoNo + 9)
SubForm_Query.SQL = SSQL
Me.MainForm.SubForm.Form.F_Sub.Refresh
    • good
    • 0
この回答へのお礼

回答を有難うございます。
なるほど、next forにこだわりすぎていました。勉強になります。

お礼日時:2005/09/20 22:46

SQL文の発行は、DAO?ADO?



DAOなら
「Set レコードセット=CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)」
として、EOF/BOFのチェック
さらに
「レコードセット.Move 移動量」
で指定のレコード位置にカーソルを移動できます。
存在するレコード以下、あるいは以上の位置にカーソルを移動しようとすると、EOF/BOFになります。


>SQL文ではじめの10件を抽出しています
現在どのような処理が行われているのか、コードが見たいです。
それにより、極力改造を必要としない方法が見つかるかもしれません。
    • good
    • 0
この回答へのお礼

大変失礼しました。
まずフォームオープン時、

Dim qdf As QueryDef
Dim strsql As String

strsql = ""
strsql = strsql & "SELECT T_日数.コード, M_社員.氏名, M_社員.入社日, T_日数.有給付与日, T_日数.有給日数, "
strsql = strsql & "FROM M_社員 INNER JOIN T_日数 ON M_社員.コード = T_日数.コード "
strsql = strsql & "WHERE (((M_社員.退社日)>Date() Or (M_社員.退社日) Is Null and (M_社員.ナンバー)<=10 ));"

Set qdf = CurrentDb.QueryDefs("Q_有給")

qdf.SQL = strsql
qdf.Close
Me.RecordSource = "Q_有給"

です。
そして各『前ページ』『次ページ』を各コードに書かず、モジュール側で10を変数にして扱うのはどうしたら、、、と困っていたのです。

DAOも他で使っている箇所があるんですが、色々参考書を読んでみてるんですけど、いまいち明確な使い方(データを見せるだけの処理であるとか、架空のものとか)がただの抽出とどう違うのかが難しくて。
私事ですが.netも覚える事になっていて、その辺りもまた詳しく質問をさせてもらおうと思っています。ありがとうございました。

お礼日時:2005/09/20 23:28

#1ですが、ざっと書いてみました。



データは配列に格納できているものとします。
「フォームに表示」の形態がわからないので、仮にテキストボックスとしました。

Private DataNum as Long   '全部のデータ数
Private DataBuff()  as String 'データを格納した配列
Private cnt As Long

'「進む」ボタンクリック
Private Sub cmdnext_Click()
Dim i As Integer
txtData.Text = ""
For i = 0 To 9
If 10 * cnt + i > DataNum Then Exit Sub
txtData.Text = txtData.Text & vbCrLf & DataBuff(10 * cnt + i)
Next
cnt = cnt + 1
End Sub

'「戻る」ボタンクリック
Private Sub cmdpre_Click()
Dim i As Integer
txtData.Text = ""
cnt = cnt - 1
If cnt < 0 Then cnt = 0
For i = 0 To 9
txtData.Text = txtData.Text & vbCrLf & DataBuff(10 * cnt + i)
Next
End Sub
    • good
    • 0
この回答へのお礼

丁寧なご回答をありがとうございます。
色んな方法を知ることができて勉強になりました。
今後も役に立ちそうです。
感謝します!!

お礼日時:2005/09/21 01:14

こんにちは。


いちいち毎回10件ずつのSQLを発行するのではなく、最初に全部取得して配列に格納してしまい、
それを表示した方が楽だと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A