Private Sub Form_Load()
Static co As New Collection 'Class1保存用
Dim ctl As Control
For Each ctl In Me.Controls
If ctl.Name Like "txt*" Then
co.Add New Class1
Set co(co.Count).テキスト = ctl
Set co(co.Count).コマンド = Me.Controls("cmd"&Mid(ctl.Name,4))
ctl.OnClick ="[イベント プロシージャ]"
End If
Next
End Sub
Private Sub 日付_BeforeUpdate(Cancel As Integer)
If Not IsNull(DLookup("日付", "テーブル名", "日付=#" & Me.日付 & "#")) Then
MsgBox "既に入力された日付です。異なる日付を入力してください"
Cancel = True
End If
End Sub
Private Sub 日付_AfterUpdate()
Me.日付.DefaultValue = “#” & Me.日付 & “#”
End Sub
Private Sub 名コード_AfterUpdate()
Me.名コード.DefaultValue = Me.名コード
End Sub
Private Sub 数量_KeyDown(KeyCode As Integer, Shift As Integer)
On Error Resume Next
Select Case KeyCode
Case vbKeyUp
DoCmd.GoToRecord ,, acPrevious
Case vbKeyDown
DoCmd.GoToRecord ,, acNext
Case Else
End Select
End Sub
メイン/サブフォームといえば、クエリからフォームを作ってサブフォームウィザードに設定する、と覚えています。皆さん、どうでしょう?
メインフォームで氏名を選んだのに、サブフォームで会員名や会員IDなどを重複表示する、意味があるのと思ったり、サブフォーム連結クエリにリンクフィールドを残しておけば、問題ないんじゃないと思ったり、参照整合性が設定されてないじゃんと思ったり、もやもやしました。
たぶん、短いテキスト型で組んであります。微妙ですよね。
動画9:50付近、左詰めだから、T_担当者マスタの担当者CDフィールドは短いテキスト型?
動画11:23付近、ルックアップウィザード完了したのに、会員マスタテーブルの担当者フィールドが短いテキスト型から数値型に変わらない?
ルックアップウィザードは、会員IDや商品CDを暗記入力するのは大変。会員氏名や商品名で入力出来たら便利よねって感じでイメージしているのですが。実際、どうですか?実務でも頻繁に使われるのでしょうか?
たぶん、ルックアップウィザードが使われている。購入履歴テーブルの会員名フィールドに、例えば、太郎と表示されていたとしよう。会員マスタテーブルの氏名フィールドに関連しているように思えるかもしれない。が、実は中身は何某かの数字である。何処からきたのか?そう、会員マスタテーブルのIDフィールドと関連している。
提示のクラスモジュールは、コマンドボタンとテキストボックスを持っています。つまり、コマンドボタンとテキストボックスが関連付けられていることになります。
この関連付けをどのように表現するかを決める必要がありますね。
例えば、
cmdホゲ と txtホゲ というように、先頭3文字でコントロールの種類、後の部分で項目名を表現するというような仕様にするとします。
こうすると下記のようなコードでいけます。
動画の下記でルックアップウィザードで「会員マスタ」の「担当者」から「T_担当者マスタ」の「担当者名」をルックアップするように設定しています。
09:14 リレーションシップ
これにより、「会員マスタ」の「担当者」で入力するとき、泥ぷダウンリストから担当者名を選択できるようになります。
またルックアップウィザードで関連付けると自動でリレーションシップも設定されることを説明しています。
動画からの切り抜き

上の画像をみると、「T_担当者マスタ」の「担当者CD」と「会員マスタ」の「担当者」が結合されています。
動画では説明されてませんが、このようにルックアップウィザードで関連付けると、
「会員マスタ」の「担当者」の「T_担当者マスタ」の「担当者CD」と同じデータ型(数値型)になります。
ところがテーブルを開いてみると、数値ではなくテキストで名前が表示されています。
これは、「担当者」には表示上は担当者名が表示されるが実際に格納されている値は「担当者CD」だからです。
これは最初は直感的に理解しずつらい部分ですので、動画の通りにテーブルを作成して、ルックアップウィザードで関連付ける作業をしてみるといいでしょう。
その上で、テーブルデザインビューでその「担当者」フィールドのプロパティ設定がどうなっているか確認するといいでしょう。とくにルックアップの設定をよく見てみましょう。
『「会員マスタ」のIDと「T_購入履歴」の会員名をリレーションシップで関連付け』も上記と同様の設定がされているのだと思います。
動画ではその辺の説明が省略されているので誤解を生みやすいですね。
「T_購入履歴」の「会員名」フィールドは私なら「会員ID」という名前にしますね。
誤解を生む原因になりますので。
リンクがうまく貼れなかったようなので、飛べないときはググッて下さい。
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13236877383
正直、ExcelVBAはよくわかりませんが、ググってみました。
これは役に立ちませんか?アレンジすれば、いけるかも?
もしやと思いましたが、Excelのマクロファイルを予め有効化しておくことでエラー回避できました。
メッセージもExcelから発せられている「OK」ボタンonlyのものです。
新規に空のaccdbファイルを作成して、そこでフォームを作成してコマンドボタンを配置して確認したということでしょうか。
もし、そうなら、Access2003から変換したaccdbで、新規フォームを作成してそこにコマンドボタンを配置した場合は動作しますか。
回答ありがとうございます。
全てのフォーム上のvba コードでしているコマンドが効いていません。エラーがでるのではなく反応していないのです。先程MsgBoxを試したのは新しいファイル作成してそれで確認しました。
VBAが動作しないのは、もともとあったフォームすべてですか。それとも特定のフォームのみですか。
また、動作しないとは、コマンドボタンをクリックしてもなんの反応もないという状態でしょうか。それともエラーが出て動作しないのでしょうか。
回答ありがとうございます。新規フォーム作成してコマンドボタンにMsgBox***を記述しますと動作しました。元のファイルのフォームに新たにボタンを追加して記述しても動作はしませんでした。そのファイルにはコードでなくマクロでのコマンドボタンもあるのですが、それは動作します。
そのaccdbファイルで、新規にフォームを作成して、コマンドボタンを配置して、下記のような簡単なコードを記述した場合は動作しますか。
もしかして
[イベントプロシージャ]
(半角)になってるとかりんごさんへ
コメントありがとうございます。
WIN10PCの方で2003mdb形式→accdb形式に変換して様子を見ています。WIN7PCの2003mdb形式の方はずっと使っており問題ありませんでした。それをWIN10PCに元のファイルをコピーしてaccdbで保存したのです。フォームも沢山あるのですが例えばメインパネルフォーム上ボタンのVBAコードの Docmd.OpenForm”***" 等も動作しないのです。Accessファイルはサーバー経由ではなく使用するPCにあります。Access2019は2003と大きく表示構成が変わっていてちょっと戸惑っています。
たぶん、お節介ですが、すみません、もう少し情報が要求されると思いまして。
2003mdb形式→accdb形式でしょうか?それは、WIN7でも期待どおりに動かないの?
VBAコードが全行動かないの?一部動かないの?例えば、どんなVBAコードが動かないの?
Accessファイルをサーバーに置いて、ローカルからリンクテーブル経由で繋いでいる?
回答すぐ頂いたのにこちらの確認が遅れてしまってすみませんでした。またACCESSは2010でなく2019でした(タイプミスしてまして失礼しました)。確認したところ参照設定に不可項目はありませんでした。設定は規定のままでしております。マクロの命令は動作しているのですがVBコードでの分が動作していませんでした。プログラム全然知識ないのですがバージョンの違いでしょうか?
この部分のコードにレコードを勝手に登録するような内容はありません。データを削除した後、「今日ではない日付」を最初に入力した場合に同じエラーメッセージが表示されますか?
(例えば「今日」が2021/9/15なら2021/9/16を入力します)
その後テーブルを開いて内容を確認してください。何が登録されていますか?
旧質問が解決済だから、新しい質問をたてるのは、どうですか?
日付を入力したテキストボックスは、非連結ですか、それとも、◯◯テーブルもしくは△△クエリのほにゃららフィールドに連結していますか?新しい質問で教えて下さい。
先日は皆様に大変お世話になりました。
そして、またご質問させてください。
先日hiroton さんに
お教えいただいた以下のプログラムを入れました。
Private Sub 日付_BeforeUpdate(Cancel As Integer)
If Not IsNull(DLookup("日付", "テーブル名", "日付=#" & Me.日付 & "#")) Then
MsgBox "既に入力された日付です。異なる日付を入力してください"
Cancel = True
End If
End Sub
そうして、希望通り重複エラーを出せるようになったんです。
ところがです。
私は、関連のデーターをすべて消しました。
そうしてシステムを最適化しました。
そうしてオートナンバーを1からスタートに
して使おうとしました。
すると、
「既に入力された日付です。異なる日付を入力してください」
というエラーが出るように成りました。
日付は、本日の日付(2021/09/14)です。
入力できないので、1日ずらして(2021/09/15)を
入力しました。
そうして気になってテーブルを覗くと、
2021/09/14と2021/09/15で
データーが入力されていました。
こういったエラーはどうしたら
取り除けますか?
その後は普通に入力できるので、
データーをオールクリアして最適化して、
オートナンバーを1から始めるようにしたときに
だけエラーが出るみたいです。
すごく細かい質問になって
失礼します。
お手数ですが、ぜひ御指南ください。
ACCESSで使うプログラミング言語はVBA(Visual Basic for Applications)ですね
VBAはその名の通りVisual Basicを各アプリケーション用にカスタマイズしたものです。
ACCESS VBAに似たようなものにEXCEL VBAがあります
「だいたい同じ」ですが「アプリケーション用にカスタマイズ」の部分で微妙に差があります。「VBA」といえば「EXCEL VBA」のほうが主流で情報としてもたいてい「EXCEL VBA」が先に見つかります。「だいたい同じ」なので気にせず情報を活用しましょう。特に今回のような話だとEXCELもACCESSも関係ないのでそのまま流用できることでしょう
本題に戻って、VBA自体にポート入出力をどうこうする機能はありません
ただし、Windows APIを使うことができるので、それで対応できるならできるでしょう
参考:第123回.APIについて(Win32API)(エクセルの神髄さん)
具体例がないと合っているのかわかりませんが適当に検索すると
EXCEL VBA(マクロ)でシリアル通信 コード公開(株式会社応用技術研究所さん)
なんかも見つかります
もしかするとこういうのも参考になるかな?
VBAでEasyCommを使用した三菱MELSEC-FXとのシリアル通信(自恃ろぐ-jizilog.comさん)
リレーションシップを設定せずに、テーブルAやテーブルBにレコードを追加したら、テーブルCにも追加する。A‘B’C‘も同様に、と単純に考えればいけるのかな、う〜ん。
たしか、内部結合があって、さらに、片方のテーブルからレコード全部をおまけしちゃう機能だったと思うんですけど、ちょっと、イメージとは違います。
1または0は、NULLを許容出来るリレーションシップを思い浮かべたのですが、冷静に考えると破綻していますね。多または0は、見出しレコードに対応する明細レコードが1:0〜多と解決しました。
テーブルA:{主キーa},属性項目x
テーブルB:{主キーb},属性項目y
テーブルC:{主キーc},外部キーa,外部キーb
机上で、排他的に参照するモデルを見ただけなのですが、遠い将来、実際に試せるものような機能が出てこないかな、と質問してみました。
テーブルA‘:{主キーa},属性項目x,{被参照キーz(重複禁止)}
テーブルB‘:{主キーb},属性項目y,{被参照キーz(重複禁止)}
テーブルC‘:{主キーc},関連項目e,参照キーz
特別なことをしてなければたいてい上位互換性はあります。
とりあえず、参照設定に参照不可の項目がないか確認してみてください。
定番のVBA関数でコンパイルエラーが出たときの対処法:Excel VBA|即効テクニック|Excel VBAを学ぶならmoug
「1または0、多または0のリレーションシップ」とはどのようなものでしょうか。
他のデータベースにはそのような機能かあるのでしょうか。
外部結合(OUTER JOIN)のことではないですよね。
とりあえずExcelみたいな何かになるけど、請求書を発行するときに、B業務テーブルの要レコードを絞り込み、追加クエリ。A業務テーブルの要レコードを絞り込み、集計クエリからの追加クエリ。みたいな感じで、請求書の明細欄テーブルに追加すれば、いいんじゃない?
それぞれメリット、デメリットがありますので、運用実態によるでしょうね。
テーブルは分けておいて、集計するときに、ユニオンクエリでまとめて、それから集計クエリにする。
メリット
現状のエクセルの表をそのままテーブルにすればよい。
デメリット
ユニオンクエリはレコード件数が多いと重くなりがち。
テーブルは一つにまとめておく。
メリット
ユニオンクエリを作る必要がなく、そのまま集計クエリにできる。
デメリット
片方のテーブルにしか必要のないフィールドもすべて持つ必要がある。
自分としては、
分ける方は、ユニオンクエリで重くなるのはどうしようもないが、
纏める方は、業務によって不必要のフィールドは、クエリや入力フォームを別に作成することでなんとでもなるので、
一つに纏める方がいいかと思います。
集計条件に該当するデータの入力があったとき(日々のデータ入力のとき)
VBAで集計条件の有無をチェックしつつSQLを発行して
hirotonならこうするだろうというたとえです。実際には要件に合わせていろいろでるでしょう
繰り返しますが
結局のところデータ構造自体はよくある「請求書」「請求明細」の構造と同じです。運用や作業性に合わせてどのようにシステムを組み込んでいくかという問題になると思います
「請求書を発行する」という目的があるようなので今あるデータを使って請求書を作ってみるといいでしょう。ACCESSで実現するために(データベース的な考え方として)何が必要か見えてきますし、そのうえで「では、新しい請求書を発行するためにはどのようなデータ構造、入力・処理が必要か」というのが見えてきます
ここまでが準備です。Excel(表計算)みたいな何かを作る企画がスタートします。
業者に発注して、Excelみたいな何かを作ってもらうのが、早いと思います。
基本的に、上から下に入力するのが、Accessだと思います。左右と上下に入力するのは、Excelみたいな何かでしょう。基本的に、持ち替え(根回し)を避けられないのがAccessだと思います。何も考えずに超スピードで入力出来るのは、Excel的な何かでしょう。
データモデリングがポンコツならば、遅かれ早かれ、不安定でどこかおかしいAccessになると思います。根回しがしっかりしていれば、AccessみたいなExcelがあってもおかしくないと思うのですが。
始めてみないとわからないと思いますよ?
テーブル作成、クエリ作成(テーブルのクエリ化)、フォーム作成(クエリのフォーム化)、集合形式から表形式に変更、高さ、上位置、左位置の微調整、単票フォームから帳票フォームに変更まで、頑張りましょう。
まず、テーブル作成ボタンを見つけて、データ型を選べますか?主キーのON/OFFを出来ますか?
次に、クエリ作成ボタンを見つけて、何をどうすればいいかわかりますか?テーブルを選んで、フィールドを選ぶだけですが。
最後に、フォームは、基本操作の解説動画を探して下さい。思い通りに移動させたり、大きくしたり小さくしたり、出来ますか?ワードやエクセルのように、雰囲気では無理です。
日付のプロパティ・・・・・既定値Date()
名コードのプロパティ・・・既定値ほにゃらら(数値型、短いテキスト型、既定値を決めて下さい。)
集計条件はいつ、どのように記録するのでしょうか?
品種コードですが、もしかして親テーブルから参照してきているのかしらと、私が早とちりしていました。ごめんなさい。
【解決】
リンゴ様
いつもありがとうございます!
教えて頂きましたコードで動作実現できました!!
「品名」に「品種コード」とリレーション・・・表現が間違ってました。
正しくは”両方とも同一テーブルで「品種番号」に入力したら「品名」に自動的に入力されるので・・・”でした。
紛らわしい表現をしてしまいすみませんでした。
早々のご回答ありがとうございました!
また、行き詰ったら宜しくお願いします。
お返事が遅くなってすみません。
ありがとうございます。
使えそうな時があったらぜひチャレンジしてみたいと思います。
具体例を挙げていただければそれに合わせて回答もできるんですがたとえば
のようなデータがあったとして請求書が
となるような場合なら
集計条件を記録するテーブルは
になります
ところで、これはどういう事でしょうか?
くわしい解説ありがとうございます
集計条件を記録するテーブルを用意、というのはどういったものですか?
理解できなくてすみません
前段階でクエリでデータを結合しておく、レポートにレポートを埋め込む仕組み(サブレポート)、VBAによる制御、等柔軟に対応する仕組みはあるので大抵のことはできますが、どの程度なら「かんたん」で済むのかは要件次第でしょう
ルールさえしっかりしていればできないことはないと思います。
ただ、請求書番号が未決定のレコードについて、新規で番号を取ればいいのか、集計で統合される別なレコードですでに決定されていないか、それらで請求書番号に矛盾がないか等の問題と対策が発生します。請求書番号は集計結果ごとの管理にしたほうが楽でしょう。
また、ちょっと難しい言い方になりますが、「印刷時に自動で請求書番号を決定するシステム」は難しいです。
プレビューで請求書番号を仮発行するのか、キャンセルした場合どうするのか、上記問題と合わせてどのような表示順にするのか
そして、これらを実現するための複雑な処理等、様々なことに悩まされることになります。
集計条件を記録するテーブルを用意してそこに条件を追加していけばいいです。集計結果自体は計算で求まるので記録する必要はないですし、そのテーブルに「請求書番号」フィールドを設ければ、集計結果の1レコードごとに「請求書番号」を管理することができます。
結局のところデータ構造自体はよくある「請求書」「請求明細」の構造と同じです。運用や作業性に合わせてどのようにシステムを組み込んでいくかという問題になると思います