TRANSFORM IIf(Count([資格パターン].[パターンCD])=3,400,0) AS 加算手当金
SELECT 作業員所持資格.作業員CD, Sum(作業員所持資格.金額) AS 手当金計
FROM 作業員所持資格 LEFT JOIN 資格パターン ON 作業員所持資格.資格CD = 資格パターン.資格CD
GROUP BY 作業員所持資格.作業員CD
PIVOT 資格パターン.[パターンCD] In (1,2,3,4,5);
SELECT 作業員CD
, Sum( total ) As 金額
FROM
(
SELECT 作業員CD
, Sum( 金額 ) As total
FROM t_資格計算
GROUP BY 作業員CD
UNION ALL
SELECT 作業員CD
, Count(1) * 400
FROM
(
SELECT x.資格GRP
, x.作業員CD
FROM
(
SELECT 資格GRP
, 資格CD
, 作業員CD
FROM t_資格グループ,
( SELECT DISTINCT 作業員CD FROM t_資格計算 ) tmp
) x
LEFT JOIN t_資格計算 y
ON x.作業員CD = y.作業員CD AND
x.資格CD = y.資格CD
GROUP BY x.資格GRP
, x.作業員CD
HAVING Count(1) = Count( y.作業員CD )
) q_plus
GROUP BY 作業員CD
) q_union
GROUP BY 作業員CD
ORDER BY 作業員CD
;
hatenaさん ありがとうございます。
恥ずかしながらブレークポイントを設定してステップ実行のデバッグはしたことがないのです。
ブレークポイント付けてからはどう進めるといいでしょうか?
今回の場合 DoCmd.Close acForm, Me.Nameの前には下記プロシージャだけですのでどこにポイント付けたらいいでしょうか? ステップ実行はどう実行させたらいいでしょうか?
Public Function proSubCk() As Boolean
If Not IsNull(Me.[受注ID]) And Me!F受注Sub.Form.RecordsetClone.RecordCount = 0 Then
MsgBox "受注内容の入力がありません。" & vbNewLine & "入力途中では実行出来ません。"
Me.[受注日付].SetFocus
proSubCk = False '戻り値設定
Exit Function
End If
proSubCk = True '戻り値設定
End Function
大変初歩的な事ですみません。
Private Sub 詳細_Print(Cancel As Integer, PrintCount As Integer)
' As Integerは変数毎につける必要がある 省略するとVariant型になる
Dim p1 As Integer, p2 As Integer, p3 As Integer, p4 As Integer
Dim ht1 As Integer
p1 = Me.直線21.Left
p2 = Me.直線20.Left
p4 = Me.s_koment.Top
ht1 = Me.s_koment.Height
Me.Line (p1, p4 + ht1)-(p2, p4 + ht1)
End Sub
何も考えずにレス付けるんですが400ってリテラルもデータベース化できないですかね?
この固定条件ならこちらの方が私のよりシンプルでいいですね。
mayuさんの最初のSQLだと、パターン数やパターン内件数が固定でなくても対応できるのでより対応範囲が広いですね。
という要件を全て満たす場合は、以下のSQLでもご希望の結果になりそうですね
大変分かりやすいデータ例の提示ありがとうございます。
おかげで回答しやすいです。
提示されているテーブル名を「作業員所持資格」と仮定して回答します。
まずはパターン情報を得るための下記のようなテーブルを作成します。
資格パターン
「作業員所持資格」と「資格パターン」テーブルから下記のようなクロス集計クエリを作成します。
隠れている「加算手当金:」の式は下記にしてください。
また「クエリ列見出し」も「1,2,3,4,5」と設定してください。
SQLビューなら下記のコードになります。
上記のクエリの結果は下記になります。
これをメインフォームのレコードソースにして、
加算を含む手当金のテキストボックスのコントロールソースに下記の式を設定します。
対象となる資格やパターンの可視化、及び パターンの増減に対応するため
別途、パターンの管理テーブルを作成しましょう
t_資格グループ
■SQL (>> 6に掲載されている「以下の表」の名前を仮に t_資格計算 とします )
■結果
SQLの結果をクエリとして保存するのではなく
SQL文を直接、フォームのレコードソースに指定するといいでしょう
返信ありがとうございます。
Qプラス400円になる資格の組み合わせは下記の5パターンということでしょうか。
資格CD1,2,3
資格CD4,5,6
資格CD7,8,9
資格CD10,11,12
資格CD13,14,15
→はい、5パターンです。
Q一人の作業員が2パターン以上の資格を持っている場合は、それぞれのパターン毎にプラス400円になるのでしょうか。
→はい、パターン毎にプラス400円です。
Q資格CD1,2,3,4,5,6を持っていたらプラス800円になるのでしょうか。
→はい、作用員一人に対して1パターンにつきプラス400円なので、2パターンなら800円、3パターンなら1200円追加されます。
不慣れで見にくい返信で申し訳ございませんでした。
以下の表で少し見やすいでしょうか・・・?
結果
Qまた、結果はクエリとして一覧表示したいのでしょうか。
それとも現状のメインサブフォームで表示出来ればいいのでしょうか。
→メインサブフォームで表示できればうれしいです。
参照ページの添付までありがとうございます。
これからも精進してまいりますので、よろしくお願いいたします。
プラス400円になる資格の組み合わせは下記の5パターンということでしょうか。
資格CD1,2,3
資格CD4,5,6
資格CD7,8,9
資格CD10,11,12
資格CD13,14,15
また、一人の作業員が2パターン以上の資格を持っている場合は、それぞれのパターン毎にプラス400円になるのでしょうか。
例えば、資格CD1,2,3,4,5,6を持っていたらプラス800円になるのでしょうか。
また、結果はクエリとして一覧表示したいのでしょうか。
それとも現状のメインサブフォームで表示出来ればいいのでしょうか。
できればデータ例と希望の結果をマークダウン書式の表として提示してもらえると回答しやすいです。
マークダウン書式については下記に説明がありますので参照してください。
Microsoft Access 掲示板 の使い方 Microsoft Access 掲示板 - zawazawa
上記で説明してありますが、下記のサイトで簡単にマークダウンテーブルが作成できます。
Markdown Tables generator - TablesGenerator.com
テーブルデータのコピーアンドペーストで簡単に作成できます。
希望結果はエクセルで作成してそれをコピーアンドペーストで簡単に作成できます。
すみません。画像貼りなおします。

返信が遅くなり申し訳ありません。
解答ありがとうございます。式はうまく作動しました。
私の説明不足で大変申し訳ないのですが…資格が70件ほどあり、全ての資格ではなく一部の資格でして…
また、所持、未更新という項目があり、所持なら金額表示、未更新なら金額をゼロとしていしています。
一度切の物や、毎年試験する資格があり、落ちると未更新になります。
不慣れなもので、画像を参照して頂ければ嬉しいです。
メインフォームに作業員CDがあり、サブフォームに資格CDの入力をしています。
作業員一人に対して
資格CD1、2、3があればプラス400円
資格CD4,5,6があればプラス400円
・
・
・
(資格CD15まで続きます)
資格CD16以降からはプラス料金はなく、単体の手当金のみになります。
手当金は1千円台から9千円台まであります。
手当金は資格に対する金額であって本人に支給されるのは、所持している人のみの「金額」になります。
いかがでしょうか…?
返答がないのでとりあえず下記のようなテーブル構成だと仮定して回答します。
所持資格テーブル
クエリのデザインビューで下記のように設定します。
SQLなら下記になります。
出力結果
作成可能と思われます。
回答するには、下記の情報が必要です。
対象のテーブル名
テーブル内のフィールド名、データ型
データ例
とりあえず、unsafe action(「coppyとpasteのところにビックリマーク」)の補足です。Microsoft公式資料が分かりにくいのでMukkuMuku備忘さんのWebサイトを紹介します
access2010 access2007 無効モードとマクロとVBAマクロ
Access 2010 / 2013 マクロ ビルダー -2-
なお、hirotonの手元にあるACCESSはMicrosoft365のACCESSで、「copy」や「paste」は日本語表記で「コピー」「貼り付け」になっています。追加貼り付けコマンドの英語表記は確認していませんが、Copilotによると「Append」または「Paste Append」と表記されるらしいです

>>「paste」ではなく、「追加貼り付け」を使ってみたらどうでしょうか?
選択できるコマンドの一覧の中に追加貼付けという項目がありませんでした。
今まで普通に使えていたので混乱しています。
他に何か試せる方法などあれば教えいてただけますでしょうか
マクロは使わないのでよくわかりませんが
「unsafe action」と呼ばれる機能(コマンド)に付くマークです。この表示自体は、なにか動作に影響する/していることはありません。
ACCESSの設定として「unsafe action」を実行しないようにするような設定はありますが、エラーメッセージからすると、copyは問題なく、pasteでエラーとなっているのであれば、この設定が変わってしまったということでもないのでしょう
レコードの追加が目的であれば、「新しいレコードへ」→「レコードの選択」→「paste」ではなく、「追加貼り付け」を使ってみたらどうでしょうか?
hatenaさん ありがとうございます。
ACCESSはまめなバックアップが必用ですね、気をつけます。
お世話になりました。
そのエラーがでるときはたいていファイルの破損が原因ですね。
まずは、最適化、修復を実行してそれでも解決しない場合、
新規ファイルにインポートでたいていはなおります。
ただ、それでも治らない場合もありますので、
定期的、かつ複数世代のバックアップをを取っておくのは必須ですね。
その後ですが、何かが破損しているのかなと思い新たなファイルを作成し全オブジェクトをインポートしましたら、その新ファイルはこの挙動は出なくなりました。原因は不明ですが。
hatenaさん ありがとうございます。
ブレークポイントは前々から気になってたのですが今回やっと使い方が分かりました(まだまださわりだけですが)。
閉じるボタンのIf・・・にポイント設定してF8で進めるとプロシージャ部に移りF8で進めると”オートメーション エラーです。(Error 440)” となりました。これは何を意味しているのでしょうか?
下記をご参考に。
【ExcelVBA入門】VBAでデバッグするための方法とは? | 侍エンジニアブログ
If proSubCk = False Then '受注IDあり時のサブフォームの件数0
の行にブレークポイントを設定して、閉じるボタンをクリックして実行して止まったらステップイン(F8)で1行ずつすすめることができます。
コードまでご教授いただき、ありがとうございます。
また、2022年頃のバージョンにロールバックしたところ、上記のバグも発生しませんでした。
今回の件をマイクロソフトにフィードバックしましたが、
解決までは時間がかかる可能性が高いので、
ロールバックしたまま使うか、こちらのコードで適宜前後を指定したいと思います。
ご助力いただき、ありがとうございました。
hatenaさん ありがとうございます。
恥ずかしながらブレークポイントを設定してステップ実行のデバッグはしたことがないのです。
ブレークポイント付けてからはどう進めるといいでしょうか?
今回の場合 DoCmd.Close acForm, Me.Nameの前には下記プロシージャだけですのでどこにポイント付けたらいいでしょうか? ステップ実行はどう実行させたらいいでしょうか?
Public Function proSubCk() As Boolean
If Not IsNull(Me.[受注ID]) And Me!F受注Sub.Form.RecordsetClone.RecordCount = 0 Then
MsgBox "受注内容の入力がありません。" & vbNewLine & "入力途中では実行出来ません。"
Me.[受注日付].SetFocus
proSubCk = False '戻り値設定
Exit Function
End If
proSubCk = True '戻り値設定
End Function
大変初歩的な事ですみません。
ないみたいですね。
VBAで強制的に前後を入れ替えるには、下記のコマンドを実行すれば可能ですが、デザインビューで実行する必要があり面倒ですね。
DoCmd.RunCommand acCmdSendToBack '最背面に移動
DoCmd.RunCommand acCmdBringToFront '最前面に移動
フォーム1のテキストボックス2を最背面に配置するコード例
デザインビューではMeは使えない。
コントロールを選択するには、InSelection = True とする。
ご返信ありがとうございます。
やはりバグでしょうか。フィードバックしてみたいと思います。
ちなみに、Accessにはコントロールの前面、背面の順番(Zorder?)は存在しないのでしょうか?
VBAで強制的に設定できればと考えたのですが、それらしきプロパティが見つかりませんでした。
後ほど、ロールバックも試してみたいと思います。
まずは、
フォームBの閉じるボタンのコードにブレークポイントを設定してステップ実行したときにどのコードでエラーが発生するか確認してみてください。
当方の365環境で同じ手順を試してみたら、同じ現象が再現しました。
マウスやプロパティシートからの選択では現象は発生しないので、やはりTABキーによる移動がトリガーのようです。
バグのような気がしますので、サポートに問い合わせてみてはどうでしょう。
早急な対策が必要なら、以前の365では正常動作していたのなら下記の方法で以前のバージョンに戻してとりあえずの対応とすることになるでしょう。
Office 365(2016)をロールバックする - Microsoft コミュニティ
hatenaさん ありがとうございます。
頂いたコードで上手く出来ました。確かにそうですね、サブクエリでしたらいいのですね。
Parentの事も初めて知りました。親フォーム参照時に便利ですね。毎回こういった事も大変勉強になります。
お世話になりました。
ご解答ありがとうございます。
ACCESSは聞ける人がいなく独学でやっているもので、まず私の拙い文章をくみ取っていただいたことが嬉しいです。
A,Bどちらの方法でもうまくいきました。ありがとうございます。
IIf関数を使用すればよかったのですね。クエリで違う関数でやってみたのですが、作業員すべてを表示したいのに対象の値しかでないので(←あたりまえですね)作業員すべて出すにはレポートで条件付き書式でしか不可能かと思いこんでいました。
おっしゃる通り一つのテキストボックスに3パターンを入れ込もうとしてました...
A,Bの提案のおかげで円滑にレポートが作成できました。ありがとうございます。
初めての質問で不安でしたがhiroton様の説明とても分かりやすく、本当に助かりました。
入社日と退職日は別列で表示してるので、ダブっていても問題はありません。ご配慮ありがとうございます。
お陰様でより良いレポートが完成しました。素晴らしい解答を本当にありがとうございます。
これがどこから出てきたのかわからないけど、年を年度に変えたい=月をずらしたいならDateAdd 関数を使うとよいでしょう
Year(DateAdd("m", -3, Date()))=Year(DateAdd("m", -3, [入社日]))の比較を行えばいいですね「印刷したくない」のが目的であれば、そもそも印字データを出力しないようにするほうがわかりやすいと思います。上記条件を使って、
A.クエリでデータ表示用フィールドを作る
B.レポート上の非連結テキストボックスで計算する(非連結のテキストボックスを配置してコントロールソースに計算式を設定する)
※レポート上に「入社日」テキストボックスが必要(可視プロパティを「いいえ」にして非表示にする)
一つのテキストボックスで3パターンの表示を考えてるんでしょうか?1年以内に退職した場合(入社日と退職日が両方表示される場合)はどうするんでしょう?
「入社日を表示する/しない」であれば、上記のように計算式でデータの出力を制御すれば、条件付き書式を使わず表現できます
上記の仕様なら、下記のようなSQLでどうでしょうか。
hatenaさん ありがとうございます。
会社テーブルはT3:会社ID(数値型), 会社名(テキスト型)の構成です。
この作業用のフォームということでしょうか。つまり、T1、T2、それぞれのマスターテーブルのメンテナンス用ということでしょうか。
メインフォームに表示されている部材を持っている会社がサブフォームに表示されている。
この会社を削除したり追加したりする。
追加するときに、コンボボックスで選択するが、そのときに既に入力済みの会社はリストから除外する。
上記の仕様でいいですか。
だとすると、別に会社マスターテーブルが必要だと思いますが、そのテーブルの情報も提示してください。
hatenaさん ありがとうございます。
仕様としては部材毎にどの会社に預けているを設定しており、別の棚卸し入力フォームで部材選択を絞り込む時に便利なのです。同じ部材の対象がA社、B社等複数あったり、棚卸外の分は未設定もあります。
なので部材登録フォーム(T1が基)にサブフォーム(T2が基)を設定してます。部材が大量にあるので在庫対象会社に対して部材IDを設定する方が大変だと思い、そうしてます。必用によって部材の在庫を持っている会社を追加、あるいは削除する事はあります。
ちょっと仕様が不明瞭ですが、
メインフォームのレコードソースがT1(部材テーブル)
サブフォームのレコードソースがT2(在庫対象会社テーブル)
ということでしょうか。
このフォームの目的はなんでしょうか。
T2(在庫対象会社テーブル)のメンテナンス用で、
部材の在庫を持っている会社を追加、あるいは削除するということでしょうか。
hatenaさん
》フォーマット時では印刷時拡張したときの高さは取得できません。
よくわかりました。詳しくご教示いただきありがとうございました。
フォーマット時で印刷時拡張を考慮して位置やサイズを計算してレイアウトを決定します。
フォーマット時では印刷時拡張したときの高さは取得できません。
印刷時にフォーマット時で決定されたレイアウトで出力します。
この時点で印刷時拡張されたときの高さを取得できます。
印刷時では直線コントロールの位置やサイズは変更できないので、Lineメソッドで直線を描画します。
hatena さん
早速 ご回答ありがとうございました。成功しました。
》「印刷時」イベントに記述してますか。
私は、「フォーマット時」に上記 vbaを記載していました。
「印刷時」に記載すると、狙い通りの結果を得られました。
実は、フォーマット時 と 印刷時の違いを知らなかったのです。
》「立体表示」プロパティに「下線付き」
こんな設定があるのも知りませんでした。これを指定すると、VBAを記載するまでもなく、目的を達成できました。
ありがとうございました。
Office2010とはずいぶん古いバージョンですが間違いないですか。
それだけ古いと下記の回答では対応してないかもしれませんので、その場合はご容赦ください。
テキストボックスの「立体表示」プロパティに「下線付き」という設定があります。その設定にすればVBAを使うまでもなく下線が表示できますし、印刷時拡張しても追従します。
上記ではうまくできないという場合は、質問のコードでいいと思いますが、このコードはどこに記述してますか。
テキストボックスを配置しているセクションの「印刷時」イベントに記述してますか。
テキストボックスが詳細セクションにあるのなら、下記のようになるはずです。
返信ありがとうございます。
非表示のほうで組み込んだところ画面もすっきりして思い通りの動作になりました。
ありがとうございました。
ポップアップフォーム名を F_Popup とすれば下記のようなコードになります。
ただ、Microsoft365だと最小化したポップアップフォームをユーザーが操作するのが難しいので、非表示にするほうがいいと思います。非表示でもポップアップフォームの抽出条件などは取得できます。
ちなみに、最小化または非表示にしたフォームを元に戻すor再表示させるのは、下記でOKです。
>>VBAですることになりますが、イベントはKeyDownではなくKeyUpが適切です。
hatena様ありがとうございました