Microsoft Access 掲示板

views
4 フォロー
6,283 件中 5,401 から 5,440 までを表示しています。
5
Accessって敷居が高い 2020/05/02 (土) 11:05:55 e08ac@b63e9 >> 4

(2)を使って解決しました。

SetTempVar
  Name CurrentRecordNo
  = [Forms]![Frm_Name].[CurrentRecord]

Requery

GoToRecord
  Record  GoTo
  Offset  =[TempVars]![CurrentRecordNo]

3
Accessって敷居が高い 2020/05/02 (土) 10:07:26 e08ac@b63e9

アドバイスありがとうございます。
初心者なので、間違った語句の使い方等はご容赦を。

ご指摘のとおり
 テーブル: メインテーブル、所属テーブル、役職テーブル
 フォーム:メインフォーム、所属追加フォーム、役職追加フォーム
の構成です。
メインフォーム中の、所属と役職を選択するコンボボックスがそれぞれ5個あり、それぞれ所属テーブルと役職テーブルを参照する形(Lookup)にしてあります。
メインフォームから、所属追加フォームと役職追加フォームを呼び出して、所属や役職を追加し、その追加修正をメインフォームの合計10個の所属・役職コンボボックスに即時かつ自動的に反映させたいのです。

所属追加フォームや役職追加フォームには、「レコードセーブボタン」、「フォームを閉じるボタン」を配してあります。アドバイス頂いたように、この2つのボタンのon-clickイベントマクロにRequery(コントロールなし)で追加するのですが、全くメインフォームには反映されない、あるいは1つのコンボボックスだけ反映されるなど、不思議な挙動をします。
この他にAfter UpdateイベントマクロにRequery(このトロールなし)を加えても同じ。追加フォーム上に「Requeryボタン」を作ってon-clickイベントでRequeryをさせても、全く同じ挙動。VBAコードとしてon-clikイベントでMe.Requeryなども試しましたが反映されず。

唯一、所属追加フォームや役職追加フォームの変更を反映させることができる動作は
(1)メインフォームにおいて、Shift-F9
(2)メインフォームにおいてRequeryを行う。

この他、Relationshipで連鎖更新もONにしてあるのですが、Joinタイプを変えるとか、私の思いつく範囲でいろいろ試してみたのですが、私の知識・経験では(1)(2)でしか実現できません。

しかし、この(1)(2)を行うと、現在入力しているレコードから、一番先頭のレコードに飛びます。User Unfriendlyも甚だしいので、なんとか、Macroを使ってCurrentRecord番号をゲットして、Requery後にGoToRecordで元のレコードに飛ばそうと思っているのですが、マクロでCurrentRecordのゲットの書式が分かりません。。。。
マクロだからeasyかと思いましたが、VBAとは違って、[TempVars]![MyVal]のフォーマットだし、かといってMacroの書式について初心者向けの資料もないし。。。。

どうしてこんな簡単なことが、ここまで難しいのか。。。。
やっぱりAccessは使うべきではないなと-と感じています。FileMakerにしておけば良かった。でも関係者にFileMakerを買わせる負担を掛ける訳にもいかず。。。。
Accessのフォーラムにこんなこと書くのは失礼かもしれませんが、Accessって基本思想自体が間違っていると感じます。

2
Accessって敷居が高い 2020/05/02 (土) 09:44:26 e08ac@b63e9

アドバイスありがとうございます。
初心者なので、間違った語句の使い方はご容赦を。

ご指摘のとおり
テーブル: メインテーブル、所属テーブル、役職テーブル
フォーム:メインフォーム、所属追加フォーム、役職追加フォーム

1
hiroton 2020/05/01 (金) 09:51:41 c385e@f966d

(3)メインフォームに「Requeryマクロ」を作り、新しいRequeryボタンに割り当てます。

作業手順がよくわかりません。
「Requeryマクロ」とはリボンの[作成]タブにある[マクロ]メニューから作成したマクロですか?

イベントとは、ユーザーの操作に対応して発生・実行されるものです。

「Requeryボタン」を押す。

と、Requeryボタンのクリック時イベントが発生します。

今回やりたいことは「サブテーブルを更新後に何かしたい」なので、「サブテーブルを更新したと判断できる作業」のイベントにマクロを設定する必要があります。
操作中のフォーム「サブフォームのイベントにマクロを設定する」と良いでしょう。

具体的にはサブフォームの更新後処理が「”自動的に”かつ”すぐに”」に合うかと思います。


”すぐに”を本当に「すぐに」にしたいのであればサブフォーム上の個別のコントロール(所属や役職)それぞれの更新後処理イベントを使うという方法もあります。

逆に、サブフォームで作業したあと、メインフォームで作業する前にサブフォームは閉じるという手順があるのであれば、サブフォームの閉じる時イベントでもいいのではないかと思います。


「サブフォーム」という言葉はACCESSではあるフォームの中に組み込まれたコントロールとしてのフォームを指す言葉として使われます。
誤解を招きやすいので「入力用フォーム」としたり、あるいは「AフォームとBフォームを作ってAフォームからBフォームを呼び出しています」等の前置きから質問すると良いです。

1
hiroton 2020/04/28 (火) 13:25:49 22653@f966d

ACCESSはクエリの作成においてSQLの直接入力にも対応しています。
リボンや右クリックのポップアップメニューからSQLビューデザインビューを相互に切り替えられるので、q_売上情報クエリのSQLをコピーして質問されるとより良い回答が得られると思います。(場合によっては売上情報テーブルの構造も)

特定のフィールドの値を条件に部分的な集計をしたい場合、集計用のフィールドを用意して、そのフィールドで集計したいフィールドだけを抽出する条件を指定するとできます。
たとえば、①テキスト用なら

事業所1集計: IIf([事業所]=1,[売上金額])

のようなフィールドを作り、クエリの集計機能を有効にし、集計の項目で合計を設定すると良いでしょう。

17
OMOTI 2020/04/28 (火) 10:31:03 05554@4b4f6

いつもありがとうございます。
反映させることができました。

16

サブレポート内のテキストボックスをクリックし、入力フォーム(F_入力フォーム)を開き、スケジュールの詳細を入力しています。
入力フォームに作成している「保存ボタン」をクリックするときにサブレポートもリクエリしています。(サブレポートに表示に反映させている)

入力フォームでの更新がF_Calendarに反映されないので、反映させたいということですね。
下記のように1行追加してみてください。

'保存ボタンクリック時
Private Sub cmd保存_Click()
    BeforeUpdate = ""
    DoCmd.RunCommand acCmdSaveRecord
    BeforeUpdate = "[イベント プロシージャ]"
    Forms![F_Calendar].SetSchedule '追加
    Forms![F_Calendar]![R_作業日一覧_カレンダー表示用].Report.Requery
End Sub
15
OMOTI 2020/04/27 (月) 17:54:49 05554@4b4f6

【カレンダー形式のスケジュール管理 その3】 
詳細データ表示用をサブフォームではなく、サブレポートを利用しています。

サブレポート内のテキストボックスをクリックし、入力フォーム(F_入力フォーム)を開き、スケジュールの詳細を入力しています。
入力フォームに作成している「保存ボタン」をクリックするときにサブレポートもリクエリしています。(サブレポートに表示に反映させている)

 '保存ボタンクリック時
Private Sub cmd保存_Click()
 BeforeUpdate = ""
 DoCmd.RunCommand acCmdSaveRecord
 BeforeUpdate = "[イベント プロシージャ]"
 Forms![F_Calendar]![R_作業日一覧_カレンダー表示用].Report.Requery
 End Sub

===============
F_Calendar への反映で困っています。

カレンダー形式のスケジュール管理 その3 
サブフォームで更新や追加、削除したときにカレンダーにその結果を反映させるためにサブフォームのフォームモジュールに下記のイベントプロシージャを作成します。SetScheduleをPublic宣言したのはサブフォームから呼び出す必要があったためでした。

'フォーム 更新後処理
Private Sub Form_AfterUpdate()
    Me.Parent.SetSchedule
End Sub

'フォーム 削除後確認
Private Sub Form_AfterDelConfirm(Status As Integer)
    If Status = acDeleteOK Then Me.Parent.SetSchedule
End Sub

=====
サブフォームではなく、サブレポートの為、上記のままではダメだと思い、色々と手を尽くしていますが、
うまくいきません。

入力フォームの「保存」ボタンをクリックしたときに、F_Calendar にも反映させたいのです。
入力フォームからサブレポートを反映させ、サブレポートからF_Calendarを反映させるでも良いのですが…

度々で申し訳ございません。ご教授いただけませんでしょうか。

14
OMOTI 2020/04/27 (月) 14:54:18 05554@4b4f6

時間表示、サブレポートの件、解決しました。
以前、説明されている記事を拝見せずに、質問してすみませんでした。
ありがとうございました。

3

エクセルは、画面での表示と印刷の表示は一致しないというのが常識らしいです。
【Excel】画面表示の通りに印刷できないのは「速度優先」だからです - わえなび ワード&エクセル問題集

「請求書」みたいなレイアウトのものを印刷したいです
請求書により、レコード数が多かったり少なかったりするので
固定の位置に最後の太い線を配置したいです

私の古いブログですかいろいろな方法を紹介していますので、ご参考に。

レコードがない場合も用紙の最後まで罫線を出力する - hatena chips

レコードがない場合も用紙の最後まで罫線を出力する関数 - hatena chips

レコードがない場合も用紙の最後まで罫線を出力する NextRecord版 - hatena chips

ページの最後の罫線を太線にする - hatena chips

3

案件によりますね。
実際に印刷して定規で測ってきっちり調整することもあります。

2

回答ありがとうございます
目分量や数値をみながらやるしかないんですね

フィールドの文字はきっちり真ん中に表示されるわけではないみたいなので微妙にズレてしまいますね
プロパティの余白で調整するようですね

私が見た目にこだわりすぎなのがいけないんでしょうけど
みなさんもっとアバウトに配置されているんですか?

2

はい
「請求書」みたいなレイアウトのものを印刷したいです
請求書により、レコード数が多かったり少なかったりするので
固定の位置に最後の太い線を配置したいです
レコードごとに仕切り線を配置しておくと、最後は、仕切り線と太い線、二本になるのが少し気になります

ACCESSでは調整がむずかしそうですが理想はエクセルで例えば20行固定にしたときのようにぴっちり収まるといいです
レコードのフィールドのフォントサイズと高さによってはヘッダーとの間に他の行より隙間があいてしまったりつまったりしそうです

1

呈示の画面はAccessではないようですが、具体的にはどのような質問でしょうか。

呈示のような書類をAccessのレポートで作成したいという質問でしょうか。

1

上下位置の自動調整の機能はないので、プレビュー画面で拡大表示して位置を確認しながら、上位置か上余白で調整するしかないのでは。

ヘッダーの下線は、ヘッダーセクションの高さを少し高めにしておいて、ラベルにかからないように直線コントロールを配置してから、セクションの高さをマウスでドラッグして小さくすればどうでしょうか。

1

codeフィールドはテキスト型ですので、SQLは下記のようにしてください。

select code,DCount("*","tblfood","code <='" & [code] & "'") AS n,name
from tblfood;

これでエラーに出なくなると思います。
ただし、これだけでは連番になりません。一意に決まるフィールドが必要になります。

下記を参照してください。
DCountでする方法、
サブクエリを使う方法、
VBAで入力する方法、
汎用関数を使う方法
を紹介しています。

グループ毎連番を自動入力する関数 - hatena chips

汎用関数を使う方法がコピーするだけで簡単に使用できますのでお勧めです。処理も高速です。

13

埋め込みマクロで設定しているということでしょうか。
where条件式 は下記のようにしてください。

[ID]=[Forms]![フォーム名]![サブレポートコントロール名].[Report]![ID]

詳細は下記をご参考に。

サブフォームとサブフォームコントロールの違いとは? - hatena chips

サブフォームコントロールで説明してますか、サブレポートコントロールでも同じです。

12
            .Caption = .Caption & rs!開始時間 & " " & rs!略名 & vbCrLf

を下記に変更してください。

            .Caption = .Caption & Format(rs!開始時間,"hh:nn") & " " & rs!略名 & vbCrLf
6

・レコードを新たに作成する用と既存のレコードを編集する用にわけるという理解をしましたが、合ってますでしょうか?

フォームを分けてもいいのですが、一つのフォームで開く時にVBAでプロパティを変更するという方法だと、変更があったとき一つのフォームの修正で済みますので楽です。

例えば、フォームのプロパティは、更新用に設定しておいて、
更新用として呼び出すときは、

Docmd.OpenForm "フォーム名", acNormal, , "主キーフィールド=" & Me.主キーフィールド

追加用として呼び出すときは、

Docmd.OpenForm "フォーム名", acNormal, , , acFormAdd

という感じでOKです。

5
rYIqAoFuZQf4ClO 2020/04/24 (金) 15:56:10

1.取引先毎に担当を決めておき、データ更新、追加はその担当が行うという運用です。
担当以外のデータは閲覧のみにします。

・これについては仕事の関係上、担当者以外が各レコードの編集を行うことはしていません。そもそもの設定から担当者はイジれないような設定にしたほうがいいのでしょうか?

2.フォームは共通でもいいのですが、フォームのプロパティの設計を下記のように変更します。

更新用フォーム
 データ入力用 いいえ
 更新の許可 はい
 追加の許可 いいえ
 削除の許可 いいえ
 レコードロック 編集済みレコード

追加用フォーム
 データ入力用 はい
 更新の許可 はい
 追加の許可 はい
 削除の許可 はい
 レコードロック 編集済みレコード

一覧表示の閲覧は、リストボックスに表示させるか、
帳票フォームで「レコードセット」を「スナップショット」にしておきます。

・レコードを新たに作成する用と既存のレコードを編集する用にわけるという理解をしましたが、合ってますでしょうか?

11
OMOTI 2020/04/24 (金) 14:46:26 05554@4b4f6

カレンダーの日時を反映させるのは、サブフォームではなく、サブレポート(R_カレンダー表示用)を使用しています。

レポート内のテキストボックスをクリックすることで、入力フォームが開くようにしています。
(プロパティシート⇒テキストボックス⇒クリック時⇒フォームを開く(where条件式 [ID]=[Reports]![R_カレンダー表示用]![ID])

レポートの状態のときは、正常に動くのですが、カレンダーのフォームにサブレポートとして組み込んだ場合に、テキストボックスをクリックすると「パラメーターの入力」を求められます。

色々やってみたのですが分かりません。
ご教授いただけませんでしょうか…
いつもすみません…

4
hiroton 2020/04/23 (木) 16:19:53 18f69@f966d

>> 1のhatenaさん提示のリンクの先にありますが

各ユーザーはフロント エンド データベースのローカル コピーを使用してデータを操作します。

これ、正しくできていますか?
データベースの分割はすでにできているということですが、分割した後のフロントエンド用ACCESSファイルはサーバーの中に置いたままで、ユーザーが全員共有して同じファイルを使っていませんか?

質問には

現在は使用者全員がファイルを閉じてから、一人だけがファイルを開き修復をする

とありますので、かなり疑わしいポイントです。

3

この手の質問は、環境や運用に左右されますので、一般論でのアドバイスは難しいです。

私自身の経験からの一例として参考事例ということになります。

私の場合は下記のような環境でここ10年以上の運用でデータベースの破損はありません。

有線LANで1台のサーバーPCに8台のクライアントPCを接続
サーバーPC Windows Sever 2012 Essentials
クライアントPC Windows10 Access2013
最大同時入力人数 5人

1.同じレコードに同時にアクセスしないようにするというのは、データの追加、更新を行うPCを決めておき、その他は閲覧のみを行うように決めるという手法で良いのでしょうか?

取引先毎に担当を決めておき、データ更新、追加はその担当が行うという運用です。
担当以外のデータは閲覧のみにします。

2.更新用フォームと追加用フォームは同義ではないのでしょうか?

フォームは共通でもいいのですが、フォームのプロパティの設計を下記のように変更します。

更新用フォーム
 データ入力用 いいえ
 更新の許可 はい
 追加の許可 いいえ
 削除の許可 いいえ
 レコードロック 編集済みレコード

追加用フォーム
 データ入力用 はい
 更新の許可 はい
 追加の許可 はい
 削除の許可 はい
 レコードロック 編集済みレコード

一覧表示の閲覧は、リストボックスに表示させるか、
帳票フォームで「レコードセット」を「スナップショット」にしておきます。

3.現在6人ほどで同時使用しているデータベースを10人ほどで共有することになった場合はエラーの発生する可能性、頻度はやはり上がってしまうのでしょうか?

これについては私からはなんとも言えません。
人数が増えればその分エラー発生の可能性は高くなるような気がしますが、根拠やデータは持ち合わせてません。

4.社用パソコンのOSのアップデートを行ってから、ACCESSの起動の時間が大幅に短くなりました。会社の先輩方の言うようには、立ち上げやデータ入力の時間は大幅に短くなったが、エラーの発生回数は多くなったように感じる、とのことでした。OSのアップデートとエラーの発生回数に因果関係があったりするのでしょうか?

Access関係の掲示板やMSの情報をチェックしてますが、そのような情報は見たことはないですね。

10
OMOTI 2020/04/23 (木) 09:08:41 05554@4b4f6

度々すみません。
時刻が表示できたのですが、〇〇:〇〇:〇〇 表示になります。
クエリ(Q_作業日一覧カレンダー表示用)でも「時刻(S)」を設定しているのですが、それだけではだめですか?

9
OMOTI 2020/04/23 (木) 08:44:15 05554@4b4f6

できました!いつも本当にありがとうありがとうございます( ;∀;)

2
rYIqAoFuZQf4ClO 2020/04/22 (水) 21:34:51

返信いただきありがとうございます。
私はまだ勤続年数が短く、このソフトに触れてから日が浅い為、内容の咀嚼に時間がかかってしまい、大変恐縮なのですが、確認させてください。

まず、同時に使用する人数が多いとエラーの発生する可能性が生じてしまうのは理解しました。また、その日の就業後にバックアップ(コピー)の作成は行うようにしています。

データベースの分割利用についてはすでに導入しており、もともと施工管理の係と営業の係で同一のデータベースで情報管理をしていたものをそれぞれの課で独立させて利用しています。同時少人数は多くても6人程度です。

以下、質問なのですが

1.同じレコードに同時にアクセスしないようにするというのは、データの追加、更新を行うPCを決めておき、その他は閲覧のみを行うように決めるという手法で良いのでしょうか?

2.更新用フォームと追加用フォームは同義ではないのでしょうか?

3.現在6人ほどで同時使用しているデータベースを10人ほどで共有することになった場合はエラーの発生する可能性、頻度はやはり上がってしまうのでしょうか?

4.社用パソコンのOSのアップデートを行ってから、ACCESSの起動の時間が大幅に短くなりました。会社の先輩方の言うようには、立ち上げやデータ入力の時間は大幅に短くなったが、エラーの発生回数は多くなったように感じる、とのことでした。OSのアップデートとエラーの発生回数に因果関係があったりするのでしょうか?

1

Accessのマルチユーザー管理はOSのファイル共有を利用した簡易的なものなので、
同時アクセス数とネットワーク環境によっては、エラー(ファイル破損)が発生する可能性はあります。

いちばんいいのは、バックエンドデータベースをSQLサーバーなどのRDBMSに変更することですが、コスト的に難しい場合もあるでしょう。

Access デスクトップ データベースを共有する方法 - Access

とりあえずの対策としては、

  • データベースを分割する。
  • なるべく同じレコードに複数ユーザーが同時アクセスしないような設計にする。
  • 閲覧用フォームと更新・追加用フォームは分けて、更新フォームは更新するレコードのみ読み込む、追加用フォームは「データ入力用」プロパティを「はい」にする。(非連結フォームにするとさらに安全性が高まりますが、高度なスキルが必要です。)
  • バックエンドデータベースファイルを定期的にバックアップしておく。
  • バックエンドデータベースファイルを置いておくサーバーPCはなるべく性能の良いものにする。

1ケタ台の人数での共有ならたいていこれで安定的運用が可能です(個人的経験による感想)。

8

あっ、すみません。OpenRecordsetのSQLの方にもフィールドを追加する必要がありました。

Public Sub SetSchedule()
Dim i As Integer, rs As DAO.Recordset
    For i = 1 To 42
        Me("T" & i).Caption = ""
    Next
    Set rs = CurrentDb.OpenRecordset( _
        "SELECT 開始時間, 作業日, 略名 FROM Q_作業日一覧カレンダー表示用 WHERE " &
        "作業日>#" & FirstDay & "# AND 作業日<=#" & FirstDay + 42 & "#", _
        dbOpenForwardOnly, dbReadOnly)
    Do Until rs.EOF
        With Me("T" & rs!作業日 - FirstDay)
            .Caption = .Caption & rs!開始時間 & " " & rs!略名 & vbCrLf
        End With
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
End Sub
7
OMOTI 2020/04/22 (水) 15:42:33 05554@4b4f6

いつもありがとうございます。
背景スタイルが「普通」になっていました。すみません。「透明」に変更すると解決しました。ありがとうございます。

1.件名の前に時刻を表示したい(例 10:00 〇〇と打ち合わせ)
↑これでつまずいています。

既存のデータをしようしているので「時刻」⇒「開始時間」と変更しています。(その他も)
黄色マーカーの部分で
エラー3265  このコレクションには項目がありません。
と表示されます。

確かに「開始時間」という項目はあるのですが…

ご教示いただけませんか?

'予定表示プロシージャ
Public Sub SetSchedule()
Dim i As Integer, rs As DAO.Recordset
    For i = 1 To 42
        Me("T" & i).Caption = ""
    Next
    Set rs = CurrentDb.OpenRecordset( _
        "SELECT 作業日, 略名 FROM Q_作業日一覧カレンダー表示用 WHERE " &
        "作業日>#" & FirstDay & "# AND 作業日<=#" & FirstDay + 42 & "#", _
        dbOpenForwardOnly, dbReadOnly)
    Do Until rs.EOF
        With Me("T" & rs!作業日 - FirstDay)
            .Caption = .Caption & rs!開始時間 & " " & rs!略名 & vbCrLf
        End With
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
End Sub

6

1.件名の前に時刻を表示したい(例 10:00 〇〇と打ち合わせ)
2.件名の行間を狭めたい(複数あると枠外になって見えない為)

下記のように修正してください。
行間については、改行(vbCrLf)を一つ減らしました。
もし、行間が狭すぎる場合は、デザインビューでラベルの行間を増やして調整してください。

Public Sub SetSchedule()
Dim i As Integer, rs As DAO.Recordset
    For i = 1 To 42
        Me("T" & i).Caption = ""
    Next
    Set rs = CurrentDb.OpenRecordset( _
        "SELECT 日付, 件名 FROM T_予定 WHERE " & _
        "日付>#" & FirstDay & "# AND 日付<=#" & FirstDay + 42 & "#", _
        dbOpenForwardOnly, dbReadOnly)
    Do Until rs.EOF
        With Me("T" & rs!日付 - FirstDay)
            .Caption = .Caption & rs!時刻 & " " & rs!件名 & vbCrLf
        End With
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
End Sub

しかし、最上段の左から3番目の枠が常に白色のままです。

デザインビューでそのラベルの「背景スタイル」を確認してください。「普通」になっていたら「透明」に変更してください。

5
OMOTI 2020/04/21 (火) 16:03:57 05554@4b4f6

すみません!!
3.過去日の内容も表示しておきたい
は無視してください

1.件名の前に時刻を表示したい(例 10:00 〇〇と打ち合わせ)
2.件名の行間を狭めたい(複数あると枠外になって見えない為)
3.過去日の内容も表示しておきたい

4
OMOTI 2020/04/21 (火) 15:50:08 05554@4b4f6

カレンダー形式のスケジュール管理フォーム作成 その2

の部分について教えてください。
クリックした日付の背景色を変更することはできました。
しかし、最上段の左から3番目の枠が常に白色のままです。(月を変更しても その部分だけ白色のまま)
どこで間違えたのでしょうか…

ご教授いただけませんでしょうか…

'フォーム 開くとき
Private Sub Form_Open(Cancel As Integer)
Dim i As Integer

    For i = 1 To 42
        Me("T" & i).OnClick = "=SetDate(" & i & ")"
    Next
    Me.cmdprev.OnClick = "=MoveMonth(-1)"
    Me.cmdNext.OnClick = "=MoveMonth(1)"
    Me.txtdate = Date
    SetCalendar
End Sub

Private Function MoveMonth(n As Integer)
    Me("T" & Me.txtdate - FirstDay).BackStyle = 0 '透明
    Me.txtdate = DateAdd("m", n, Me.txtdate)
    SetCalendar
    DoEvents
End Function

Private Function SetDate(i As Integer)
    Me("T" & Me.txtdate - FirstDay).BackStyle = 0 '透明
    Me.txtdate = FirstDay + i
    Me("T" & i).BackStyle = 1
End Function

3
OMOTI 2020/04/21 (火) 15:34:14 05554@4b4f6

いつもありがとうございます。
数カ所分からないところがあるので、教えてください。

1.件名の前に時刻を表示したい(例 10:00 〇〇と打ち合わせ)
2.件名の行間を狭めたい(複数あると枠外になって見えない為)
3.過去日の内容も表示しておきたい

よろしくお願い致します。

'予定表示プロシージャ
Public Sub SetSchedule()
Dim i As integer, rs As DAO.Recordset
    For i = 1 To 42
        Me("T" & i).Caption = ""
    Next
    Set rs = CurrentDb.OpenRecordset( _
        "SELECT 日付, 件名 FROM T予定 WHERE " &
        "日付>#" & FirstDay & "# AND 日付<=#" & FirstDay + 42 & "#", _
        dbOpenForwardOnly, dbReadOnly)
    Do Until rs.EOF
        With Me("T" & rs!日付 - FirstDay)
            .Caption = .Caption & rs!件名 & vbCrLf & vbCrLf
        End With
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
End Sub

29
フック船長 2020/04/17 (金) 10:38:47 修正 f3309@726d9

皆様お久しぶりです。
いろいろとありがとうございました。
特にmayu様、hiroton様、本当にありがとうございました。

作っていただきました構文を業務で使わせていただいております。
やっていく中で改善点があり、またこちらのサイトで教えていただくことがあるかと思います。
その際はよろしくお願いします。

上段で期首在庫が必要かという質問がありましたので私の見解を伝えさせていただきます。
私自身、簿記を勉強した経験(3級取得ですが…)から、先入先出法の考え方を持っております。
テーブルには入ってませんがで入庫単価(仕入単価)・出庫単価(売上単価)のフィールドを作り、
クエリで入庫金額、出庫金額(売上金額)、期首前在庫単価、期首前在庫価格を作れば
物の流れやお金の流れが分かりやすくなるのではないかと思ったからです。
いずれはここまでもっていけたらと思っていますが……

参考サイト
https://petit-blog.com/boki/shikurikurishi/

2
OMOTI 2020/04/16 (木) 10:16:45 05554@4b4f6

早速のお返事ありがとうございます。
無事、設定することができました。
本当にありがとうございました。

12
うしねこ 2020/04/15 (水) 23:28:24 482a1@8a5c8

hirotonさん
hatenaさん

理想どおりに動きました!!

まだよく理解できていない部分も多いので、
リンク先をよく見て勉強します。
本当にありがとうございました。

1
hatena 2020/04/15 (水) 20:26:18 修正

下記のように変更すればいいでしょう。

'カレンダー 日にち設定関数
Private Function SetCalendar()
Dim i As Integer, D As Date, m As Integer, n As Integer

  m = Me.月
  FirstDay = DateSerial(Me.年, m, 1)
  FirstDay = FirstDay - Weekday(FirstDay)
  For i = 1 To 42
    With Me("D" & i)
      D = FirstDay + i
      .Caption = Day(D)
      .ControlTipText = Nz(DLookup("備考","T_休日","日付=#" & D & "#")) '※ 休日の備考をヒントテキストに設定
      If .ControlTipText = "【A】" Then 
              .ForeColor = vbGreen '【A】は文字色 緑
      ElseIf Weekday(D) = 7 Or .ControlTipText = "【B】" Then
        .ForeColor = vbBlue  '土曜または【B】は文字色 青
      ElseIf Weekday(D) = 1 Or .ControlTipText <> "" Then '※
        .ForeColor = vbRed  '日曜または祝日は文字色 赤
      Else
        .ForeColor = vbBlack
      End If
      n = Month(D)
      If m = n Then
        .FontSize = 11
      Else
        .FontSize = 8 '月が異なるときは文字を小さく
      End If
    End With
    Me("T" & i).Caption = ""
  Next

End Function
16

メインのVBAコード

Sub 月次移動平均計算()
    Const c_開始月 = 7

    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    
    Dim 月順(11) As String
    Dim i As Long
    Dim 前月数量 As Long
    Dim 前月金額 As Double
    Dim 仕入数量 As Long
    Dim 仕入金額 As Double
    Dim 払出数量 As Long
    Dim 払出金額 As Double
    
    'ループ処理したいので月の並びを配列に確保'
    For i = 0 To 11
        月順(i) = (c_開始月 + i - 1) Mod 12 + 1 & "月"
    Next
    '--(ここまで)--'

    Set db = CurrentDb
    
    '下処理クエリ実行'
    db.Execute "Q月次移動平均表Clear"
    db.Execute "Q月次移動平均基礎データ作成"
    '--(ここまで)--'
    
    Set rs = db.OpenRecordset("T月次移動平均表")
    
    Do Until rs.EOF
        rs.Edit
        
        '移動平均計算'
        前月数量 = Nz(rs!期首数量, 0)
        前月金額 = Nz(rs!期首金額, 0)
        For i = 0 To 11
            仕入金額 = Nz(rs(月順(i) & "仕入金額"), 0)
            仕入数量 = Nz(rs(月順(i) & "仕入数量"), 0)
            払出数量 = Nz(rs(月順(i) & "売上数量"), 0)
            
            If 前月数量 + 仕入数量 = 0 Then
                払出金額 = 0
            Else
                払出金額 = (前月金額 + 仕入金額) / (前月数量 + 仕入数量) * 払出数量
            End If
            前月金額 = 前月数量 + 仕入金額 - 払出金額
            
            rs(月順(i) & "払出金額") = 払出金額
            rs(月順(i) & "金額") = 前月金額
            
            前月数量 = Nz(rs(月順(i) & "数量"), 0)
        Next
        '--(ここまで)--'
        
        rs.Update
        rs.MoveNext
    Loop
    
    rs.Close
    db.Close
    Set rs = Nothing
    Set db = Nothing
End Sub

変数の型(平均計算で小数点以下がでる)のと/ (前月数量 + 仕入数量)があるのでそこの条件判断をしてあげないといけないかなぁという感じ
計算部分はちょっと自信ないので出力結果が正しいかは十分にテストしてください

テーブル、クエリ、VBAと使うものが多いのでフィールド名を変えたりする場合はよく見てください

ワークテーブルを使う方法は実行する度にACCESSファイルが肥大化するので適宜、最適化が必要になると思います。大本のデータとはファイルを分けてリンクテーブルで拾うようにするといいかな?

いろいろ手間な部分もあるのでhatenaさんの方法でうまくいけばそれでいいんじゃないかな。とも

15
hiroton 2020/04/15 (水) 16:06:05 079da@f966d

VBAを使う方法ってことでつらつらと

まずは下準備から
データ出力用のテーブルを用意します。
T月次移動平均表

フィールド名
商品ID
商品名
期首数量
期首金額
7月仕入数量
7月仕入金額
7月売上数量
7月払出金額
7月数量
7月金額

本来出力したかったクエリの全フィールドを持ったテーブルです。データ型は適宜設定してください。
各月の「払出金額」と「金額」は平均の処理が入るから倍精度浮動小数点型になるのかな?

データ処理用のクエリを用意します(2つ)
Q月次移動平均表Clear

DELETE T月次移動平均表.*
FROM T月次移動平均表;

ワークテーブルを使いまわすので処理前にまっさらにするようクエリです。

Q月次移動平均基礎データ作成

INSERT INTO T月次移動平均表
SELECT *
FROM (
	SELECT q.商品ID, Max( q.商品名) AS 商品名, Sum( IIf( 月 = -1, 仕入数量)) AS 期首数量
	, Sum( IIf( 月 = -1, 仕入金額)) AS 期首金額
	, Sum( IIf( 月 = 0, 仕入数量)) AS 7月仕入数量, Sum( IIf( 月 = 0, 仕入金額)) AS 7月仕入金額, Sum( IIf( 月 = 0, 売上数量)) AS 7月売上数量, Sum( IIf( 月<= 0, 仕入数量 - 売上数量)) AS 7月数量
	, Sum( IIf( 月 = 1, 仕入数量)) AS 8月仕入数量, Sum( IIf( 月 = 1, 仕入金額)) AS 8月仕入金額, Sum( IIf( 月 = 1, 売上数量)) AS 8月売上数量, Sum( IIf( 月<= 1, 仕入数量 - 売上数量)) AS 8月数量
	, Sum( IIf( 月 = 2, 仕入数量)) AS 9月仕入数量, Sum( IIf( 月 = 2, 仕入金額)) AS 9月仕入金額, Sum( IIf( 月 = 2, 売上数量)) AS 9月売上数量, Sum( IIf( 月<= 2, 仕入数量 - 売上数量)) AS 9月数量
	, Sum( IIf( 月 = 3, 仕入数量)) AS 10月仕入数量, Sum( IIf( 月 = 3, 仕入金額)) AS 10月仕入金額, Sum( IIf( 月 = 3, 売上数量)) AS 10月売上数量, Sum( IIf( 月<= 3, 仕入数量 - 売上数量)) AS 10月数量
	, Sum( IIf( 月 = 4, 仕入数量)) AS 11月仕入数量, Sum( IIf( 月 = 4, 仕入金額)) AS 11月仕入金額, Sum( IIf( 月 = 4, 売上数量)) AS 11月売上数量, Sum( IIf( 月<= 4, 仕入数量 - 売上数量)) AS 11月数量
	, Sum( IIf( 月 = 5, 仕入数量)) AS 12月仕入数量, Sum( IIf( 月 = 5, 仕入金額)) AS 12月仕入金額, Sum( IIf( 月 = 5, 売上数量)) AS 12月売上数量, Sum( IIf( 月<= 5, 仕入数量 - 売上数量)) AS 12月数量
	, Sum( IIf( 月 = 6, 仕入数量)) AS 1月仕入数量, Sum( IIf( 月 = 6, 仕入金額)) AS 1月仕入金額, Sum( IIf( 月 = 6, 売上数量)) AS 1月売上数量, Sum( IIf( 月<= 6, 仕入数量 - 売上数量)) AS 1月数量
	, Sum( IIf( 月 = 7, 仕入数量)) AS 2月仕入数量, Sum( IIf( 月 = 7, 仕入金額)) AS 2月仕入金額, Sum( IIf( 月 = 7, 売上数量)) AS 2月売上数量, Sum( IIf( 月<= 7, 仕入数量 - 売上数量)) AS 2月数量
	, Sum( IIf( 月 = 8, 仕入数量)) AS 3月仕入数量, Sum( IIf( 月 = 8, 仕入金額)) AS 3月仕入金額, Sum( IIf( 月 = 8, 売上数量)) AS 3月売上数量, Sum( IIf( 月<= 8, 仕入数量 - 売上数量)) AS 3月数量
	, Sum( IIf( 月 = 9, 仕入数量)) AS 4月仕入数量, Sum( IIf( 月 = 9, 仕入金額)) AS 4月仕入金額, Sum( IIf( 月 = 9, 売上数量)) AS 4月売上数量, Sum( IIf( 月<= 9, 仕入数量 - 売上数量)) AS 4月数量
	, Sum( IIf( 月 = 10, 仕入数量)) AS 5月仕入数量, Sum( IIf( 月 = 10, 仕入金額)) AS 5月仕入金額, Sum( IIf( 月 = 10, 売上数量)) AS 5月売上数量, Sum( IIf( 月<= 10, 仕入数量 - 売上数量)) AS 5月数量
	, Sum( IIf( 月 = 11, 仕入数量)) AS 6月仕入数量, Sum( IIf( 月 = 11, 仕入金額)) AS 6月仕入金額, Sum( IIf( 月 = 11, 売上数量)) AS 6月売上数量, Sum( IIf( 月<= 11, 仕入数量 - 売上数量)) AS 6月数量
	FROM (
		SELECT 商品ID, 商品名, -1 AS 月, 期首数量 AS 仕入数量, 期首金額 AS 仕入金額, 0 AS 売上数量, 0 AS 売上金額
		FROM t商品マスタ, t決算日
		union all
		SELECT 仕入商品ID, "", ( month( 仕入日) + 5) mod 12, 仕入数量, 仕入単価 * 仕入数量, 0, 0
		FROM t仕入明細, t決算日
		WHERE 仕入日 Between DateAdd( "yyyy", -1, 決算日 + 1) And 決算日
		union all
		SELECT 売上商品ID, "", ( month( 売上日) + 5) mod 12, 0, 0, 売上数量, 売上単価 * 売上数量 FROM t売上明細, t決算日
		WHERE 売上日 Between DateAdd( "yyyy", -1, 決算日 + 1) And 決算日
	) AS q
	GROUP BY q.商品ID
);

各月の「払出金額」と「(集計)金額」を除いた基礎となるデータを追加クエリでワークテーブルに追加するクエリです。