• ベストアンサー

accessのVBAの記述についていくつか質問です。

質問が複数あるため、箇条書きにいたします。(質問の仕方がまちがってたらごめんなさい)どれも基本的な質問で申し訳ありません。 (1)エラートラップはすべてにつけたほうがいいのでしょうか?  極端に言えば、フォームを開くだけの時にもつけるものなのですか?  みなさんはどのような基準でつけているのでしょうか。 (2)FUNCTIONプロシージャは「結果を返す」時に使うものとありますが  いまいち意味がわかりません。SUBプロシージャでもできるのでは  ないでしょうか?どのようなときに役立つものなのでしょうか? (3)ADO,DOAもマスターしたいと思っているのですが、参考書を見ても  いまいち理解ができません(T T) なにかいい勉強方法、コツ、よい参考書があったら教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
noname#102878
noname#102878
回答No.2

(2)について 組み込みのVBA関数なんかでIsDate()やらNow()やらありますよね。 IsDate()はカッコの中に入れた変数の中身が日付として評価できるならTrueを、日付として評価できない値ならFalseを返します。 自前でFunctionを作るので一番多いのは「入力された文字列をチェックする」です。 例えば・・・ 日付型のフィールドにデータを入れるためのテキストボックスがあったとして、その値が日付かどうかは先のIsDate関数でもできちゃいます。 だけど「日付だったらなんでもいいの?」という、そのデータベースだけで通用するルールも存在するわけです。 従業員名簿なら定年が60歳だから誕生日フィールドに今から61年以上前の日付は入らないし、16歳から入社できるならそれよりも後の日付も入らない。 こういうチェックをするために自前のFunctionを作りますね。 もとのイベントプロシージャ内に記述するとゴチャゴチャしちゃうでしょ? [更新]ボタンのイベントプロシージャには単純にデータを更新するためのコードしか書かない。 値をチェックするコードは別途Functionプロシージャに書いてイベントプロシージャから呼び出してあげれば、イベントプロシージャ内のコードがすっきりする。 Functionを呼び出す部分に「日付をチェック」とかコメントを書けば済んじゃう。 (3)について 今は意味がわからなくても、とにかくサンプルをどんどん経験して行くしかないと思います。 Access自体の入門書ではADOやDAOまで載ってませんから、ADO自体の書籍か、VB+ADOの書籍を狙ったらいいと思います。 ちなみにDAOは古い技術ですからなかなか見つからないと思いますが・・・ そして「オブジェクトの構造」を覚えちゃえば簡単ですって。 ADOであれば、Connectionオブジェクトって言う「データベースに接続するためのオブジェクト」があって、ConnectionStringプロパティに「接続するための情報」を文字列で指定する。Access2000以降であれば単純に Dim cn As ADODB.Connection Set cn = CurrentProject.Connection ってやるだけで全部済んじゃう。 テーブルやクエリーで開いたレコードのかたまりを取得したければRecordsetオブジェクトを使う。 Dim rs As ADODB.Recordset Set rs = New ADODB.Recordset rs.Open "テーブル名またはクエリー名またはSQL文字列", cn ってするだけでOK。 そこから実際に各フィールドの値を取りたければ rs.Fields("フィールド名").Valueの値を取ればいい。 「あるレコードの中の特定のフィールドの値」なんだから見たまんまでしょ? ADOやDAOで開いている全てのレコードの値を取る場合はレコードを1件ずつループさせながら行う。 例えば10件あるレコードの場合、頭の中にエクセルのシートを思い浮かべる。 ちなみに今見てる行を「カレントレコード」って言います。 rs.MoveFirst Do Until rs.EOF MsgBox rs.Fields("フィールド1の名前").Value MsgBox rs.Fields("フィールド2の名前").Value ・・・ rs.MoveNext Loop こうやって、「レコードのかたまり」の最初の行から最後の行まで1行ずつループさせて、フィールド1つずつ値を取ってゆく。 まぁあせらずゆっくり勉強してくださいな。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

(3)の簡単な例を挙げます。これを色々な場合に修正し、繰り回して使いこみすれば、相当使えます。丸暗記するべきですが、意味も参考書で調べて習得してください。前半は他の質問に答えたもの、後半はADOとDAOの比較形式にしています。('の行がDAOの場合の表現) 内容はテーブル(マンション)を読んで、一部(販売フィールド、yes/no型のyes分)をアウトプットテーブル(売却済マンション)に追加しています。 (1)DAO Sub test01() Dim db As Database Dim rs As Recordset Dim ors As Recordset Set db = CurrentDb Set rs = db.OpenRecordset("マンション", dbOpenDynaset) Set ors = db.OpenRecordset("売却済マンション", dbOpenDynaset) rs.MoveFirst While Not rs.EOF '------------ If rs!販売 = True Then ors.AddNew ors!マンション = rs!マンション ors.Update ' MsgBox rs!マンション End If '----------- rs.MoveNext Wend rs.Close ors.Close End Sub '=============================== (2)ADO Sub test02() Dim cn As ADODB.Connection ' Dim db As Database Set cn = New ADODB.Connection ' Set db = CurrentDb '--------- Dim rs As ADODB.Recordset 'Dim rs As Recordset Dim ors As ADODB.Recordset ' Dim ors As Recordset '-------- cn.ConnectionString = "provider=microsoft.jet.OLEDB.4.0;" & _ "data source=c:\My Documents\db7.mdb" ' db7データベース cn.Open '--------- Set rs = New ADODB.Recordset rs.Source = "マンション" 'マンションテーブル rs.ActiveConnection = cn rs.CursorType = adOpenDynamic rs.Open 'Set rs = db.OpenRecordset("マンション", dbOpenDynaset) Set ors = New ADODB.Recordset ors.Source = "売却済マンション" '売却済マンションテーブル ors.ActiveConnection = cn ors.CursorType = adOpenStatic ors.LockType = adLockOptimistic ors.Open ' Set ors = db.OpenRecordset("売却済マンション", dbOpenDynaset '--------- rs.MoveFirst ors.MoveLast While Not rs.EOF '------------ If rs!販売 = True Then ors.AddNew ors!マンション = rs!マンション ors.Update ' MsgBox rs!マンション End If '----------- rs.MoveNext Wend '-------- rs.Close 'rs.Close Set rs = Nothing ors.Close ' ors.Close Set ors = Nothing '------- Set cn = Nothing End Sub

  • papayuka
  • ベストアンサー率45% (1388/3066)
回答No.1

こんにちは。 (1)はただ開くだけなら、私は付けません。  (Open時の処理で、エラーの出る可能性がある場合は別です) (2)はSubでも出来ますが、「テーブル名と検索文字を渡すとテーブル内を検索してデータの個数を返す」とか、そういうロジックを複数の Sub で何度も使うような場合に、その都度 Sub の中に書いても良いけど Function にしてしまえば1つだけで済み、修正が必要な場合でもそこだけ直せばOKとなります。 例では、1.05 を 1.07 に直す必要が出来た時に Function 内だけの修正で済みます。 (簡単な例なのでその都度書いても対した手間ではないけど、、、) Function PLUS(i As Currency, j As Currency) As Currency  PLUS = (i + j) * 1.05 End Function Sub a()  MsgBox PLUS(100, 200) End Sub Sub b()  MsgBox PLUS(300, 400) End Sub Sub C()  MsgBox PLUS(500, 1400) End Sub (3)は他の方にお任せします。(^^;

関連するQ&A

  • アクセス2002 VBA

    フォームを保存せずに閉じたいのですが、 当該フォームの「閉じる時」プロパティーにイベントプロシージャを設定し、 Private Sub Form_Close() DoCmd.Close acForm, "フォーム1", acSaveNo End Sub と記述しました。  ところが、実行すると 「Close アクションの実行はキャンセルされました。」とエラーになってしまいました。  間違いの指摘をお願いします。

  • Access VBAで

    VBAの超初心者です。 Accessのフォームでコマンドボタンを押すと、決まった文字が入力できるフォームを作りたいと思っています。 クリック時のイベントプロシージャーはどのように記入すればよいのでしょうか。 ど素人な質問ですみません。

  • アクセス イベントプロシージャーを記述する場所。

    アクセス初心者です。表題の件です。アクセスクラブを参考にしながら管理簿を作成しています。SampleFile184を見ながら作っているのですが、イベントプロシージャーを記述する場所が分かりません。カレンダーコントロールを貼り付けたフォームに以下のようなプロシージャーを記述します。とありますが、どこから入って記述すればいいのでしょうか?フォームヘッダーをクリックしてデザインから開いて、クリック時のとこでしょうか?それともモジュールを開いて書いていけばいいのでしょうか?初心者の質問ですみません。困っています。わかる方がいましたら、ご教授ください。よろしくお願い致します。

  • Functionプロシージャの便利さがわかりません

    私はVBAコードを作る時は、もっぱらsubプロシージャーを使ってしまうのですが、 http://excelvba.pc-users.net/fol5/5_4.html を参考に、 Functionプロシージャとsubプロシージャの違いを確認してみたのですが、 Functionプロシージャの便利さがわかりません。 *********************************** Sub Test() SubプロシージャとFunctionプロシージャのテスト i = 1 Call Subプロシージャ(i) i = Functionプロシージャ(i) MsgBox "Functionプロシージャ結果:" + CStr(i) End Sub Sub Subプロシージャ(ByVal i As Integer) MsgBox "Subプロシージャ結果:" + CStr(i) End Sub Function Functionプロシージャ(ByVal i As Integer) As Integer i = i + 1 Functionプロシージャ = i End Function *********************************** Functionプロシージャは、 (ByVal i As Integer) As Integer のように、、二回もデータ型(Integer)の指定をしなくてはいけないのでしょうか? リンク先の説明には、 「SubプロシージャとFunctionプロシージャの違いは Subプロシージャが引数を受け取るのみに対して Functionプロシージャは引数を受け取り、 戻り値を返すという関数としての役割を果たすことができる点です。」 と記載されてますが、 それはSubプロシージャでも出来てますよね? サンプルコードにおいてのFunctionプロシージャの便利さを教えてください。

  • ExcelのVBA。Staticな変数について

    あるプロシージャやfunctionで定義したstaticな変数は、その定義したsubやfunctionで有効です。今回、例えば、static a as integer とSub AAA 内で、定義し、その AAA が呼び出す BBB という ユーザーフォームの中でも staticな変数である a に値を代入したり、変更したりし、その後 sub AAAにまた入ったとき、BBBで変更した内容を保持することができるのでしょうか。

  • アクセステーブルがあれば削除VBA

    win10 office365 access365におきまして テーブル この例ではTMPがあれば テーブルそのものを削除し (ですから削除クエリを使うこととは違うと思いましたが) はじめから存在しないときは次のコードに進む ということでほかの記事を参考に作ってみたのが Public Function tmpdelete() If funcTableExists("T_TMP") = True Then DoCmd.DeleteObject acTable, "T_TMP" End If End Function ----------------------- そもそもfuncTableExistsというのは 付属の関数ではないのかなと調べまして ----------------------- Private Function funcTableExists(ByVal strTableName As String) As Boolean Dim db As Database Dim tdf As TableDef Set db = CurrentDb For Each tdf In db.TableDefs If (T_TMP= strTableName) Then funcTableExist = True Exit Function End If Next tdf Set tdf = Nothing db.Close Set db = Nothing End Function --------------------- If (T_TMP= strTableName) Then ここに削除判定の対象のテーブル名を入れましたが 上記いずれも 作動しません マクロのプロシージャで組み入れたいので subでばく functionで書くようにとありましたので 上記のようにしました また すみません 宜しくお願い致します

  • access vbaのコンパイルエラーについて

    お世話になります。 vbaは超初心者なので、説明が良くないかもしれませんがご容赦ください。 フォーム上のレコード数を一件に制限する必要があり、下記サイトを参考に作成中のデータベースに構文をあてはめてみました。 http://hatenachips.blog34.fc2.com/blog-entry-189.html サブフォーム移動時のプロシージャは、 Public Sub Form_Current() Me.AllowAdditions = Me.Recordset.RecordCount < 1 End Sub メインフォーム移動時の動作として、対象のサブフォーム名を入れて下記のような構文を 作りました。 Private Sub Form_Current() Me.新規入力 サブフォーム.Form.Form_Current End Sub ところが、「コンパイルエラー 変数が定義されていません」となってしまいました。 サブフォームコントロール名はデザインビューのプロパティで、タブの「すべて」の名前の欄にあるものだと思っているのですが、もしかしてこれが違っているのでしょうか? エラーの意味がよくわからず、困り果てています。 どなたかお力をお貸しください。 よろしくお願いします。

  • Excel VBAの Functionをワークシートから使用できないようにしたいのですが...

    Excel VBAについて質問です。 functionプロシージャを使っている時,一般のマクロからは呼び出せるが,ワークシート関数として使いたくないものがあります。 すなわち,「関数の挿入」ダイアログの「ユーザー定義」のところに不必要な(ワークシート関数として使う意図のないもの)を表示させたくないのですが,そのようなことは可能でしょうか。 今,できるだけsubプロシージャの形にするようにしたりしているのですが,うまい方法があればFunctionも使いたいと思っています。 良い方法があれば教えてください。

  • access vba プロシージャの呼び出し

    access vba についての質問です。 フォームにテキストボックスが二つあるのに対して、 オプションボタンが三つあります。(グループです) テキストボックス1に文字列を入力し、コマンドボタンを押すと 選択されているオプションボタンのcaptionをテキストボックス1の文字列と合わせる形でテキストボックス2に反映させたいです。 コマンドボタンのクリックで以上の動きをするfunctionプロシージャを呼び出したいのですが、呼び出す側プロシージャと呼び出される側プロシージャの変数の設定がわかりません。 超初心者のため初歩的、かつ説明がわかりづらくて恐縮ですが、理解のため省略などをしない形でコードの見本等お教え願えませんでしょうか。 よろしくおねがいします。

  • Accessの条件つき抽出>テーブル作成。

    「T_マスタ」 ・氏名ID ・氏名 ・会社グループ 「T_サブ」 ・氏名ID ・データ年 というようなテーブルがあり、この2ツから「Q_検索」というクエリを作成しています。 このクエリを元に検索フォームを作成しました。 この検索フォームで「データ年」を選んで「エクスポート」を押すと、 会社グループが「110」のものだけを抽出して「T_Excel_110」という テーブルが作成されるようにしたいのです。 「エクスポート」ボタンのコードは ---------------------------------------- (検索用のコード)省略 DoCmd.RunSQL "SELECT [T_マスタ].[氏名ID], [T_マスタ].[氏名], [T_マスタ].[会社グループ],[T_サブ].[データ年], INTO T_Excel_110" _ & " FROM (T_マスタ INNER JOIN T_サブ ON [T_マスタ].[氏名ID]=[T_サブ].[氏名ID]) " _ & " WHERE ((([T_マスタ].[会社グループID])="110"))" & WhereCond stDocName = "T_Excel_110" DoCmd.OpenTable stDocName, acNormal, acEdit MsgBox "[ファイル]-[エクスポート]でExcelファイルを指定してください。" としたのですが、エラーになってしまいます。 いったいどこを直せばいいのでしょうか?

専門家に質問してみよう