条件によってテーブルに新たな行を挿入?更新?SQLが盛り込まれたVBAコードの条件式の中身を解読したい。

今、「水族館の売上」というテーブルがありまして。
以下のようなVBAコードが記載されています。

-----------
・・・
Dim sql_info as string
Dim aquarium as DAO.Recordset
Dim aNo as Long '番号
Dim sDate as string
・・・・
public const min_val as integer = 0

・・・

If aquarium.EOF Then 
 aNo = IIf(IsNull(DMax("番号","水族館の売上")),1,DMax("番号","水族館の売上") + 1)
  sql_info = ""
  sql_info = "insert into 水族館の売上 values(" & aNo 
  sql_info = sql_info & "," & Format(SearchDate(sDate),"YYYYMMDD")
  sql_info = sql_info & "," & min_val & "," & min_val
  sql_info = sql_info & "," & Val(Nz(Me.水族館Sub.Form.翌営業日.Value))
  sql_info = sql_info & "," & Format(Now,"YYYYMMDD")
  sql_info = sql_info & "," & Format(Now,"HHMMSS") & ")" 

回答の条件
  • 1人20回まで
  • 登録:
  • 終了:2020/05/07 10:10:41
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。
id:moon-fondu

Else

 aNo = aquarium.Fields(0).Value          

  sql_info = ""  

  sql_info = "update 水族館の売上 set"

  sql_info = sql_info & " 口座残高 = " & Val(Nz(Me.水族館Sub.Form.翌営業日txt.Value))

  sql_info = sql_info & ", 更新日 = " & Format(Now,"YYYYMMDD")   

  sql_info = sql_info & ", 更新時間 = " & Format(Now,"HHMMSS")

  sql_info = sql_info & " where 番号 = " & aNo

End If

Set aquarium = Nothing


※"SearcDate"は営業日を検索する関数、です。ソースコードの別の場所で色々書かれてます。

※"水族館Sub"はサブフォーム、"翌営業日txt"は、テキストボックスです(どちらもフォーム内にあるパーツです)。

-----------

解読しようと試みているのですが、疑問点が残っています。

①aquarium.EOFは、カレントレコードの位置が Recordset オブジェクトの最後のレコードより後ろにあるかかどうかを判定?

If文は、"水族館の売上"テーブルのレコードにデータが入っていない(範囲外)場合の処理かと思います。

ただその式に入るまでのaquarium.EOFですが、ここではrecordsetオブジェクトとして用いられているのか、recordsetプロパティとしてなのか…分かりかねる部分があります。

Recordsetとは|Recordsetでレコード数を取得するサンプル:Access VBA入門 

https://www.feedsoft.net/access/guide-vba/guide13.html  

によりますと、「.」(ドット) で繋げずにrecordsetを利用する場合もあるようで…しかし「Set recordset ~」で使う場合と、「~.recordset」で使う場合に「どう違うのかなぁ」と、こんがらがっております。

②次にElse文のほうですが、「aNo aquarium.Fields(0).Value」というのは、何をしているのでしょうか…。

③If文もElse文も、Format関数を使って前日の売上とかをテーブルに計上したり、計上した日付や時間もテーブルに記入しようとしている?と把握しております。

しかしIf文の方はInsert文を使って、Else文の方はなぜupdate文なのか…疑問が残ります。

質問が多くなってしまいましたが、上記①~③の理由につきまして、解説のお力添えをいただけますと幸いです。

よろしくお願い致します。

ベストアンサー

id:tobeoscontinue No.1

回答回数220ベストアンサー獲得回数59

ポイント1200pt

> ①aquarium.EOFは、カレントレコードの位置が Recordset オブジェクトの最後のレコードより後ろにあるかかどうかを判定?
概ね合っていると思います。
If aquarium.EOF Then
の前に"SELECT * FROM 水族館の売上 WHERE 番号="
のような照会があると思います。照会結果がaquariumに返された時に番号のレコードが無い場合には追加(insert)してレコードがあれば更新(update)します。
https://tonari-it.com/excel-vba-access-if-exists/

aquariumはrecordsetオブジェクトです。
EOFはaquariumのrecordsetプロパティです。

イメージとして 本棚.本.5p と(ドット)で繋げると毎回本棚から本を取り出し5pを開く感じです。
Set book = 本棚.本 では本棚から取り出した本を毎回使う感じです。参照が一回ならどちらでも同じでしょうがbookを何度も参照する場合その度に同じ本を取り出すのは無駄のように思います。(実際はキャッシュなどでさほど問題が無いのかもしれません)
しかし場合によっては最新である必要がある場合もあるので使い分ける必要があるでしょう。後は可読性の考慮でしょうか。

> ②次にElse文のほうですが、「aNo = aquarium.Fields(0).Value」というのは、何をしているのでしょうか…。
照会で取り出したaquariumのFields()の0番目には番号が入っていますのでそれを.Valueで取り出しaNoに代入しています。

> ③If文もElse文も、Format関数を使って前日の売上とかをテーブルに計上したり、計上した日付や時間もテーブルに記入しようとしている?と把握しております。
Format関数は日付や時間を文字列にするものです。売上に関するものは口座残高ですがMe.水族館Sub.Form.翌営業日txtと名称が合っていないように思います。

> しかしIf文の方はInsert文を使って、Else文の方はなぜupdate文なのか…疑問が残ります。
If文が真の場合は水族館の売上デーブルの中にaNo番号のレコードが無いのでinsertになります。
Else文ではaNo番号のレコードがあるのでupdateになります。

他3件のコメントを見る
id:tobeoscontinue

https://excelwork.info/excel/adofieldobject/
でFieldsのindexは0から始まるとありました。
ではCollectionは1から始まるので違うものなのかとググると
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/the-fields-collection
で"ADO コレクションでは使用できない、 CancelUpdate 、 Delete 、 Resync 、および Update の各メソッドも使用できます。"
とありCollectionと似たものだけど異なるものだったんですねぇ。これで0から始まる理由が納得できました。

2020/05/20 12:08:24
id:moon-fondu

FieldsコレクションはCollectionオブジェクト https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/collection-object と、厳密には異なる…ということですか?
自分はまだ実感できていないですが…(^^;

リンクありがとうございます。紹介いただいたこちら https://excelwork.info/excel/adofieldobject/ 、Fieldsオブジェクトの解説がありますが。
「.Type」のTypeプロパティは使われているようですが。
その他の箇所で、わからない部分が多いです…このページにつきましては再度、質問させていただこうと思いますので。
その際はまた、よろしくお願い致しますm(__)m

2020/05/28 13:57:47

その他の回答0件)

id:tobeoscontinue No.1

回答回数220ベストアンサー獲得回数59ここでベストアンサー

ポイント1200pt

> ①aquarium.EOFは、カレントレコードの位置が Recordset オブジェクトの最後のレコードより後ろにあるかかどうかを判定?
概ね合っていると思います。
If aquarium.EOF Then
の前に"SELECT * FROM 水族館の売上 WHERE 番号="
のような照会があると思います。照会結果がaquariumに返された時に番号のレコードが無い場合には追加(insert)してレコードがあれば更新(update)します。
https://tonari-it.com/excel-vba-access-if-exists/

aquariumはrecordsetオブジェクトです。
EOFはaquariumのrecordsetプロパティです。

イメージとして 本棚.本.5p と(ドット)で繋げると毎回本棚から本を取り出し5pを開く感じです。
Set book = 本棚.本 では本棚から取り出した本を毎回使う感じです。参照が一回ならどちらでも同じでしょうがbookを何度も参照する場合その度に同じ本を取り出すのは無駄のように思います。(実際はキャッシュなどでさほど問題が無いのかもしれません)
しかし場合によっては最新である必要がある場合もあるので使い分ける必要があるでしょう。後は可読性の考慮でしょうか。

> ②次にElse文のほうですが、「aNo = aquarium.Fields(0).Value」というのは、何をしているのでしょうか…。
照会で取り出したaquariumのFields()の0番目には番号が入っていますのでそれを.Valueで取り出しaNoに代入しています。

> ③If文もElse文も、Format関数を使って前日の売上とかをテーブルに計上したり、計上した日付や時間もテーブルに記入しようとしている?と把握しております。
Format関数は日付や時間を文字列にするものです。売上に関するものは口座残高ですがMe.水族館Sub.Form.翌営業日txtと名称が合っていないように思います。

> しかしIf文の方はInsert文を使って、Else文の方はなぜupdate文なのか…疑問が残ります。
If文が真の場合は水族館の売上デーブルの中にaNo番号のレコードが無いのでinsertになります。
Else文ではaNo番号のレコードがあるのでupdateになります。

他3件のコメントを見る
id:tobeoscontinue

https://excelwork.info/excel/adofieldobject/
でFieldsのindexは0から始まるとありました。
ではCollectionは1から始まるので違うものなのかとググると
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/the-fields-collection
で"ADO コレクションでは使用できない、 CancelUpdate 、 Delete 、 Resync 、および Update の各メソッドも使用できます。"
とありCollectionと似たものだけど異なるものだったんですねぇ。これで0から始まる理由が納得できました。

2020/05/20 12:08:24
id:moon-fondu

FieldsコレクションはCollectionオブジェクト https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/collection-object と、厳密には異なる…ということですか?
自分はまだ実感できていないですが…(^^;

リンクありがとうございます。紹介いただいたこちら https://excelwork.info/excel/adofieldobject/ 、Fieldsオブジェクトの解説がありますが。
「.Type」のTypeプロパティは使われているようですが。
その他の箇所で、わからない部分が多いです…このページにつきましては再度、質問させていただこうと思いますので。
その際はまた、よろしくお願い致しますm(__)m

2020/05/28 13:57:47

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません