Microsoft Access 掲示板

views
4 フォロー
6,283 件中 3,801 から 3,840 までを表示しています。
1

レポートで6ヶ月分のカレンダー表示 - hatena chips

上記の テーブル「T_月」に 0 から 11 までの数値を入力すれば12ヶ月分のデータが出力されます。
それを元にレポートを作成すればいいでしょう。
あとは、上記のリンク先の方法を理解して応用してください。

1

ページ関係の制御はメインレポート側で行いますので、サブフォームにはページという概念はないです。
レポートヘッダーかグループヘッダーを使ってください。

1

週に2回(月曜日を起算日とする)

ということなら、まずは週マスターテーブルを作成すると管理が楽になりそうです。

例えば下記のような感じです。

テーブル名 T_週 

年度週ID開始日終了日
202113月29日4月4日
202124月5日4月11日
202134月12日4月18日
202144月19日4月25日

フォームはメイン/サブフォーム形式にして、
メインフォームは上記のテーブルをレコードソースにして、サブフォームは勤務時間管理用のテーブルをレコードソースにします。「週ID」フィールドも勤務時間管理テーブルに持たせます。

サブフォームのヘッダーかフッターにテキストボックスを配置してコントロールソースに下記の式を設定すれば、
勤務時間計や勤務時間が8時間以上の回数を表示できます。

=Sum([退勤時間]-[出勤時間]) * 24

=Sum(IIf((([退勤時間]-[出勤時間]) * 24)>=8, 1, 0))

3

テーブルを開いてそこで直接更新しても、テーブルやテーブルのフィールドではイベントが発生しないので、自動でフィールドBに計算結果を代入することはできません。

フィールドAを更新したときに自動でフィールドBも更新するには、テーブルと連結した入力フォームを作成する必要があります。
フォーム上では、フィールドと連結したテキストボックスで入力することになります。
テキストボックスの更新後処理イベントを使うことになります。

以上の説明で理解いただけたでしょうか。
不明な点があれば、具体的に質問してください。

2
すいちゃん 2021/04/12 (月) 17:32:00 58219@5a5ac

フィールドA→テキストボックス→フィールドBとするのですか?
フィールドA→フィールドBではなにか不具合がありますか?

1

どちらでもお好みでいいと思います。

単価×個数 というような単純な式ならクエリにする場合が多いですね。
フォームや他のレポートでも使いまわせますので。

複雑な式で、そのレポートのみでしか使用しない場合はレポート上のテキストボックスのコントロールソースに式を設定する場合もあります。デザインビューですぐに確認できますし、修正もそこで完了します。

しかし、たいていは入力フォームでも計算結果を表示させる場合が多いので、共通のクエリにしてクエリで式を設定する方が多いですね。

1

目的次第だと思います。

入力した直後に結果を格納したいのなら、テーブルと連結した入力フォームを作成して、フィールドAと連結したテキストボックスの更新後処理のイベントでフィールドBに計算結果を格納することになります。

3

レポートを選択すれば幅は表示されます。ただし、変更はデザインビューにする必要があります。

画像1

2

レイアウトで数値指定で幅を設定できましたっけ?
プロパティ見てたけど見つけられませんでした

2
ワッフル 2021/04/11 (日) 12:53:15 557b6@73a2b

いつも迅速、ご丁寧なご返事をありがとうございます。
参考にして頑張りたいと思います。

1

用紙の幅-左右の余白 が印刷範囲の幅というように計算するか、
プレビューのさせて、はみ出たら狭くする、足らなければ広くするというようにレポート幅を調整することになりますね。

例えば、A4縦なら用紙幅210mm 左右余白が各15mmなら 210-(15*2)=180mm が印刷範囲の幅になります。

また、A4の左右に2ページ分印刷するときは、A5で作成して、それを印刷設定で1枚に2ページ印刷するようにするのでしょうか?印刷時に列数を2にする方法だと、レイアウトをつくるときにどこまで幅をとると2列になるかの把握がしずらくなりますよね?

項目のレイアウトによって、印刷設定で2ページ印刷にするか、列数2にするか、レポート幅を用紙幅の2倍にするか、を選択します。

1

そこで、クエリに代入コーナーを設け、2021/3と入力したら、」
の意味が、
クエリのデザインビューで、フィールド欄に、[]で囲んだ式を入力しており、プレビューするときにダイアログが開きそこに日付を入力するとその日付で抽出されるということでしょうか。
この場合、フィールド欄に入力した式をパラメーターといい、パラメーターを含むクエリのことをパラメータクエリといいます。
基本的な用語ですので覚えておきましょう。

現状は、商品一覧クエリに[日付指定【例:2021/3】]というパラメーターが設定してあり、商品一覧レポート(メインレポート)のレコードソースになっている。
この商品一覧クエリからさらに集計クエリを作成して、商品別集計クエリ(サブレポート)のレコードソースにしている。

この場合、それぞれがパラメータークエリになりますので、2回入力を要求されます。

上記のような状況だと理解しました。

対処法ですが、パラメーターの式にはフォームのテキストボックスを参照する式にすることができます。そうすると、フォームを開いてテキストボックスに日付を入力してからレポートを開けば、パラメーターダイアログか開くことはないです。

設定する式は、下記のような書式になります。

Forms!フォーム名!テキストボックス名

テキストボックスなら設定で日付選択カレンダーを表示させたりすることが出来ますし、そのフォームにレポートを開くコマンドボタンを配置しておけば、より使いやすいものになります。

9
ゲッキョク駐車場 2021/04/08 (木) 16:30:23 cb55f@f6500 >> 5

朱色さん
ありがとうございます。

大変申し訳ないのですが、私の不勉強故、バックエンドデータベース上のテーブルを参照する場合に「SELECT~ FROM~ 」や「INSERT INTO~ VALUE~」を用いたりすることと、朱色さんが今回説明してくださっているリンクテーブルへの変更云々との違いがよくわかりません。

今回提示している、UserLogに関するVBA以外は変更していませんが、情報の閲覧や編集はできているので、大きな不便は感じていないのですが…。

8
ゲッキョク駐車場 2021/04/08 (木) 16:19:14 cb55f@f6500 >> 4

hirotonさん

申し訳ありません、言葉足らずでした。
RemoveDate = Format(RemoveDate, "yyyy/mm/dd hh:mm") を抜けば、という
考えで勝手に先走ってました…。申し訳ありません。

日付が内部では数値で云々の箇所は、昔に、自作カレンダーフォームの移動関数
のあたりでhatena氏から聞き及んでおりました…!

ご尽力を無駄にしてしまうような形となってしまい申し訳ありません。

7
hiroton 2021/04/08 (木) 14:09:01 3ea36@f966d >> 4

それともエラー回避のために念のためつけておくのが安牌でしょうか…。

RemoveDateDim RemoveDate As Dateと宣言している(date型で宣言している)ので「#」は必須です(ないと困ったことになります)

Dim d As Date
d = date
Debug.print d & ""

こういう処理(date型を文字列にして出力する)と

2021/04/08

日付(+時刻)っぽい文字に変わります

問題のコードも

strSQL = strSQL & "where 日時<#" & RemoveDate & "#"

が実際に処理されるときはRemoveDateが日付っぽい文字に変わるのでそれをSQL文上での日付データとして扱うためには「#」で囲む必要があります。これを怠ると、例えば

where 日時<2021/4/8

のようなSQL文になるので、「2021/4/8」=「2021÷4÷8」=「63.15625」

where 日時<63.15625

が実行されます。やばいですね

ちなみにdate型というのはコンピュータの内部では数値データです。
Date Data Type (Visual Basic)
つまり、上のSQLは

where 日時<#1900/03/03 3:45:00#

と同じです。SQL構文として問題のない文なので動きます。でも、これでは意図した通りの結果は得られませんよね?ちょーやばいです。エラーを出してくれたほうがマシです

6
ゲッキョク駐車場 2021/04/08 (木) 09:26:19 cb55f@f6500 >> 4

hirotonさん
ありがとうございます。

元のプログラム文で、日数指定をしてから、「~~以前のデータを削除します」みたいなMSGBOX
を出していたので、formatで文字列に変えてました。

ってことは、strSQL内のWHERE条件も "where 日時<" & RemoveDate & で
わざわざ##囲みしなくても良いんでしょうか…。
それともエラー回避のために念のためつけておくのが安牌でしょうか…。

5
朱色 2021/04/07 (水) 20:19:08 db0eb@4c730

ちなみにですけど、テーブルをリンクテーブルにしたらだめなんですかね?
そうすればVBA変えなくていいしクエリとか使ってるならそれもそのままでOKになるし・・・フォルダ構成が変わったとかの時も対応できるし、バッチリだとおもうんですが。
あとACCSESSはデータを消しても容量が減らないので、捨てるデータはたとえば月単位でDB作って書き込み、月が替わったらDB切り替えするとか、そもそも隠す内容でない&検索するとか再利用しないならCSVに吐き出していくとかでも良い気がします。

なおリンクテーブルにするなら参考↓
ACCESSのVBAでリンクテーブルを更新する

4
hiroton 2021/04/07 (水) 17:08:36 bb98d@f966d

難しい質問ですねぇ
実行されるクエリが、という意味ならDB.Execute strSQLの行でのstrSQLの中身は問題ないように思います


VBAコードの良し悪しという意味なら突っ込みどころも出てきます

とりあえず、完全にNGなので指摘しますが

RemoveDate = Format(RemoveDate, "yyyy/mm/dd hh:mm")

RemoveDateDate型の変数です。Format()は文字列を返します。Date型の変数に文字列を代入しようとしているので暗黙の型変換が発生します。この行は結局

RemoveDate = RemoveDate

と変わりません。完全に無駄な処理です

他の記述については、好みの問題まで発展しそうな話ので触れないことにしておきます

3
ゲッキョク駐車場 2021/04/07 (水) 14:20:03 cb55f@f6500

hiroton さん
お早いご返事誠に痛み入ります。
実際に置換してみたところ、うまくいきました・・・!
ありがとうございます!
VBAでSQL文を書いてると、ゴチャついてきちゃいますね。
追加で代入していく方法も今後用いて、着実にミスの無いようにしていきたいです。

また、早速参考にして、UserLogの古い履歴をイイカンジに消す CleanLog にも頑張って適用してみました。下記。

Public Sub CleanLog(Day As Integer)
'上記で登録したユーザーAccessデータを、いい感じの古さの物から削除

  Dim RemoveDate As Date: RemoveDate = DateAdd("d", -Day, Now)
  '今の日にちから、●●日前 を特定する関数
    
  RemoveDate = Format(RemoveDate, "yyyy/mm/dd hh:mm")
  '特定した日付を、xxxx/xx/xx xx:xx の形に整える

  Dim DB As DAO.Database: Set DB = CurrentDb
  Dim strSQL As String
  
  strSQL = strSQL & "delete from T_UserLog "
  strSQL = strSQL & "IN '' [MS Access; PWD=PASSWORD; DATABASE=C:\略\MnfctMng_BEDB.accdb;] "
  strSQL = strSQL & "where 日時<#" & RemoveDate & "#"

  DB.Execute strSQL
  '上記の日時からのデータをすべて削除する

End sub

これによって、BEDBの方の古いログも消すことができましたが、これで問題ないでしょうか…。
ログなので別にミスって全消去になってもそこまで問題はないのですが、DELETEを扱うので
すこし心配になってしまって。
ご教示の程宜しくお願い致します。

2
ワッフル 2021/04/07 (水) 12:39:05 9fdff@73a2b

早速のご返事誠にありがとうございます。

試してみたいと思います。

2
hiroton 2021/04/07 (水) 11:40:44 bb98d@f966d

コードの記述はちょっと気に掛けてあげると問題にも気づきやすくなります

問題のあるコードそのまま書き換え

Dim strSQL As String
strSQL = strSQL & "insert into T_UserLog (場所,行為,ユーザー名,マシン名)"
strSQL = strSQL & " values ('" & PN & "','" & AN & "','" & WSH.UserName & "','" & WSH.ComputerName & "')"
strSQL = strSQL & " T_UserLog IN '' [MS Access; DATABASE=C:\略\MnfctMng_BEDB.accdb;PWD=PASSWORD;];"""
CurrentDb.Execute strSQL

INSERT INTO ステートメント

外部ファイルに接続する場合の記述は

複数のレコードを追加するクエリは、次のとおりです。

INSERT INTO target [(field1[, field2[, ...]])] [IN externaldatabase]
SELECT [source.]field1[, field2[, ...]
FROM tableexpression

1 つのレコードを追加するクエリは、次のとおりです。

INSERT INTO target [(field1[, field2[, ...]])]
VALUES (value1[, value2[, ...])

VALUESを使った記述の場合「外部ファイルに接続する方法」の記述がありませんね・・・

まぁ、Microsoftの公式資料なんてそんなもんです。きっと似たような記述をすればなんとかなるはず

INSERT INTO target [(field1[, field2[, ...]])] [IN externaldatabase]
VALUES (value1[, value2[, ...])

Dim strSQL As String
strSQL = strSQL & "insert into T_UserLog (場所,行為,ユーザー名,マシン名)"
strSQL = strSQL & " IN '' [MS Access;DATABASE=C:\略\MnfctMng_BEDB.accdb;PWD=PASSWORD;]"
strSQL = strSQL & " values ('" & PN & "','" & AN & "','" & WSH.UserName & "','" & WSH.ComputerName & "')"
CurrentDb.Execute strSQL

お試しを

1
ゲッキョク駐車場 2021/04/07 (水) 11:07:42 修正 cb55f@f6500

変更後のVBA(下の方)のDim strSQL行の最後に select * from を加筆し、

  Dim strSQL As String: strSQL = "insert into T_UserLog (場所,行為,ユーザー名,マシン名) values ('" _
  & PN & "','" & AN & "','" & WSH.UserName & "','" & WSH.ComputerName & "') select * from "
  
  CurrentDb.Execute strSQL & "T_UserLog IN '' [MS Access; DATABASE=C:\略\MnfctMng_BEDB.accdb;PWD=PASSWORD;];"""

と書き直した所、CurrentDb.Execute行に 最後の;が足りないエラーが出てしまいました。
strSQLの内容がまずい気がするんですが、いかがでしょうか…。

5
hatch 2021/04/07 (水) 09:37:49 0d922@b524f

解決しました!!
リレーション先登録されている社員番号と一致しないせいでエラーが出ていました・・・
同じように登録するとエラーなしで表示されました!
お手数をお掛けし申し訳ありません。

1

レコードソースのパラメータはそのまま参照できます。
テキストボックスを2つ配置して、コントロールソースにそれぞれ下記のように設定すればOKです。

=[はじまりの日付【例:2021/3/1】]

=[終わりの日付【例:2021/4/2】]

4
hiroton 2021/04/06 (火) 14:36:50 修正 6edc5@f966d
SELECT 社員マスタ.社員番号, 全社員住所歴マスタ.社員番号, 社員マスタ.氏名, 社員マスタ.入社年月日, 社員マスタ.生年月日, 全社員住所歴マスタ.郵便番号,
 全社員住所歴マスタ.都道府県, 全社員住所歴マスタ.市区町村, 全社員住所歴マスタ.番地,
 全社員住所歴マスタ.[マンション等], ([全社員住所歴マスタ].[都道府県] & ([全社員住所歴マスタ].[市区町村]) & [全社員住所歴マスタ].[番地] & ([全社員住所歴マスタ].[マンション等])) AS 全住所,
DateDiff("yyyy",[生年月日],Date())+(Format([生年月日],"mmdd")>Format(Date(),"mmdd")) & "歳" AS 年齢, 全社員住所歴マスタ.登録日
FROM 社員マスタ LEFT JOIN 全社員住所歴マスタ ON 社員マスタ.社員番号 = 全社員住所歴マスタ.社員番号
WHERE 全社員住所歴マスタ.社員番号 IS NULL;

このクエリを実行するとエラーは表示されますか?または、レコードが表示されませんか?

3
りんご 2021/04/06 (火) 14:24:29 48103@0e907

素人がググっただけですが、社員番号がnullになるものが無くても、LEFT JOINの結果、組み合わせでnullになっているせいとか?

2
hatch 2021/04/06 (火) 13:48:39 0d922@b524f

hiroton様
回答いただき誠にありがとうございます。
私も原因がそれだと思い探したのですが社員番号がnullになるのはありませんでした。。。

1
hiroton 2021/04/06 (火) 13:26:27 6edc5@f966d

SELECT 社員マスタ.社員番号, 社員マスタ.氏名, 社員マスタ.入社年月日, 社員マスタ.生年月日, 全社員住所歴マスタ.郵便番号,
 全社員住所歴マスタ.都道府県, 全社員住所歴マスタ.市区町村, 全社員住所歴マスタ.番地,
 全社員住所歴マスタ.[マンション等], ([全社員住所歴マスタ].[都道府県] & ([全社員住所歴マスタ].[市区町村]) & [全社員住所歴マスタ].[番地] & ([全社員住所歴マスタ].[マンション等])) AS 全住所,
DateDiff("yyyy",[生年月日],Date())+(Format([生年月日],"mmdd")>Format(Date(),"mmdd")) & "歳" AS 年齢, 全社員住所歴マスタ.登録日
FROM 社員マスタ LEFT JOIN 全社員住所歴マスタ ON 社員マスタ.社員番号 = 全社員住所歴マスタ.社員番号
WHERE (((全社員住所歴マスタ.登録日)=DMax("登録日","全社員住所歴マスタ","社員番号 =" & [全社員住所歴マスタ].[社員番号])) AND ((社員マスタ.退職の有無)=False));

[全社員住所歴マスタ].[社員番号]がnullになるレコードがあるのでは?

4

高さに応じて上位置を少し小さくすることになるかと。その辺はトライ&チェックが微調整するしかないかなと思います。

3
積み木 2021/04/06 (火) 04:44:42 2a30e@05952

例えばヘッダーや詳細の一番下におきたいときにはどうすればいいのでしょうか?
数値指摘での位置合わせは、どうもその要素の真ん中が基準になっているような、気がします

2
積み木 2021/04/06 (火) 00:49:31 2a30e@05952

おー!気が付きませんでした
線に見えるけど細い四角なんですね
調整もしやすそうです!
大変参考になりました!

1
hatena 2021/04/05 (月) 21:01:11 修正

Accessのレポートで罫線はなかなか難しいですね。
細線とか1ポイントとか設定しても、プリンターによって太さが異なったりします。

直線コントロールの代わりに四角形コントロールで、境界線は透明、背景色を黒にして、高さをいろいろ変更すると細かく調整できます。

下記は、直線コントロールの幅、四角形コントロールの高さを変更したものをプレビューで500%ズームしたもののキャプチャーです。

画像1

3

履歴テーブルをつくるとそれなりのコストがかかるというのはどういった意味でしょうか?

設計する手間やコード量が増えるという意味です。
再請求や修正・削除が無制限にできるという自由度と引き換えに、作成する時間がかかるし、メンテナンスも大変そうです。
一度、作成してしまえばいいですが。

いっそ削除したものは、データベースには残さずに請求書発行時にPDFとして写しを作成し、確認用としてとっておく、とかが楽なのかもしれないと思ってきました

インボイス制度がもうすぐ始まるそうですが、請求書の発行者もなんからの形で控えを保存しておく必要があるそうです。
下記で議論してますのでご参考に。

請求書をPDFで保存するかどうか Microsoft Access 掲示板 - zawazawa

50
もんぞう 2021/04/05 (月) 18:19:09 62ea7@f778d

hirotonさんへ

「クロス集計クエリからレポート印刷」に関して最初の設計図と現状は大幅に変わってしまいました。
アクセスでクロス集計表を作る場合は列と値は1つしか設定できないという認識がありました。
現状は最終的にクロス集計表としての複数の列と値を設定できるようになり求める設計図が大幅に広がってしまいました。
「クロス集計クエリからレポート印刷」というトピックへの書き込みはこれで最後にします。
一か月近い期間のアドバイスありがとうございました。
また機会がありましたらよろしくお願いします。

2
積み木 2021/04/05 (月) 17:32:47 58219@ca66a

頭で考えれば単純な処理なんですが体系立てるのはなかなかむずかしいみたいですね
削除請求書番号に記載するにしても、用意したフィールドよりも削除が発生するかもしれない(常識的に考えれば2つも用意すれば十分でしょうけど)といった不安もありますね

履歴テーブルをつくるとそれなりのコストがかかるというのはどういった意味でしょうか?
保存容量や動作の軽さに影響するという意味ですか?

いっそ削除したものは、データベースには残さずに請求書発行時にPDFとして写しを作成し、確認用としてとっておく、とかが楽なのかもしれないと思ってきました

起こる確率の低いイレギュラーなことばかり考えてしまい、全然進まなくなるのが悪い癖ですね

1

その要件は、昔からなかなか難しい要件の一つです。
いろいろな方法があると思います。

請求した通りに間違いなく、遅れもなく入金してくれれば問題はないのですが、いろいろイレギュラーなことがありますからね。

期限までに入金してくれなかったり、
一部だけ入金してきたり、
まとめて入金してきたり、
たまに、余分に入金してきたり、
・・・

こちら側にも、入力間違いとか、ありますしね。

これらのイレギュラーにも柔軟に対応できるようにするには、ある程度データに冗長性を持たせることになりますね。

売上テーブルのレコードにはどの請求書で請求したか、を何らかの形で残すものですか?(売上レコードの請求書番号フィールドなどに番号をいれる?)

自分もそのような設計にすると思います。
あと、入金日も持たせるかな。
期限をすぎても、入金されない場合は、再請求する必要がありますので、
再請求時の請求書番号も必要になりますね。
品番に再請求が発生するなら、別テーブルに履歴として保存しておく必要があるかも知れません。

後から誤りが発覚してつくりなおすときに請求書を削除するときには、その後の問い合わせにも対応できるように論理削除にしようと思います

これは、当然そうすべきでしょうね。

削除した請求書に記載していた売上レコードは、別の請求書に記載することになると思います
番号を付与するようにしていても、新たな請求書に記載したときに上書きされてしまうので、過去の請求書に表示させられなくなります

売上テーブルに、請求書番号、削除請求書番号、というフィールドを持たせるか、
別テーブルにして履歴をすべて残すか、ですね。
履歴には上記の再請求も含めて残すといいでしょう。

再請求や修正/削除がどの程度発生するかによってどちらかに決めることになると思います。
別テーブルで履歴を残すというのはそれなりにコストがかかりますので、それに見合うかどうか、検討してください。

49
hiroton 2021/04/05 (月) 08:49:46 36a0e@f966d

区切りをどこで付けるかというのは悩みどころですが、そろそろ質問を分けたほうがよさそうです

当初の質問として

ワンクリックぐらいで印刷できるように

とあり、それに対してデータベース的なアプローチ(クエリ・SQLを駆使してデータ整形)で回答を付けました。ACCESS的なアプローチで連番を振ったり、処理速度的に厳しいところをVBAで対応したりもしましたが、元データに依存するような部分はなかったと思います。
言葉にすると「大きなデータをページ毎のデータに整形する方法」ですね

追加の質問は元データから項目が追加されてきているし、「各ページのデータができた後のレポート表示のしかた」といった感じで最初の質問からは内容が離れてきているので、改めて必要な内容(データ構造、レポートの表示イメージ等)を整理した上で新たな質問にしてください

48

[テキスト122]~[テキスト125]は適切な名前で運用するか、

[テキスト122]→n0ケース数表示

等、注釈を追記するようにしてください(質問者以外中身のわからないモノでは回答しにくいです)

それと、コードはなるべくコピペで提示するようにしましょう。いろいろ捗ります
コードブロック

1

Accessに関する情報交換の掲示板ですが、どの辺がAccessと関係ありますか。

AccessのVBAで実現したいという話ですか。
AccessからWSHを呼び出すという話ですか。