Microsoft Access 掲示板

views
4 フォロー
6,283 件中 4,921 から 4,960 までを表示しています。
2

複数の選択肢に情報をつなげる方法 Microsoft Access 掲示板 - zawazawa
で提示されているテーブルと同じものかな?

だとしたら、データベース設計のセオリーとしては、正規化しましょう、ということになりますね。

正規化については、下記のページの「4.正規化」の項目を読んで学習してください。
もう一度学ぶMS-Access

具体的には下記のようにテーブルを分割します。

●T会社
会社ID 主キー
会社名
会社備考
・・・

●T商品
商品ID 主キー
商品名
単価
・・・

●T取扱商品
会社ID 主キー
商品ID 主キー

複数のフィールドに主キーを設定する方法は下記を参照。

複数のフィールドの組み合わせで重複がないようにする - hatena chips

リレーションシップで、同じ名前のフィールド同士結合しておきます。

リレーションシップの設定と効果 - もう一度学ぶMS-Access

T会社とT取扱商品を結合したクエリをレコードソースとする帳票フォームを作成します。

T商品をレコードソースとする単票フォームに、上記のフォームをサブフォームとして埋め込みます。
サブフォームのリンク親フィールド、リンク子フィールドは「会社ID」と設定します(リレーションシップの結合にあわせて自動で設定される場合もあり)

このフォームから、商品を見ながら、扱っている会社名のリストもサブフォームで見れます。また、サブフォームで取り扱い会社を追加することもできます。

逆に、
T商品とT取扱商品を結合したクエリをレコードソースとする帳票フォームを作成します。

T会社をレコードソースとする単票フォームに、上記のフォームをサブフォームとして埋め込みます。
サブフォームのリンク親フィールド、リンク子フィールドは「商品ID」と設定します。

このフォームからは、会社情報を見ながら、扱っている商品のリストもサブフォームで見れます。また、サブフォームで取り扱い商品を追加することもできます。

このような設計にしておけば、取り扱い商品や取り扱い会社の数に制限なくいくらでも追加できます。

1

現状のテーブル名と、そこに含まれるフィールド名、主キーフィールド、を提示してもらえますか。

4
どんぐり 2020/08/12 (水) 17:29:38 0029a@1c915 >> 1

教えていただいた方法でうまくいきました!色々方法がありますね。ありがとうございます。

3
どんぐり 2020/08/12 (水) 17:28:07 0029a@1c915 >> 2

うまくいきました!""の使い方がまだよく理解できておらず、助かりました。ありがとうございます。

2
kitasue 2020/08/12 (水) 17:01:35 ce705@e9d43
=DLookUp("会社備考","T会社","会社ID='" & [会社1] & "'")
=DLookUp("会社備考","T会社","会社ID='" & [会社2] & "'")

としては、いかがでしょうか。

1

ID, パスワードが一致したらフォームを開く - hatena chips

上記で紹介したものてすね。

とりあえずサンプルを作成してみました。下記のリンクからダウンロードできます。
参考にしてください。

FrmRogIn2.zip

1
hiroton 2020/08/12 (水) 15:11:29 5a62e@f966d

エラーはどのような間違いをしているのかを教えてくれる大事なものなのでエラーの内容も提示しましょう

見た感じ間違いがあるように見えませんが、よくあるパターンとしては会社IDがテキスト型であるとか

そもそもクエリ上でやりたいのなら「T会社」テーブルを2回入れてしまうのが良いです
クエリデザインでテーブルの表示から「T会社」を2回選ぶと、一つ目は「T会社」、二つ目は「T会社_1」となります
「T商品」の「会社1」と「T会社」の「会社ID」、「T商品」の「会社2」と「T会社_1」の「会社ID」を紐づけて上げれば
備考1:[T会社].[会社ID]
備考2:[T会社_1].[会社ID]
で望みの結果になります

7
hiroton 2020/08/11 (火) 08:24:04 60b00@f966d >> 6

自分なら、だと

入力フォームは、フォームヘッダーにコンボボックスかラジオボタンを配置しておいて、運転日報か出勤簿か選択できるようにして

メニュー画面で「出勤簿」「運転日報」それぞれのボタンを用意して入力フォームを開いたときに規定値を弄るとか、ですかね

3

どのコードでエラーはでますか。

当方のサンプルでの実験では問題なく実行できました。

2
オートナンバー 2020/08/08 (土) 18:52:53 3d629@e87f3 >> 1

アドバイスありがとうございます。
テストしてみましたがエラーのままでした。

マクロで以下のプロシージャの実行
オートナンバー型初期化("TEST3","ID")
※前後これ以外の処理はありません。

テーブルTEST3に定義しているフィールド名IDは以下の設定になっています。
データ型オートナンバー型
フィールドサイズ 長整数型
新規レコードの値 インクリメント
インデックス   いいえ
文字配置     標準

ローカル変数のSQLは以下のようになっていました。
"Alter Table [TEST3] Alter Column [ID] Counter(1,1)"

2
かえる 2020/08/08 (土) 17:37:11 8e098@f9b2c

連投すみません
新しいファイルでやり直したら問題なくできました

原因はわかりませんが、できなかったファイルでは
レイアウトビュー レポートビューで、一切レコードが表示されていませんでした
なにかのプロパティをいじってしまったのでしょうか?
正常なものと見比べましたがどこに違いがあるかわかりませんでした

1
かえる 2020/08/08 (土) 17:29:34 8e098@f9b2c

何度も印刷プレビューとデザインビューを切り替えていると
”印刷時縮小 はい”で入力したレコードが表示される場合があるようですが
印刷するとレコードは表示されていませんでした

またすべてのレコードに余計な空白行が挿入されています

17

データ数が多くて処理が重く感じた時点で、インデックスを付けることを検討するということでもいいです。
インデックスとは、百科事典・学術書などの最後についている索引のようなものと考えればいいでしょう。
それが、あると検索や抽出が高速になります。

16
セロハン 2020/08/08 (土) 10:06:09 0029a@1c915 >> 12

内容確認しました!とても勉強になりました。
「抽出条件でインデックスが無効になる場合」につきましては、また新しい知識なので勉強したいと思います。インデックスもいまいち理解できていなかったので貴重なお話をありがとうございます。

1
セロハン 2020/08/08 (土) 08:23:39 0029a@1c915

すみません…コンボボックスを左寄せ設定したら解決できました。(右寄せ設定になっていたわけではないので、原因は結局不明ですが…)お騒がせしました

15
cerophan 2020/08/08 (土) 07:44:28 0029a@1c915 >> 12

とても丁寧な解説、本当にありがとうございます。じっくり読み解きたいと思います。心から感謝申し上げます。

6

フィールドを同じにする場合、下記のようなフィールド構成にする。

開始時刻 日付/時刻型
終了時刻 日付/時刻型
運転日報 Yes/No型

レポートの設計は、
出勤簿も運転日報も 開始時刻、終了時刻 をコントロールソースにすればよい。
ラベルの標題を出勤簿なら、出勤時間、退勤時間 に、
運転日報なら、開始点呼時間、終了点呼時間 にすればよい。

出勤簿と運転日報のレイアウトが同じでラベルの標題だけが違うのなら、
ラベルをテキストボックスに変換して、コントロールソースを下記のようにすれば一つのレポートでどちらでも使えます。

=IIf([運転日報],"開始点呼時間","出勤時間")

=IIf([運転日報],"終了点呼時間","退勤時間")


入力フォームは、フォームヘッダーにコンボボックスかラジオボタンを配置しておいて、運転日報か出勤簿か選択できるようにして、「運転日報」フィールドに対してフィルターをかけて対象レコードを表示するようにする。
あるいは、メイン/サブフォーム形式にしてもいいでしょう。

ラベルはレポートの同様にテキストボックスにすればいいでしょう。

自分なら上記のような設計にします。

14

サンプルの解説

テーブル T_案件 に 日付/時刻型の「年月日」フィールドがある。
「年月日」は未入力(NUll)のレコードもある。

上記のテーブルから帳票フォームを作成する。
フォームヘッダーにコンボボックスを「cbo年月」を配置する。

値集合ソース

SELECT DISTINCT
 Format(Format([年月日],"yyyy/mm"),"&;""(空欄)""") AS 年月,
 [年月日] Is Null AS N
FROM T_案件
ORDER BY 2, 1 DESC; 

テーブルに未入力のレコードが存在するのでユニオンクエリにする必要はなかったです。
Format([年月日],"yyyy/mm") で年月日を年月に変換、
さらに Format(・・・,"&;""(空欄)""") をかぶせることで、Nullを(空欄)に変換。

(空欄)を先頭に持ってくるようにするために、[年月日] Is Null AS N というフィールドを追加

ORDER BY 2, 1 DESC;
の数字は何列目かを指定しています。下記と同じ意味になります。
ORDER BY [年月日] Is Null, Format(Format([年月日],"yyyy/mm"),"&;""(空欄)""") DESC;
フィールドの式が長いときは簡略化できるので便利です。


cbo年月の更新後処理のイベントプロシージャ

Private Sub cbo年月_AfterUpdate()
    If Nz(Me.cbo年月) = "" Then
        Me.Filter = ""
        Me.FilterOn = False
    ElseIf Me.cbo年月 = "(空欄)" Then
        Me.Filter = "年月日 Is Null"
        Me.FilterOn = True
    Else
        Me.Filter = "年月日>=#" & Me!cbo年月 & "# AND 年月日<#" & _
                     DateAdd("m", 1, Me!cbo年月) & "#"
        Me.FilterOn = True
    End If
End Sub

cbo年月 が未選択の時は全件表示、
"(空欄)"を選択したときは年月日が空欄のレコードを抽出、
年月を選択したときは、その年月のレコードを抽出。

年月でフィルターをかける時、
Me.Filter = "Format([日付],"yyyy/mm")='" & Me!cbo年月 & "'"
とした方がコードは短くなるが、インデックスが無効になるので、処理を軽くしたい場合は上のコードのように年月日フィールドに直接条件を設定するようにしたほうがよい。
詳細は下記参照。

抽出条件でインデックスが無効になる場合 - hatena chips

5

レポートレイアウトのテクニックになるのかもしれませんが
出勤簿の提出があったとき
レポートには出勤時間や退勤時間レベルフィールドを配置したものにしますが
運転日報で入力したレコードに関してはその項目に値がないので
フラグでいずれかのフィールドを表示させるとかでしょうか?

13

簡単なサンプルを作成してみました。
下記のリンクでダウンロードできます。

案件管理.zip

12
cerophan 2020/08/07 (金) 23:19:54 0029a@1c915 >> 10

何度も連投してしまい、申し訳ありません。自己解決する度、お答えする手間をかけないようにと思って都度都度投稿してしまっておりました…
現状のファイルをお送りしたい気持ちは山々なのですが、難しい状況です。
お言葉、ありがとうございます。

今回の件は、下記で解決とすることにしました。
大変お騒がせしました。

★降順にしていたものを昇順としたが、その他の問題は解決。
【値集合ソース】
SELECT DISTINCT "(空欄)" AS 年月
FROM T_案件
WHERE (((T_案件.年月) Is Null))
UNION SELECT DISTINCT T_案件.年月
FROM T_案件
WHERE (((T_案件.年月) Is Not Null));

11
cerophan 2020/08/07 (金) 22:57:47 0029a@1c915 >> 9

【VBA】すみません・・修正しました。

Private Sub cbo年月_AfterUpdate()

    If Me.cbo年月 = "(空欄)" Then
        Me.Filter = "年月 Is Null"
        Me.FilterOn = True
    Else

        Me.Filter = "年月 ='" & Me!cbo年月 & "'"
        Me.FilterOn = True
    End If
End Sub

★残り問題点
①(空欄)が選択肢の一番下に表示されるのを一番上に持ってきたい
②選択肢の中に空のものがあるのを表示しないようにしたい。

10

現状のファイルを送信フォームから送ってもらった方が速そうです。

9
cerophan 2020/08/07 (金) 21:59:18 0029a@1c915

修正しました!
しかし、まだ問題点が残っています。

①年月がなぜか選べなくなった。(選択すると表示されるレコードが0になる)
②(空欄)の選択肢を一番上に持ってくる方法がわからない。

【VBA】
Private Sub cbo年月_AfterUpdate()

    If Me.cbo年月 = "(空欄)" Then
        Me.Filter = ""
        Me.FilterOn = True
    Else
        Me.Filter = "年月=" & Me.cbo年月
        Me.FilterOn = True
    End If
End Sub

【値集合ソース】
SELECT DISTINCT "(空欄)" AS 年月
FROM T_案件
WHERE (((T_案件.年月) Is Null))
UNION SELECT DISTINCT 年月
FROM T_案件
ORDER BY 年月 DESC;

★下記のVBAにすると、きちんと絞り込み表示ができます。
Private Sub cbo年月_Click()
    DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub

1

いろいろ方法はありますが、一例を紹介しておきます。

フォームウィザードで入力したいテーブルをもとに単票フォームを作成します。
フォームプロパティを下記のように設定します。

プロパティ設定値
フィルターFalse
読み込み時にフィルターを適用はい
追加の許可いいえ
 

「日付」のテキストボックスの「使用可能」は「いいえ」にします。

フォームヘッダーにテキストボックスを配置して下記のように設定します。

プロパティ設定値
名前txt日付
書式yyyy/mm/dd
(書式はお好みの日付書式に)

txt日付更新後処理のイベントプロシージャを下記のように記述します。

Private Sub txt日付_AfterUpdate()
    If IsDate(Me.txt日付.Value) Then
        Me.Filter = "日付=#" & Me.txt日付.Value & "#"
        Me.FilterOn = True
        If Me.Recordset.RecordCount = 0 Then
            Me.日付.DefaultValue = "=#" & Me.txt日付.Value & "#"
            Me.AllowAdditions = True
        End If
        Me.項目1.SetFocus
    End If
End Sub

 
フォームの挿入後処理のイベントプロシージャを下記のように記述します。

Private Sub Form_AfterInsert()
    Me.AllowAdditions = False
End Sub

以上です。

4

同じでも、分けても、どちらでもOKです。

労基などに提出する統一された出勤簿が同じ欄なら同じで、異なる欄なら別に、というように用途に合わせて使いやすいように設計すればいいでしょう。

3

テーブルを分けない場合
開始点呼時間 終了点呼時間 と
出勤時間 退勤時間 を
それぞれ同じフィールドにするということですか?

1

とりあえずコードは下記に修正してみてください。

Function オートナンバー型初期化(テーブル As String, フィールド As String, Optional 初期値 = 1) As Boolean
    On Error GoTo エラー
    DoCmd.Close acTable, テーブル
    Dim SQL AS String
    SQL = "Delete from " & テーブル
    CurrentDb.Execute SQL

    SQL = "Alter Table [" & テーブル & "] Alter Column [" & フィールド & "] Counter(" & 初期値 & ",1)"
    CurrentDb.Execute SQL
    オートナンバー型初期化 = True
    Exit Function
エラー:
    MsgBox Error, vbCritical, Format(Err, "エラー番号 0")
End Function

修正前のコードだとテーブル名やフィールド名に空白や記号が含まれるとエラーになる場合がありますので、その対策を追加しました。

それてもエラーになるなら、この関数を呼び出す前後のコードを提示してください。

8
cerophan 2020/08/07 (金) 08:47:08 0029a@1c915 >> 7

上記は、値集合ソースとvbaに入力しているものです。

5
cerophan 2020/08/07 (金) 08:45:37 0029a@1c915 >> 4

詳しいご解説ありがとうございます。コントロールソースを指定しておりませんでした。大変お手数をおかけいたしました。うまくいきました!ありがとうございます。

7
cerophan 2020/08/07 (金) 08:37:07 0029a@1c915

下記作成しましたが、何を選択してもなにも表示されない状態になりました。
また、コンボボックス内に空白の選択肢ができてしまいます。

SELECT "(すべて)" AS 年月
FROM T_案件
UNION SELECT 年月
FROM T_案件;

'年月選択 更新後処理
Private Sub cbo年月_AfterUpdate()
    If Me.cbo年月 = "" Then
        Me.Filter = ""
        Me.FilterOn = True
    Else
        Me.Filter = "年月=" & Me.cbo年月
        Me.FilterOn = True
    End If
End Sub

4
hiroton 2020/08/07 (金) 08:36:07 bf850@f966d

「cbo種類」はフォーム上のコントロールの名前で、コントロールソース名とは別ですか?

カウントに使えるフィールドはレコードソースのフィールドなので、cbo種類のコントロールソース名を指定してあげてください


条件判断についても実際のデータに対して行うので、コンボボックスで目に見える表示と連結列が異なる場合は連結列の値で条件判断をしてあげる必要があります。「特別」や「通常」が直接テーブルに保存される値ならそのままで大丈夫です

追加で試された「=Count(IIf([txt価格]="1,000",1))」は「=Count(IIf([価格]=1000,1))」のような形なら動くと思います

6
cerophan 2020/08/07 (金) 07:56:29 0029a@1c915 >> 5

あ・・わかりました、
上記SQLをcbo年月に入れて、下記をVBAに入れています。
これが、②に対応できていないんですね・・もう少し考えてみます。

Private Sub cbo年月_Click()
    DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub

3
cerophan 2020/08/07 (金) 07:50:24 0029a@1c915 >> 1

テキストボックスに上記式を入れたのですが、「#エラー」と表示されます。
ためしに「=Count(IIf([txt価格]="1,000",1))」など、他のフィールドでも試してみたのですが、「#エラー」と出ました…。何か原因になりうるものがありますでしょうか。

5
cerophan 2020/08/07 (金) 00:12:02 0029a@1c915

こちらの件、ずっと解決できず課題になっていました。
下記sqlを作ったのですが、うまくいきません…なぜでしょうか…
①元のデータが降順にならない。
②すべてが表示されない。

SELECT DISTINCT T_案件.年月
FROM T_案件
ORDER BY T_案件.年月 DESC
UNION
SELECT "(すべて)" AS 案件NO FROM T_案件;

2
cerophan 2020/08/06 (木) 17:22:58 f1ed8@29cdf >> 1

ありがとうございます!のちほど試してみます!

1
hiroton 2020/08/06 (木) 16:06:25 ce719@f966d

どのように表示したいですか?

フォームで見えてる分だけで集計したいならCount()関数で
Count()関数は、指定したフィールドの「Null」のデータをカウントしないのでIIf()関数を使って数えたいものだけデータを出力するようにすればそれぞれで件数を出すことはできます
ex)

=Count(IIf([cbo種類]="特別",1))
2
cerophan 2020/08/06 (木) 14:25:10 0029a@1c915

大変参考になりました。クエリの件も、見直してみたいと思います。ありがとうございました。

1

人それぞれの考え方があると思いますが、私は結合するフィールド同士は同じ名前にしています。

クエリにするとき、通常は、一対多の関係のテーブルを結合しますが、クエリに表示させるのは、多側のフィールドにします。
それを両方表示させたり、* で全フィールドを表示させたりすると、同じ名前のフィールドが存在するので、コントロールソースなどで参照するとエラーになります。
ですので、両方表示させることがないように設計すれば問題ないです。
もし、両方表示させる必要がある場合(通常はないですが)は、片方のフィールドに別名を付ければ問題ないです。

2

労基などに提出するときに、統一された出勤簿である必要があるので

ということなら、hirotontさんも言われてますか、そもそも分ける必要がないと思います。

その統一された書式でテーブルを作成して(両方に必要なフィールドをすべて持たせる)、そこに入力していけばいいのでは。
あとは、運転日報かどうかを識別するフィールド(Yes/No型)を追加して、運転日報のみ必要な時に、そのフィールドで抽出をかければいいだけです。