饂飩コーディング

iOSアプリやら、Unityやら、Cocos2dやらごにょごにょ書いております

レコード選択画面を作成してみる ダメバージョン

f:id:appdeappuappu:20201202224934p:plain
上の商品マスターを使ったデータ抽出画面の作成をしてみましょう。

下のフォームの様に、左上のチェックボックスを外した状態であれば
商品説明1,商品説明2がブランクのレコードも含めて画面に表示し
コンボボックスで絞り込みを可能にします。
f:id:appdeappuappu:20201202225000p:plain
 Like (Nz([Forms]![フォーム1]![cb大分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb中分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb小分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb商品説明1],"*"))
 Like (Nz([Forms]![フォーム1]![cb商品説明2],"*"))

 Like (Nz([Forms]![フォーム1]![cb大分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb中分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb小分類],"*"))
 IS NULL
 IS NULL
チェックボックスFALSEの時のOR条件にすればいいでしょう。



左上のチェックボックスをオンにすると
商品説明1、商品説明2ともにブランクのレコードのみになり
コンボボックスで絞り込みを可能にします。
f:id:appdeappuappu:20201202225514p:plain
Like (Nz([Forms]![フォーム1]![cb大分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb中分類],"*"))
 Like (Nz([Forms]![フォーム1]![cb小分類],"*"))
 IS NULL
 IS NULL
チェックボックスTRUEの時の条件にすればいけます。


上記までの内容をフォームのレコードソースに設定すれば
あとはコンボボックスの集合ソースを適当にグループ化してあげればOK!
f:id:appdeappuappu:20201202225028p:plain



ただ難点は、コンボボックスで選択できる項目
この場合は、大分類、中分類、小分類は何かしらのデータがセットされている
必要があります。
LIKE * では 何かしら文字がセットされているレコードを拾ってくるので
そうなってしまいます。

AccessのSQLはカラム名を[]で囲んだほうが安全なのか?

はい!またドはまりしました。

まぁ、もともとカラム名って二バイト文字で設定するものじゃないのは今までの経験上
それが当然だとおもっていたんですが、Accessではテーブルカラムを日本語で作成できますよね。
当然のようにテーブル構造が日本語で命名されてて「へぇ~そんなもんなんだ?」
程度の認識でした。

が、SQL書いて実行するとエラーになることがあったんです。
たとえば
UPDATE sampleTabel set memo='かっこでくくらないとエラーになるよ' WHERE アイテム='消しゴム';
のmemoの部分です。このSQLはエラーになる。もちろんカラムはmemoでCreateしてる。

はぁ????

ちなみにテーブルのカラム名を日本語でメモにして
UPDATE sampleTabel set メモ='これなら実行される。' WHERE アイテム='消しゴム';

そんなバカな!?って感じで
もやもやしてます。

そもそも[]でカラム名をくくるって知らなかった…・・・・

UPDATE sampleTabel set sampleTable.memo='かっこでくくらないとエラーになるよ' WHERE アイテム='消しゴム';
これでもダメだからね。はぁ???

Accessって謎。
ちなみに、上記SQLはクエリデザインにはりつければどちらもエラーなく処理できます。
問題なのはVBAでは[]がついてないと動かない。



Private Sub コマンド0_Click()
    Dim ct As New ADODB.Connection
    Dim stSQL As String
                                                                  
    Set ct = CurrentProject.Connection
    'テーブルのカラムが日本語の場合 例:カラム名=メモ
    'stSQL = "UPDATE sampleTabel set メモ='これは更新できるパターンだよ。' WHERE アイテム='消しゴム'"
    'stSQL = "UPDATE sampleTabel set [メモ]='これでも更新できるよ。' WHERE [アイテム]='消しゴム'"
    
    'テーブルのカラムが英字の場合 例:カラム名=memo
    stSQL = "UPDATE sampleTabel set [memo]='英文字だけのカラムかっこで囲む必要があるよ' WHERE アイテム='消しゴム';"
    ct.Execute stSQL
                                                                      
    Set ct = Nothing
End Sub

D関数~12個覚書 簡単な操作ならこいつらで!注意点は返り値が一つでレコード順は無視してるところ

f:id:appdeappuappu:20201122102858p:plain

D関数は集計したり検索したりする12個のApplication Object Methodがあります。
あぷりけーしょんめそっど?まぁ、Access自体に包括されている便利なものでしょうかね?
ご存じの方ご教授いただけると幸いです。

Dlookup テーブルの値を取得
Davg 平均
Dcount レコード数
Dfirst 最初の値
Dlast 最後の値
Dmax 最大値
Dmin 最小値
Dsum 合計
DstDev 合計
DStDevp 標準偏差
Dvar 標準偏差
Dvarp 分散


記述方法は全部同じで
D~関数(式、定義域、条件)

カウント

Private Sub cmdDCount_Click()
    Dim count As Long
    count = DCount("商品番号", "商品マスター", "カテゴリ='器具'")
    Me.txtDcount = count
End Sub

商品マスターのカテゴリー="器具"の商品番号カラムのレコード数をカウントする
注意点は条件の文字列はシングルコーテーションで囲むってとこかな。


検索

Private Sub cmdDLookup_Click()
    Dim itemName As String
    itemName = DLookup("商品名", "商品マスター", "カテゴリ='ペン' AND 単価 > 90")
    Me.txtDcount = itemName
End Sub

商品マスターのカテゴリー="ペン"かつ単価>90の商品名を検索してかえしてくれますが、
注意点1 ペンという文字列の条件はシングルコーテーションで囲むこと
注意点2 返り値が一つなので商品マスターには二つ条件に合うレコードがあるが
     ボールペンと万年筆どちらが表示されるかは担保されていない。
     まぁ、基本後から追加されたレコードが表示されるんだけど、DBMSそれぞれの
     仕様によって生のレコード登録アドレスって色々違うからここはなーんの保証もないよ!
     って思っててよさそう。アドレス空いた部分に差し込んできたりするからね。


平均

Private Sub cmdavg_Click()
    Dim avg As Long
    avg = DAvg("単価", "商品マスター", "カテゴリ='その他'")
    Me.txtDcount = avg
End Sub

最初のレコード

Private Sub cmdFirst_Click()
    Dim itemName As String
    itemName = DFirst("商品名", "商品マスター", "カテゴリ='器具'")
    Me.txtDcount = itemName
End Sub


最後のレコード

Private Sub cmdLast_Click()
    Dim itemName As String
    itemName = DLast("商品名", "商品マスター", "カテゴリ='ペン'")
    Me.txtDcount = itemName
End Sub


最大値

Private Sub cmdMax_Click()
    Dim itemMax As Long
    itemMax = DMax("個数", "商品マスター", "カテゴリ='紙類'")
    Me.txtDcount = itemMax
End Sub


最小値

Private Sub cmdMin_Click()
    Dim itemMin As Long
    itemMin = DMin("個数", "商品マスター", "カテゴリ='紙類'")
    Me.txtDcount = itemMin
End Sub

合計

Private Sub cmdSum_Click()
    Dim itemSum As Long
    itemSum = DSum("個数", "商品マスター", "カテゴリ='紙類'")
    Me.txtDcount = itemSum
End Sub


標準偏差関連は割愛させてください。

Access VBA VBE画面でスニペットっぽくコーディングしてみる。

標準モジュールにSnipetModuleって名前でモジュール追加して
下のプロシージャを記述しておく。
VBEのイミディエイト画面で「sni」と入力してCtrl+Spaceで
選択できるので、まぁスニペットっぽく使えるかな?

f:id:appdeappuappu:20201115190225p:plain


先人の知恵をお借りしました。へへへ
まぁ、複数人開発での標準化の参考資料にはなりそうですな。
basファイルで受け渡ししてもよいですね。
f:id:appdeappuappu:20201115190533p:plain

Attribute VB_Name = "SnipetModule"
Option Compare Database
Option Explicit

Public Function sni_コメントヘッダ()
    Debug.Print "'--------------------------------------------------------------"
    Debug.Print "'コメント記述欄                                                "
    Debug.Print "'機能をここに記述                                              "
    Debug.Print "'--------------------------------------------------------------"
    
End Function

Public Function sni_Case()
    Debug.Print "Dim i As Integer                                     "
    Debug.Print " i = 2                                               "
    Debug.Print " Select Case i                                       "
    Debug.Print "     Case 1                                          "
    Debug.Print "         MsgBox ""; iの値は1です。; ""                "
    Debug.Print "     Case 2                                          "
    Debug.Print "         MsgBox ""; iの値は2です。; ""                "
    Debug.Print "     Case 3                                          "
    Debug.Print "         MsgBox ""; iの値は3です。; ""                "
    Debug.Print "     Case Else                                       "
    Debug.Print "         MsgBox ""; iの値は1, 2, 3; 以外の値です。; """
    Debug.Print " End Select                                          "
    
End Function

Public Function sni_For()
    Debug.Print " Dim i As Integer                  "
    Debug.Print " For i = 1 To 10 Step 2            "
    Debug.Print " MsgBox i                          "
    Debug.Print " Next i                            "
    
End Function

Public Function sni_DoWhile()
    Debug.Print "Dim i As Integer           "
    Debug.Print "i=1                        "
    Debug.Print "Do While i < 100           "
    Debug.Print "i = i + 1                  "
    Debug.Print "Loop                       "
    Debug.Print "Msgbox                     "

End Function

Public Function sni_DoUntil()
    Debug.Print "    Dim i As Integer              "
    Debug.Print "    i=1                           "
    Debug.Print "'100を超えるまでループ 101で抜ける"
    Debug.Print "   Do Until i > 100              "
    Debug.Print "    i = i + 1                      "
    Debug.Print "    Loop                          "
    Debug.Print "    Msgbox i                      "


End Function

Public Function sni_SQL_UPDATE()
    Debug.Print "Dim ct As New ADODB.Connection                                    "
    Debug.Print "Dim stSQL As String                                               "
    Debug.Print "                                                                  "
    Debug.Print "Set ct = CurrentProject.Connection                                "
    Debug.Print "stSQL = ""UPDATE テーブル1 set 中分類=""1"" WHERE 小分類=""3"""; ""
    Debug.Print "ct.Execute stSQL                                                  "
    Debug.Print "                                                                  "
    Debug.Print "Set ct = Nothing                                                  "

End Function

Public Function sni_SQL_DELETE()

    Debug.Print "Dim cn As ADODB.Connection             "
    Debug.Print "Dim MYSQL As String                    "
    Debug.Print "'接続                                  "
    Debug.Print "Set cn = CurrentProject.Connection     "
    Debug.Print "'削除                                  "
    Debug.Print "MYSQL = ""Delete * FROM テーブル1;""   "
    Debug.Print "cn.Execute MYSQL                       "
    Debug.Print "'終了                                  "
    Debug.Print "cn.Close: Set cn = Nothing             "
    
End Function

Public Function sni_SQL_SELECT典型的()
    Debug.Print "Dim Cn As ADODB.Connection 'ADOコネクションオブジェクト              "
    Debug.Print "Dim Rs As ADODB.Recordset 'ADOレコードセットオブジェクト             "
    Debug.Print "Dim MySQL As String 'SQL文                                           "
    Debug.Print "                                                                     "
    Debug.Print "Set Cn = CurrentProject.Connection '現在のデータベースへ接続         "
    Debug.Print "Set Rs = New ADODB.Recordset  'ADOレコードセットのインスタンス作成   "
    Debug.Print "MySQL = ""SELECT * FROM テーブル名 WHERE 条件;"" 'SQL文作成            "
    Debug.Print "Rs.Open MySQL, Cn 'レコード抽出                                      "
    Debug.Print "                                                                     "
    Debug.Print "If Rs.BOF = True And Rs.EOF = True Then '存在チェック                "
    Debug.Print "   MsgBox (""レコードが存在しません"")'メッセージ                     "
    Debug.Print "Else                                                                 "
    Debug.Print "   Do Until Rs.EOF '抽出したレコードが終了するまで処理を繰り返す     "
    Debug.Print "       Debug.Print Rs!フィールド名 'フィールドを取り出す             "
    Debug.Print "       Rs.MoveNext '次のレコードに移動する                           "
    Debug.Print "   Loop                                                              "
    Debug.Print "End If                                                               "
    Debug.Print "                                                                     "
    Debug.Print "'閉じる                                                              "
    Debug.Print "Rs.Close                                                             "
    Debug.Print "Cn.Close                                                             "
    Debug.Print "'オブジェクトの破棄                                                  "
    Debug.Print "Set Rs = Nothing                                                     "
    Debug.Print "Set Cn = Nothing                                                     "

End Function

Public Function sni_SQL_レコード処理エラー無し()
    Debug.Print "Dim ct As New ADODB.Connection                            "
    Debug.Print "Dim rs As New ADODB.Recordset                             "
    Debug.Print "Dim stSQL As String                                       "
    Debug.Print "                                                          "
    Debug.Print "'select文の作成                                           "
    Debug.Print "stSQL = ""SELECT * FROM テーブル1 WHERE 小分類=""""9"""";"""
    Debug.Print "stSQL = stSQL & """" "
    Debug.Print "                                                          "
    Debug.Print "Set ct = CurrentProject.Connection                        "
    Debug.Print "rs.CursorLocation = adUseClient                           "
    Debug.Print "rs.Open stSQL, ct, adOpenDynamic, adLockOptimistic        "
    Debug.Print "                                                          "
    Debug.Print "If rs.EOF Or rs.BOF Then                                  "
    Debug.Print "    '条件に合うレコードがない場合                         "
    Debug.Print "Else                                                      "
    Debug.Print "    '条件に合うレコードがある場合                         "
    Debug.Print "     '先頭レコードに移動                                  "
    Debug.Print "       rs.MoveFirst                                       "
    Debug.Print "       While Not rs.EOF                                   "
    Debug.Print "            MsgBox (rs.Fields(""本文""))                    "
    Debug.Print "           '次のレコードに移動                            "
    Debug.Print "          rs.MoveNext                                     "
    Debug.Print "       Wend                                               "
    Debug.Print "End If                                                    "
    Debug.Print "                                                          "
    Debug.Print "'レコードセットを変更する場合はコレ                       "
    Debug.Print "'Set Me.Recordset = rs                                    "
    Debug.Print "                                                          "
    Debug.Print "Set rs = Nothing                                          "
    Debug.Print "Set ct = Nothing                                          "
    Debug.Print "                                                          "
    Debug.Print "Me.Requery                                                "

End Function

Public Function sni_SQL_レコード処理エラー処理付き()
    Debug.Print "Dim myCn     As ADODB.Connection    'ADOコネクションオブジェクト                        "
    Debug.Print "Dim myRs     As ADODB.Recordset     'ADOレコードセットオブジェクト                      "
    Debug.Print "Dim strSQL   As String              'SQL文用文字列                                      "
    Debug.Print "                                                                                        "
    Debug.Print "'エラートラップ                                                                         "
    Debug.Print "On Error GoTo Err_Exit                                                                  "
    Debug.Print "                                                                                        "
    Debug.Print "'現在のデータベースへ接続                                                               "
    Debug.Print "Set myCn = CurrentProject.Connection                                                    "
    Debug.Print "                                                                                        "
    Debug.Print "'ADOレコードセットのインスタンス作成                                                    "
    Debug.Print "Set myRs = New ADODB.Recordset                                                          "
    Debug.Print "                                                                                        "
    Debug.Print "'SQL文作成(誕生月指定)                                                                "
    Debug.Print "strSQL = ""SELECT * FROM 顧客テーブル WHERE 誕生月 = 3""                                  "
    Debug.Print "                                                                                        "
    Debug.Print "'レコードセット取得・・・(※1)                                                          "
    Debug.Print "myRs.Open strSQL, myCn, , adLockOptimistic                                              "
    Debug.Print "                                                                                        "
    Debug.Print "With myRs                                                                               "
    Debug.Print "    '対象データがなければ終了                                                           "
    Debug.Print "    If .EOF Or .BOF Then                                                                "
    Debug.Print "        MsgBox ""該当データがありません。処理を終了します。"", vbOKOnly + vbInformation   "
    Debug.Print "        GoTo End_Proc                                                                   "
    Debug.Print "    Else                                                                                "
    Debug.Print "        '先頭レコードに移動                                                             "
    Debug.Print "        .MoveFirst                                                                      "
    Debug.Print "        While Not .EOF                                                                  "
    Debug.Print "            'プレゼント発送日にシステム日付を代入                                       "
    Debug.Print "            .Fields(""プレゼント発送日"") = Date                                          "
    Debug.Print "            '更新実行                                                                   "
    Debug.Print "            .Update                                                                     "
    Debug.Print "            '次のレコードに移動                                                         "
    Debug.Print "            .MoveNext                                                                   "
    Debug.Print "        Wend                                                                            "
    Debug.Print "    End If                                                                              "
    Debug.Print "End With                                                                                "
    Debug.Print "MsgBox ""処理を終了しました。"", vbOKOnly + vbInformation                               "
    Debug.Print "'********                                                                               "
    Debug.Print "End_Proc:                                                                               "
    Debug.Print "    'オブジェクトの開放                                                                 "
    Debug.Print "    Set myRs = Nothing: Close                                                           "
    Debug.Print "    Set myCn = Nothing: Close                                                           "
    Debug.Print "                                                                                        "
    Debug.Print "    Exit Function                                                                       "
    Debug.Print "                                                                                        "
    Debug.Print "Err_Exit:                                                                               "
    Debug.Print "    'エラーNOとエラーの詳細を表示                                                       "
    Debug.Print "    MsgBox Err.Number & "":"" & Err.Description, vbOKOnly + vbCritical, ""ADO接続()""   "
    Debug.Print "    'オブジェクトの開放                                                                 "
    Debug.Print "    Set myRs = Nothing: Close                                                           "
    Debug.Print "    Set myCn = Nothing: Close                                                           "

End Function

accessでナビゲーションウィンドウが小さくなった時。

デザインビューでナビゲーションウィンドウが小さくなり過ぎて大きく出来なくなる事があります。

その時はF11で一度最小化してマウスを合わせて大きくしましょう。メモでした

me.[商品名]とme.商品名の違いは?  me. me!の違いは?

me.[商品名]とme.商品名の違いは?
[xxxx] 基本は同じ
me.[商品名]のような使い方は商品名23の様に数字・日本語が名前に混在して入っている場合に使う


me. me!の違いは?
掲示板では
「Me.」は「Meのプロパティとして構成しているラベルコントロールのプロパティであるCaption」
「Me!」は「Meという名のFormの中にあるラベルコントロールのプロパティであるCaption」
(両方ともMeは自分自身のことを示す変数となりますが)

okwave.jp

「!」を使うと、フォームの場合はフォームに設置されたコントロールが選択できる。

f:id:appdeappuappu:20201105213340p:plain
!だとコントロールが選択できる

「.」を使うと、フォームの場合はフォームのプロパティーが選択できる。

f:id:appdeappuappu:20201105213509p:plain
.だとプロパティーが選択できる


標準モジュールからだとこんな感じで他のフォームの値をセットできるよ。
Forms!パブリックテスト!txtここへセット.Value = "2"
Forms!パブリックテスト!txtここへセット = "111112"

Forms! フォーム名!コントロール名 てな具合

他にも、
フォーム名.コントロール名も使える。