Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


53 / 500 ページ ←次へ | 前へ→

【12255】Re:コンボボックス絞り込みで2つに所属...
回答  かるびの  - 13/1/25(金) 2:28 -

引用なし
パスワード
   >リレーションについてはある程度理解しており、絞り込みに生かすやり方がわかりません。
 問題点が拡散してきたような気がします。


 第1に、1人の人の所属は常に1つだけであるという前提の下で、
コンボボックスの連動はでき上がっているのでしょうか。
 つまり、大項目コンボボックスで所属Bを選択すると、
小項目コンボボックスのリストには、所属がBの人だけが表示される
ということは、できているのかということです。

 
 第2に、コンボボックスの連動ができているならば、
次なる問題は、大項目テーブルと小項目テーブルをどう対応させるか
ということになります。
 これを考える前提が、前回のレスにも書きましたが、
大項目テーブルと小項目テーブルの関係です。
 大項目テーブルと小項目テーブルの関係は、一対一、一対多、多対一、多対多の
どれになるのでしょうか。


 第3に、よくわからないのは、小項目テーブルの使われ方です。
 小項目コンボボックスの表示のためだけにしか使わないというのであれば、
   Aさん ID1
   Bさん ID1
   Bさん ID2 ←
   Cさん ID2
   Dさん ID4
というように、Bさんのレコードを2レコードにすれば済みます。
 しかし、小項目テーブルを大項目テーブル以外のほかのテーブル、
特にその都度データを入力させるテーブル(トランザクション・テーブル)と
結合させることもあるというならば、Bさんを重複させるわけにはいきません。
 小項目テーブルの使われ方はどっちなのでしょうか。


 第4に、テーブル構成を示すときには、
テーブル名、主キー、主要なフィールドのフィールド名、それらのデータ型
も示してくださいね。
・ツリー全体表示

【12254】Re:重複する値があるため主キーとして設...
回答  かるびの  - 13/1/25(金) 1:43 -

引用なし
パスワード
   >ですが、テーブルA(メインフォーム)に入力したコードをテーブルB(サブフォーム)のコードフィールドにに自動入力させるのは無理でしょうか?

 「コード」フィールドは、メインフォームとサブフォームをリンクさせるのには使わない
という前提ですよね。
 そうだとすると、一般機能に限定すると、ちょっと方法が思いつきません。


 VBAを使うならば、次のような方法はどうでしょうか。

 メインフォームの「コード」のテキストボックス(txtCodeMain)が更新されたときに、
サブフォームの「コード」のテキストボックス(txtCodeSub)の既定値プロパティに
txtCodeMainのValueプロパティの値を指定する。
・ツリー全体表示

【12253】Re:コンボボックス絞り込みで2つに所属...
発言  初心  - 13/1/24(木) 17:08 -

引用なし
パスワード
   返信ありがとうございます。
小項目テーブルのBさんがID1,2となっておりますが、
今回の投稿で、このような感じでやりたいという、視覚的に分かりやすくするための記述でした。
(すいません私の説明不足です。)
実際はまだ、2項目に該当する人がなく、1項目ですんでいる状態です。
近々やってくる事態に備えての質問でした。

リレーションについてはある程度理解しており、絞り込みに生かすやり方がわかりません。一項目の絞り込みは既に行っているのですが、VBAでもよろしいので、引き続き御回答お願い申し上げます。
・ツリー全体表示

【12252】Re:重複する値があるため主キーとして設...
質問    - 13/1/24(木) 16:37 -

引用なし
パスワード
   ▼かるびの さん:
こんにちは、いつもありがとうございます

テーブルBにテーブルAと同じA_IDを入力しましたところ、ちゃんと表示されるようになりました。
フォームで新しくデータを入力したらちゃんとテーブルBのA_IDに自動的に値が入ります

ですが、テーブルA(メインフォーム)に入力したコードをテーブルB(サブフォーム)のコードフィールドにに自動入力させるのは無理でしょうか?
関係ないとは思いましたがコード同志をリレーションしたり、いろいろやってみたのですけどできませんでした。
更新クエリの更新のところに、forms!サブフォーム!コード(コントロール名)とか書いてみたり。

フォームのコードのテキストボックスにはDLOOKUPで格納できますが、肝心要のテーブルBには値が入りません。
もう私の頭に負えないのでどうかお力をお貸しください。
・ツリー全体表示

【12251】Re:コンボボックス絞り込みで2つに所属...
回答  かるびの  - 13/1/24(木) 2:34 -

引用なし
パスワード
    小項目テーブルのBさんのID値を「1,2」のように入力したら、
データベースとしてまるで使い物にならなくなってしまいます。
 データベースでは、1セルにつき値は1つだけにします。
 このようにした状態を、第1正規形と言います。
 データベースでは、「テーブルを正規化しなければならない」とよく言われますが、
テーブルの正規化の第1歩目です。
 
 この観点からすると、
小項目コンボボックスのRowSourceとなるクエリ又はテーブルは、
   Aさん ID1
   Bさん ID1
   Bさん ID2 ←
   Cさん ID2
   Dさん ID4
という形になっている必要があります。

 ただ、小項目テーブルは、
おそらくは、氏名についてのマスタ・テーブルなのでしょうから、
Bさんのレコードが2つあるというのは、まずいですよね。
 そこで、一工夫する必要があります。
 
 その前提として、大項目テーブルと小項目テーブルの対応関係、
つまり、一対一か、一対多か、多対一か、多対多かということを
まず考えてみてください。

 私の体験では、この関係を考えるときは、頭で考えるだけでは不十分であり、
紙に図を書いて、各テーブルのレコードを結ぶ線を引いて考えないとダメでした。


 私がアクセスをいじりだして数年の間は、
テーブルの関係が一対一なのか、一対多なのかということを
全く考えなかったのですが、
近時、それをきちんと把握しないと進まないという事態に遭遇しました。
 テーブル相互の関係が一対一なのか、一対多なのかを把握することは
テーブル設計の基本のようです。
・ツリー全体表示

【12250】Re:重複する値があるため主キーとして設...
回答  かるびの  - 13/1/24(木) 1:56 -

引用なし
パスワード
   >やってみたのですが、サブフォームに何も表示されなくなってしまいました。
>テーブルBのA_IDに何も値が入っていないのですが、それが原因でしょうか?

 たぶんそのとおりだと思います。

 テーブルBの「A_ID」フィールドには、
対応するテーブルAの「A_ID」フィールドの値を格納してください。
・ツリー全体表示

【12249】Re:重複する値があるため主キーとして設...
回答    - 13/1/23(水) 16:34 -

引用なし
パスワード
   かるびの様

早速のご回答ありがとうございます

やってみたのですが、サブフォームに何も表示されなくなってしまいました。
テーブルBのA_IDに何も値が入っていないのですが、それが原因でしょうか?
・ツリー全体表示

【12248】Re:重複する値があるため主キーとして設...
回答  かるびの  - 13/1/23(水) 3:31 -

引用なし
パスワード
   >メインフォームのコードフィールドに1を入力し、その後サブフォームにデータを入力すると
>サブフォームに入力したデータのコードフィールドには自動的に1が入力されます
>これはテーブルAの主キーとテーブルBの主キーではないフィールドがリレーションされているため
>という認識であっていますでしょうか?

 私も素人なので、正確な知識がありません。そういう前提で読んでください。

 厳密に言うと、そのような認識は間違っていると思います。
 上記のようになるのは、リレーションシップを設定しているからではなく、
メイン/サブフォームだからそうなるのです。
 リレーションシップを外してしまっても、同じように動くはずですから、
リレーションシップとは関係ありません。
 つまり、「リレーションされている」という言葉を使った点で
間違っていると思います。


>同じコードが重複するため主キーに設定できないため使えません。(これも認識正しいでしょうか?)
 これは、まさにそのとおりです。
 主キーの値は、他のレコードと同じ値を持つことはできません。


>何か良い方法はないでしょうか?
 普通に両テーブルを結合させるフィールドを設けるだけです。

 まず、テーブルAに主キーを設ける必要があります。
 テーブルAの「コード」フィールドが主キーになれないことは、
巻さんの仰るとおりです。
 そこで、例えば、オートナンバー型の「A_ID」フィールドを設け、
これを主キーにします。
「A_ID」というのはテーブルAのIDという意味です。
テーブルBの「ID」フィールドと混同しないようにするため、
フィールド名をちょっと変えます。

 次にテーブルBに「A_ID」フィールドを設けます。こちらは長整数型にします。

 リンク親フィールドとリンク子フィールドには「A_ID」フィールドを指定します。


 蛇足ですが、テーブルAの主キー「A_ID」フィールドを設けた場合、
テーブルBには、「コード」フィールド、「日にち」フィールド、
「部署」フィールドを設ける必要がなくなりますね。
・ツリー全体表示

【12247】重複する値があるため主キーとして設定で...
質問    - 13/1/22(火) 16:06 -

引用なし
パスワード
   こんにちは、いつもお世話になってすみません
基本的な質問ですがよろしくお願いします

テーブルA
コード テキスト型・・・・主キー
日にち 日付/時刻型
部署コード 数値型
記事 メモ型

テーブルB
ID オートナンバー型・・・・主キー
コード テキスト型
日にち 日付/時刻型
部署コード 数値型
商品コード 数値型
数量 数値型
備考 メモ型

テーブルA(一)テーブルB(多)
でリレーションシップされていて
参照整合性とフィールドの連鎖更新にチェックが入っています

メインフォームのレコードソースが テーブルA
サブフォームのレコードソースが テーブルB
サブフォームのリンク親フィールド子フィールドはコード

メインフォームのコードフィールドに1を入力し、その後サブフォームにデータを入力すると
サブフォームに入力したデータのコードフィールドには自動的に1が入力されます
これはテーブルAの主キーとテーブルBの主キーではないフィールドがリレーションされているため
という認識であっていますでしょうか?

とても便利なフォームなので使ってみたいと思ったのですが、
私がいま使っているファイルは年度初めにコードがリセットされ1に戻るため
同じコードが重複するため主キーに設定できないため使えません。(これも認識正しいでしょうか?)

ほかに
テーブルAにもIDフィールドを作ってみてこれをつないだらどうか?と思ったのですが1レコード1IDの為使えませんでした。

何か良い方法はないでしょうか?
・ツリー全体表示

【12246】コンボボックス絞り込みで2つに所属する...
質問  初心 E-MAIL  - 13/1/22(火) 0:53 -

引用なし
パスワード
   いつもお世話になっております。
色々、調べてみたのですが、回答を見つける事が出来なかったため、何卒、御指導お願い申し上げます。

テーブル2つをIDでつなげて、フォーム上に絞り込みコンボボックスを作成致しました。
Bさんが所属Aにも所属Bにも該当するため、大項目コンボボックスで所属Aと所属Bを選択したときのどちらにも小項目コンボボックスにBさんを出現させるためにはどのようにすればよろしいのでしょうか?よろしくお願い致します。

大項目テーブル
所属A ID1
所属B ID2
所属C ID3
所属D ID4

小項目テーブル
Aさん ID1
Bさん ID1,2
Cさん ID2
Dさん ID4
・ツリー全体表示

【12245】Re:レポート
お礼  Sam  - 13/1/21(月) 12:17 -

引用なし
パスワード
   ▼かるびの さん:

クロス集計について教えてくださりありがとうございました。

本日ようやく試すことができ、
教えていただいたようにテーブルを一本化し、クロス集計クエリで思っていた形が出ています。
レポート作成の際には抽出した参加日のみにしたいのでもう少し完成まで時間がかかりそうですが、何とか形が見えてきた気がします。
ありがとうございました!


>>セミナーA出席リスト
>>    B C D
>>1氏名 □ □ □
>>2氏名 □ □ □
>>3氏名 □ □ □
>
>>このようなリストを作ることは可能でしょうか?
>
> クロス集計クエリですね。
>
> ただし、現状のテーブル構成では難しいでしょう。
>
> まず、テーブルは、次のようなものである必要があります。
>    氏名   出席セミナー 
>    山田     A    
>    山田     C    
>    山田     D    
>    田中     B    
>    田中     D    
>    川村     C    
>    海野     A    
>    海野     B    
>      (正規化されていない点は御容赦)
>    
> ここから、次のようなクエリ(クエリA)を作ります。 
>   氏名   出席セミナー 集計のための値
>   山田     A     True
>   山田     C     True
>   山田     D     True
>   田中     B     True
>   田中     D     True
>   川村     C     True
>   海野     A     True
>   海野     B     True     
>
> さらに、クエリAを元にして、
>出席セミナーがAであるものを抽出したクエリBを作ります。
> 最後に、クエリBからクロス集計クエリを作ります。
>集計値はFirstあたりになると思います。
>
>
> とはいえ、クロス集計は使ったことが数えるほどしかなく、
>レポートもあまり使わないので、
>ちょっと突っ込まれると、答えられなくなってしまいます。
・ツリー全体表示

【12244】Re:レコードの検索
お礼    - 13/1/10(木) 12:52 -

引用なし
パスワード
   かるびの様

おかげさまで、下記コードでうまくいきました
Private Sub コマンド1_Click()

Dim myRec As DAO.Recordset
Dim strJoken As String
If IsNull(Me!指定コード.Value) Then
MsgBox "コードを指定下さい"
Exit Sub
Else

Set myRec = Forms!フォームA.RecordsetClone
strJoken = "Year(日付) =" & Me!指定年度.Value & "" & " And " & "コード =" & Me!指定コード.Value & ""
'Debug.Print strJoken
myRec.FindFirst strJoken
'Debug.Print myRec("コード")

If myRec.NoMatch Then
MsgBox ("ない")
Else
Forms!フォームA.Bookmark = myRec.Bookmark
End If
End If
End Sub

ネットで調べてみたのですが、最初にイミディエイトウインドウに出ていたFalseは、私の書いたコードが比較式と判断されて、当然=ではないからFALSEと出ていたのですね。で、式自体はエラーではないと。
長々と訳の分からないことを書いて申し訳ありませんでした。
また何かありましたら、この掲示板にお邪魔すると思いますが
よろしくお願いします。
・ツリー全体表示

【12243】Re:レコードの検索
質問    - 13/1/10(木) 9:46 -

引用なし
パスワード
   ▼かるびの さん:
ご回答ありがとうございます。
長々とお付き合いいただき申し訳ないです

>strJoken = Year(日付) = Me!指定年度.Value And コード = " & Me!指定コード.Value"
>
> 本当にこのコードですか。
> もし、このコードのままであれば、この行でエラーになるはずです。

本当にそのコードなのです。
strJokenに格納された値はFalseになっています
最初にTrueかFalseが帰るとのことなので
値がヒットしないという意味なのかなとつまり
ないというメッセージと同じ意味だと思ってスルーしてました。
もしかしてエラーというのはこのことですか?
・ツリー全体表示

【12242】Re:レコードの検索
回答  かるびの  - 13/1/10(木) 1:25 -

引用なし
パスワード
   >strJoken = Year(日付) = Me!指定年度.Value And コード = " & Me!指定コード.Value"

 本当にこのコードですか。
 もし、このコードのままであれば、この行でエラーになるはずです。

 また、strJokenに格納された値はどうなっていますか。
 目指すべき文字列となっていますか。
 そのためのイミディエイト・ウィンドウですよ。


 コードを1行ずつ実行させて、strJokenに然るべき値が格納されているかなど
チェックしつつ、確認してみましょう。
・ツリー全体表示

【12241】Re:レコードの検索
質問    - 13/1/9(水) 13:31 -

引用なし
パスワード
   先ほどはお騒がせしてすみませんでした。
あれからいろいろ直して下記のようにしたら
とりあえずエラーはでなくなりました。

Dim myRec As DAO.Recordset
Dim strJoken As String
If IsNull(Me!指定コード.Value) Then
MsgBox "コードを指定して下さい"
Exit Sub
Else

Set myRec = Forms!フォームA.RecordsetClone
strJoken = Year(日付) = Me!指定年度.Value And コード = " & Me!指定コード.Value"
Debug.Print strJoken
myRec.FindFirst strJoken

If myRec.NoMatch Then
MsgBox ("ない")
Else
Forms!フォームA.Bookmark = myRec.Bookmark
End If
End If
End Sub

ですが、実際に走らせると実在する年度とコードが存在するにもかかわらず
ない とメッセージが出て終わってしまいます。
年度を年度、コードをコードと認識してないのでしょうか
・ツリー全体表示

【12240】Re:レコードの検索
発言    - 13/1/9(水) 12:59 -

引用なし
パスワード
   ▼かるびの さん:
何度も何度も申し訳ありません
先ほどのコードは間違ってませんでした
私がテキストボックスに値を入れてないので空白になっていただけでした
ただ、値がないとエラーが出るようなので、作り直しています。
今直しています。お騒がせして申し訳ありませんでした。
・ツリー全体表示

【12239】Re:レコードの検索
質問    - 13/1/9(水) 11:35 -

引用なし
パスワード
   ▼かるびの さん:
こんにちは、ご回答ありがとうございます

Dim myRec As DAO.Recordset
Dim strJoken As String

Set myRec = Forms!フォームA.RecordsetClone
strJoken = "日付 =#" & Me!指定年度.Value & "# And コード =" & Me!指定コード.Value & ""

Debug.Print strJoken
myRec.FindFirst strJoken

If myRec.NoMatch Then
MsgBox ("ない")
Else
Forms!フォームA.Bookmark = myRec.Bookmark
End If
End Sub

としました。すると3077演算子がありません、と出ました。

イミディエイトウインドウ便利ですね
日付はちゃんと日付 =#2012/04/01# と出ていて、コード=の後が空白になっているので、どうやらこちらが間違ってるようです

なかなか難しいです

> 次に、「指定年度」テキストボックスです。
> この命名からすると、日付が入るのではなく、
>例えば「2013」のような数値が入力されるように思えるのですが、
>どうなのでしょうか。
> もし、「2013」のような数値が入力されるならば、例えば
>   "Year(日付)=2013 AND コード=123"
>のようにする必要があります。 

これは確かにそうなんですが、そこまでやるとややこしいので、まずフィールドに入っている値そのままで、後で直そうと思っていました。
・ツリー全体表示

【12238】Re:レポート
回答  かるびの  - 13/1/9(水) 3:37 -

引用なし
パスワード
   >セミナーA出席リスト
>    B C D
>1氏名 □ □ □
>2氏名 □ □ □
>3氏名 □ □ □

>このようなリストを作ることは可能でしょうか?

 クロス集計クエリですね。

 ただし、現状のテーブル構成では難しいでしょう。

 まず、テーブルは、次のようなものである必要があります。
    氏名   出席セミナー 
    山田     A    
    山田     C    
    山田     D    
    田中     B    
    田中     D    
    川村     C    
    海野     A    
    海野     B    
      (正規化されていない点は御容赦)
    
 ここから、次のようなクエリ(クエリA)を作ります。 
   氏名   出席セミナー 集計のための値
   山田     A     True
   山田     C     True
   山田     D     True
   田中     B     True
   田中     D     True
   川村     C     True
   海野     A     True
   海野     B     True     

 さらに、クエリAを元にして、
出席セミナーがAであるものを抽出したクエリBを作ります。
 最後に、クエリBからクロス集計クエリを作ります。
集計値はFirstあたりになると思います。


 とはいえ、クロス集計は使ったことが数えるほどしかなく、
レポートもあまり使わないので、
ちょっと突っ込まれると、答えられなくなってしまいます。
・ツリー全体表示

【12237】Re:レコードの検索
回答  かるびの E-MAIL  - 13/1/9(水) 2:54 -

引用なし
パスワード
   >myRec.FindFirst "日付 =#" & Me!指定年度.Value & "# " And "コード =" & Me!指定コード.Value & ""

 まず、FindFirstメソッドの引数として目指すべき文字列は、例えば、
   "日付 = #2012/01/08# AND コード = 123"
という文字列です。

 「AND」の周囲によく注意してみてください。


 次に、「指定年度」テキストボックスです。
 この命名からすると、日付が入るのではなく、
例えば「2013」のような数値が入力されるように思えるのですが、
どうなのでしょうか。
 もし、「2013」のような数値が入力されるならば、例えば
   "Year(日付)=2013 AND コード=123"
のようにする必要があります。 

 
 最後に、蛇足ですが、
FindFirstメソッドの引数は、いったん変数に代入し、
変数を引数に指定した方がデバッグが楽です。

>Dim myRec As DAO.Recordset
Dim strJoken as String    

>Set myRec = Forms!フォームA.RecordsetClone
strJoken = "コード =" & 指定コード.Value
Debug.Print strJoken
myRec.FindFirst strJoken

 「Debug.Print strJoken」というコードにより、
変数strJokenに格納された文字列がイミディエイト・ウィンドウに表示される
ので、デバッグがより楽になります。
 きちんと動くことが確認できたら、
「Debug.Print strJoken」のコードは、消すか、コメントにします。
・ツリー全体表示

【12236】Re:レコードの検索
質問    - 13/1/8(火) 16:06 -

引用なし
パスワード
   ▼かるびの さん:

Dim myRec As DAO.Recordset

Set myRec = Forms!フォームA.RecordsetClone
myRec.FindFirst "日付 =#" & Me!指定年度.Value & "# " And "コード =" & Me!指定コード.Value & ""

If myRec.NoMatch Then
MsgBox ("ない")
Else
Forms!フォームA.Bookmark = myRec.Bookmark
End If

End sub

と書き換えましたら前よりはましになりました
エラーが"型が一致しません" になりました(全然ましではないか)

かるびのさんのご指摘に
FindFirstメソッドの引数は、条件式を文字列として指定します
とありましたが、私のコードでは
条件式が文字列として指定されていないということでしょうか
・ツリー全体表示

53 / 500 ページ ←次へ | 前へ→
ページ:  ┃  記事番号:
1078299
(SS)C-BOARD v3.8 is Free