特に配列も作られていない?空の引数を持つ変数が、UBound・Lbound関数で値を取得できるのかという疑問と、VBAで文末が","で終わる文が問題ないかにつきまして


今、以下のようなACCESS VBAコードがあります。
https://gist.github.com/AuroraNorthernQuarter/3061e780edb2382b12c6f5f5498a763f
テーブルは「資金情報」「売上情報」という2つのテーブルがありまして、大まかにテーブルからデータを引っ張って何かしたいのかな?ということぐらいしか判らず…悩んでおります。

疑問は4つほどあります。

(1)「for cntn = lbound(sum_m) to ubound(sum_m)」という箇所につきまして。lbound関数とubound関数、for文のループで、配列の値を取得しているのだと思いますが。
肝心の配列はどこにあるのかと思いまして。
「sum_m」という変数を追うと、今回のVBAが登場する「setkasusql」関数とは別の関数とか箇所で、宣言されたりredim関数を適用されたり値を代入されているようですが。

回答の条件
  • 1人20回まで
  • 登録:
  • 終了:2020/07/28 15:33:15
id:moon-fondu

そもそもsum_mは配列なのかという疑問もありまして。

配列でしたらArray関数を用いて「sum_m = array("A","B"."C")」のように、どこかで要素を定義している箇所があると思うのですが、探しても見当たらないのです。

また「sum_m」にlbound、ubound関数を適用した後に。

次の行「i_tSql = i_tSql & sum_m(cntn) & ","」と、新たにcntnという引数が設定されて、関数のように使われている?…こういった書き方は、vbaであり得るのでしょうか。

何を行っているのか、sum_m(cntn)は何を求めようとしているのか、全体的によくわからない状況です…。

(2)tSqlに格納されていくSQL文は、「資金情報」テーブルや「売上情報」テーブルからデータを取得するために、必要かと思うのですが。

そのSQL文の終わりに「set aquarium = dbinfo.openrecordset(tSql,dbopendynaset)」という箇所が2箇所ほど、あるかと思います。

これらは「select文で抽出したレコードを、openrecordsetメソッドで新たなレコードの集合体(レコードセット)として作成している」という認識で正しいでしょうか?

ただ、引数が「(tSql,dbopendynaset)」となっている部分が疑問です。

http://www7b.biglobe.ne.jp/~cbcnet/DAO/database.html

によりますと、dbopendynasetの方は、optionの引数なのでわかります。

しかしtSqlの方は、「引数 type には次の定数から 1 つを使用します。」というルールとは異なる変数だと思うのですが…。

(3)VBAのコード内にやたらと「i_tSql = i_tSql & minimumdate & ","」のように、文末が","で終わっている文が多いですが。

これはVBAの文法として?正しいのか疑問でして…文末を","にしている理由について、自分はコードを読んでも判らないのですが、何をしているのでしょうか。

「i_tSql = i_tSql & "'" & trim(aquarium.fields(0).value) & "',"」のように、アポストロフィで囲んで、カンマで終わらせている部分も、目的がよくわからない状況です。

「資金情報」「売上情報」という2つのテーブルの情報が不十分で、たくさんの疑問で恐れ入りますが、ご助言いただけますと助かります。

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

ベストアンサー

id:gizmo5 No.1

回答回数504ベストアンサー獲得回数141

ポイント1000pt

(1) は Redim で配列のサイズを指定していますね。この変数は配列です。

(2) は、dbopendynaset にどんな値が設定されているかが分かりませんが、その書き方で合っています。
どこぞの誰かが書いたページよりも、公式のドキュメントを参照しましょう。
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/database-openrecordset-method-dao

(3) は、提示のソースだと全貌がよく分かりませんが、何かの情報をカンマ区切りで結合したものを取得したいのだと思われます。
カンマ区切りという意味では末尾に余計なカンマが付きそうに思いますが。

id:moon-fondu

gizmo5さんありがとうございます、redim文、意識していなかったです。
調べましたら、redim文を使って何回でも大きさを変えられるみたいですね。
宣言する時に使うdim文はよく見ますが。
「宣言にはdim文を、初期化にはredim文を使う」と本にありました。

2020/07/23 05:38:23

その他の回答0件)

id:gizmo5 No.1

回答回数504ベストアンサー獲得回数141ここでベストアンサー

ポイント1000pt

(1) は Redim で配列のサイズを指定していますね。この変数は配列です。

(2) は、dbopendynaset にどんな値が設定されているかが分かりませんが、その書き方で合っています。
どこぞの誰かが書いたページよりも、公式のドキュメントを参照しましょう。
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/database-openrecordset-method-dao

(3) は、提示のソースだと全貌がよく分かりませんが、何かの情報をカンマ区切りで結合したものを取得したいのだと思われます。
カンマ区切りという意味では末尾に余計なカンマが付きそうに思いますが。

id:moon-fondu

gizmo5さんありがとうございます、redim文、意識していなかったです。
調べましたら、redim文を使って何回でも大きさを変えられるみたいですね。
宣言する時に使うdim文はよく見ますが。
「宣言にはdim文を、初期化にはredim文を使う」と本にありました。

2020/07/23 05:38:23
  • id:tobeoscontinue
    VBAはもう何年も書いていないのでコメントにて

    (1)sum_mは動的配列で
    redim sum_m(2)
    で宣言されています。「setkasusql」関数からはモジュールレベル変数扱いになっていると思います。
    動的配列では添え字の範囲を指定可能なのでlbound(sum_m)とubound(sum_m)を使っていますが
    この場合はfor cntn = 0 to 2と等価です。
    sum_m(cntn)は動的配列sum_mのcntn番目の要素ということで通常の配列と同等です。

    (2)認識が正しいかわかりませんがhttp://www7b.biglobe.ne.jp/~cbcnet/DAO/database.htmlにある
      Set recordset = database.OpenRecordset (type, options)
    は間違っていると思います。
    https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/database-openrecordset-method-daoでは
    式.OpenRecordset (Name、Type、Options、LockEdit)
    となっています。tSqlはNameでありdbopendynasetはTypeです。

    (3)SQL文ではカンマ区切りで記述するのでただ単にtSqlの文字列の最後に次の文のためのカンマを連結しているだけです。
  • id:moon-fondu
    そうなんですね。cntn番目の要素だったんですね、ありがとうございます。
    モジュールレベル変数、初めて聞きました。

    ・モジュールレベル変数(コロ子勘違いしていた) - 派遣事務員の迷走
    https://koroko.hatenablog.com/entry/2019/08/16/083105

    ・モジュールレベル変数、グローバル変数、変数のスコープ | ExcelVBAでデキる事務職になる!
    https://vba-gate.com/a63/

    の記事を読みまして…すみません更に1点、疑問が生じたのですが。
    (モジュール変数ではなく通常の)「変数は宣言されたプロシージャの中でしか使用できません。」という説明が、リンク先にありました。

    しかしsetkansusqlは、モジュール最上部の宣言セクション内ではなく、「private function setkansusql(~」と、setkansusqlプロシージャ内で宣言されているようなので。
    これはプロシージャ変数?…という呼び方をするかどうかは不明なのですが、普通の変数ではないでしょうか?

    (2)につきましてもありがとうございます。マイクロソフト公式と、違う内容が掲載されていたんですね。やはり言語の開発元、公式の文法をしっかり把握しないといけませんね。

    (3)はそうでした、初歩的な質問で恐れ入ります。
    カンマ(,)はわかったのですが。一重引用符で囲まれた「i_tSql = i_tSql & "'" & trim(aquarium.fields(0).value) & "',"」の箇所は、文字列リテラルだから…という理由でしょうか?
    この箇所だけ一重の引用符になっているのが、少し疑問です。

    ・第2回 文字列リテラル|オススメ!OSS-DB情報|OSS-DB道場|受験対策|DBスペシャリストを認定する資格 OSS-DB技術者認定試験
    https://oss-db.jp/dojo/dojo_02

    ・第3回 SQL と引用符|オススメ!OSS-DB情報|OSS-DB道場|受験対策|DBスペシャリストを認定する資格 OSS-DB技術者認定試験
    https://oss-db.jp/dojo/dojo_03


    に、説明があったのですが。
    「SQLの文字列リテラルは一重の引用符(二重引用符は文字列リテラルには使えない)」とあります。
    今回のVBAのコードに出てくるSQLの部分は、二重引用符で囲まれた部分が多いですが、こちらは何となくわかります。
    tSqlに色々、代入しているみたいで。そしてtSQLは「dim tSql as string」と定義されているので、string型の文字列を入れるために二重引用符で囲って文字列扱いしているんだろうな、と認識しております。

    しかし一重引用符で囲われている「i_tSql = i_tSql & "'" & trim(aquarium.fields(0).value) & "',"」は、文字列…ではなく「文字列リテラル」として扱う目的や理由は、何なのでしょうか?

    度々すみません、tobeoscontinueさんの見解を伺えましたら幸いです。

    よろしくお願い致します。
  • id:tobeoscontinue
    (1)しかしsetkansusqlは、モジュール最上部の宣言セクション内ではなく、「private function setkansusql(~」と、setkansusqlプロシージャ内で宣言されているようなので。これはプロシージャ変数?…という呼び方をするかどうかは不明なのですが、普通の変数ではないでしょうか?
    最初グローバル変数だと思ったのですが確認のため検索して初めてプロシージャ変数というのを知りました(^^)
    setkansusqlにfalseやtrueが代入されているので変数だろうという認識なのでしょうがfunctionの戻り値なので変数扱いなのかどうなのかはわかりません。
    private function setkansusql(byref i_tSql as string,_byval datei as string) as booleanが宣言で
    setkansusqlプロシージャ内で使われている(代入している)だけでsetkansusqlプロシージャ内で宣言されているわけではないと思います。
    どの位置から見るかで変わってくると思います。モジュールから見ればsum_mはローカル変数ですしprivate function setkansusqlもローカル関数?です。
    tSql,aquarium,cntnの存在さえ知りません。
    一方private function setkansusql内からはsum_mはプロシージャ変数となり、tSql,aquarium,cntnはローカル変数です。

    (3)一重引用符で囲まれた「i_tSql = i_tSql & "'" & trim(aquarium.fields(0).value) & "',"」の箇所は、文字列リテラルだから…という理由でしょうか?
    文字列を現す場合一重引用符と二重引用符があります。私の解釈では一重引用符はそのまま、二重引用符はエスケープ文字など検査して展開するという操作が入ると思っています。
    言語によっては違うかもしれませんしVBAがどうなのかは知りません。例えば二重引用符を文字列で書こうとすると"""と書くことはできません。"\""とする必要があります。
    エスケープ文字があると読みにくいんですよねぇ。だから一重引用符を使っているのだと思います。
    i_tSql = i_tSql & "\"" & trim(aquarium.fields(0).value) & "\","でもOKなはずです。
    i_tSql = i_tSql & ''' & trim(aquarium.fields(0).value) & '','でもOKなはずです。
  • id:moon-fondu
    tobeoscontinueさん再度ご回答いただきまして、ありがとうございます。
    自分はローカル変数も怪しいので、復習します(^^;

    エスケープ文字、奥が深そうです。
    https://wa3.i-3-i.info/word11732.html#:~:text=%E3%81%A7%E3%81%82%E3%82%8B%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E6%96%87%E5%AD%97%E3%81%A7%E3%81%99,%E3%81%84%E3%82%8B%E3%81%A8%E8%A7%A3%E9%87%88%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82
    一重引用符も二重引用符も、文字列を現すという点で、共通している部分もあるんですね。

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

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

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

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