プロが教える店舗&オフィスのセキュリティ対策術

フォームに対してRequeryすると先頭のレコードへ移動してしまうので
Requeryする前のレコードの番号を取得して
Requery後にそのレコード番号へ移動したいのですが

Sub test()
i = Forms("Form").Controls("SubForm").Form.CurrentRecord
Forms("Form").Controls("SubForm").Requery
DoCmd.GoToRecord acActiveDataObject, Forms("Form").Controls("SubForm"), acGoTo, i
End Sub

これをすると、実行時エラー2498
指定した式は、いずれかの引数とデータ型が対応していません。
になりますが、
どこがおかしいのでしょうか?

A 回答 (2件)

【要旨】


サブフォームのレコード移動では、対象サブフォームは引数で指定するのではなく、
SetFocusメソッドで移動後、引数を省略したGotoRecordを使用します:
  Forms("Form").Controls("SubForm").SetFocus
  DoCmd.GotoRecord , , acGoto, i

但し、「Requery前後でのレコード移動の回避」が目的の場合は、Requeryの
対象を「親フォームまたはサブフォームのFormオブジェクト」ではなく「サブフォーム
コントロール」とすればOkです。
 <現状・例1>
  Forms("Form").SetFocus
  DoCmd.Requery
 <現状・例2>
  Forms("Form").Requery
 <現状・例3>
  Forms("Form").Controls("SubForm").Form.Requery
 <代替策>
  Forms("Form").Controls("SubForm").Requery
  ※「現状・例3」との違い(→途中の「.Form」の有無)に注意。


【詳細】
> 実行時エラー2498

このエラーの直接の原因は、GotoRecordメソッドの第2引数に指定している
「Forms("Form").Controls("Subform")」の部分です。

ここに指定するのはオブジェクト名になりますが、そのデータ型は文字列型です。
一方、「~.Controls(~)」の形で指定した場合、取得できるのは
 a)オブジェクトそのもの
 b)そのオブジェクトのデフォルトプロパティ
のどちらかです(→状況によって変化します)。
(例えばテキストボックスなら、TextBoxオブジェクトまたはValueプロパティの値)

サブフォームのデフォルトプロパティは調べていませんが(汗)、少なくとも文字列
型のプロパティではないため、「型が一致しない」とのエラーとなります。
サブフォームのコントロール名を取得する場合は、
  Forms("Form").Controls("SubForm").Name
というように、Nameプロパティを明示的に指定する必要があります。

ただ、「サブフォームのレコード移動」の場合、明示的に「Name」プロパティを
指定しても解決には至りません(汗)
これは、GotoRecordメソッドの第2引数には、直接開いているオブジェクトの
名前のみが有効なためで、サブフォームを直接的に指定することはできない、
ということです。
(注:Microsoftの資料を探したわけではなく、経験則から記述していますので、
 私の勘違いでしたらご容赦願います(汗))

サブフォームのレコード移動には、冒頭に記述したとおり、「フォーカスの移動」と
「一部の引数を省略したGotoRecord」を使用します:
  Forms("Form").Controls("SubForm").SetFocus
  DoCmd.GotoRecord , , acGoto, i

なお、これも冒頭に書きましたが、サブフォームのRequeryの仕方には幾つか
方法がありますが、Requeryの対象を「コントロールとしてのサブフォーム」にすれば、
レコード移動が発生しませんので、GotoRecord自体が不要になります。
http://www.f3.dion.ne.jp/~element/msaccess/AcTip …
    • good
    • 7
この回答へのお礼

ご回答ありがとうございました。

お礼日時:2013/02/22 21:49

フォーカスがあろうが無かろうが、やりたいことをやる・・・・



レコードを特定できるもの(以下では「an」のオートナンバ)があるとします。
現在の「an」が何かを覚えておいて Requery します。
結果の RecordsetClone に対して検索( FindFirst )します。
一致するものがあたら、その Bookmark をフォームへ設定します。

Public Sub test()
  Dim sS As String

  With Forms("Form").Controls("SubForm").Form
    .Painting = False
    sS = "an = " & .Recordset("an")
    .Requery
    .RecordsetClone.FindFirst sS
    If (Not .RecordsetClone.NoMatch) Then
      .Bookmark = .RecordsetClone.Bookmark
    End If
    .Painting = True
  End With
End Sub

※ 対象のフォームを変更する時には
  With Forms("Form").Controls("SubForm").Form
部分を変更するだけです。

※ 新規行だった場合は上記はエラーになるかも・・・
また、Requery によって、覚えていた「an」が表示対象外になった場合、先頭のままです。

なお、何行目・・・これが Requery 前後で変更なければ以下でできるかも

Public Sub test()
  Dim i As Long

  With Forms("Form").Controls("SubForm").Form
    .Painting = False
    i = .Recordset.AbsolutePosition
    .Requery
    .Recordset.AbsolutePosition = i
    .Painting = True
  End With
End Sub

※ 上記双方未検証(動かなかったらごめんなさい)
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

お礼日時:2013/02/22 21:49

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

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


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