Microsoft Access 掲示板

views
4 フォロー
6,283 件中 4,121 から 4,160 までを表示しています。
4
よし 2021/01/13 (水) 00:58:22 d9508@7e9fa

hiroton様の投稿内容でも試してみましたが、うまく動作しませんでした。
HTMLでのカラーコードはRGBの順ですが、VBAでの10進数のカラーコードをhex関数で16進数に変換すると、
何となくですがBGRの順で出てきます。
VBAは内部的に色をBGRの順で計算しているのでしょうか。
考えていると頭が混乱してきました。

参考画像を貼っておきます。アドバイスを頂いたお二方、本当にありがとうございました。

3
よし 2021/01/13 (水) 00:02:09 d9508@7e9fa

年末年始の繁忙期のため、お礼が遅くなり申し訳ございません。

以前投稿されていた、詳細_paintイベントを使う方法でうまいこと動いてくれました。
お教え頂いた方に感謝申し上げます。

カラーコードのテキストボックスを txt_ColorCode、
色を表示したいラベルを Lbl_info とします。

Private Sub 詳細_Paint()
    If Nz(Trim(txt_ColorCode), vbNullString) <> vbNullString Then
        Me.Lbl_info.BackStyle = 1
        Me.Lbl_info.BackColor = txt_ColorCode
    Else
        Me.Lbl_info.BackStyle = 0
    End If
End Sub

これで色を表示させることが出来ました。ありがとうございました。

6

集計結果を表示出来ない原因が参照先のクエリが開けなくなっていだ事が原因だと分かりました。社内SEが式に合わせる為、フィールド名を変更していた様で何処かでバグが起きて開けなくなっていました。開けるクエリと置き換え式のフィールド名を変えた所表示できました。今までと違い違うパソコンからそのクエリを開こうとするとodbc接続に失敗しましたというエラーがでたり色々分からない事が多いですが取り敢えず集計ボックス表示はできたので助かりますました。有難う御座いました。

2
nokonoko 2021/01/12 (火) 18:21:54 653a6@54883

ありがとうございました。

ご回答をもとに組み立てることができました。
MT_年月を前もって作成しておくのは、長期運用しにくいので、
自力で解決策を考えてみます。
(困ったら、また質問させていただきます

2
おもち 2021/01/12 (火) 10:21:17 0029a@1c915

Accessの問題ではなかったんですね。権限の問題で、表示スケールがいじれないのですが、Accessのせいではないということがわかって助かりました。ありがとうございます。

1

また、かなり可能性が低いですが、生産が止まった月があった場合、列も表示されません。
これは対処できるのでしょうか?

これに対応するには、出力したいすべての年月を格納するテーブルが必要になりますね。
下記のようなテーブルを作成してください。

テーブル名 MT_年月

年月
2020年01月
2020年02月
2020年03月
2020年04月


一つのクエリでは難しいので、複数のクエリを組み合わせて目的に出力になるようにしていきます。

Q_商品_年月

SELECT MT_商品.商品ID, MT_年月.年月
FROM MT_商品, MT_年月;

このクエリですべての商品IDと年月の組み合わせが出力できます。


Q_商品年月別計

SSELECT
 T_生産.商品ID,
 Format([生産日],"yyyy\年mm\月") AS 年月,
 Sum(T_生産.生産量) AS 生産量計
FROM T_生産
GROUP BY T_生産.商品ID, Format([生産日],"yyyy\年mm\月");

このクエリで、商品別年月別の生産量の合計が出力できます。


上記の2つのクエリから下記のようなクロス集計クエリを作成します。
CQ_商品年月別

TRANSFORM Nz(First([生産量計]),0) AS 値
SELECT Q_商品_年月.商品ID
FROM
 Q_商品_年月 LEFT JOIN Q_商品年月別計
 ON (Q_商品_年月.年月 = Q_商品年月別計.年月) AND (Q_商品_年月.商品ID = Q_商品年月別計.商品ID)
GROUP BY Q_商品_年月.商品ID
PIVOT Q_商品_年月.年月;

これでご希望の結果になると思います。

1

OSのディスプレイの表示スケールの設定を標準から変更してないでしょうか。
もし、しているなら 100% に戻したらどうなりますか。

Windows 10でディスプレイの表示スケールの設定を変更して見やすくする:Tech TIPS - @IT

2
どんぐり 2021/01/05 (火) 14:16:42 ef15c@e2de4 >> 1

なるほど…簡単なことが思いつかずお手数をおかけしてしまいました。申し訳ありません。
ご回答ありがとうございました!

1

現在の仕様だと、企業テーブルにデータが存在していないものも
企業IDが空欄として問題なく処理されてしまいます。

更新クエリの抽出条件で企業テーブルにデータが存在していないものを除外するようにすればいいのでは。

これで分からなければ、現状の更新クエリのSQLと各テーブルの主キーフィールドを提示してください。

3
hiroton 2021/01/05 (火) 12:00:47 dfd95@f966d

締日は普通、情報は日付のみでは?

請求日 支払い条件1(20日締め翌月末) 支払い条件2(締め翌月末)
締日 支払日 締日 支払日
2021/1/20 2021/1/20 2021/2/28 2021/1/31 2021/2/28
2021/1/21 2021/2/20 2021/3/31 2021/1/31 2021/2/28

支払条件には月の区切りとする日(締日)と、支払いに関する日付(担当者が入金処理をする日)の2つの日付の情報が含まれるものです(支払いの方法(現金、手形等)も記述されるものですが今回は省略)

例外としては
前払い(初回取引のためだったり)
請求後30日(「締日」を定めない。日本の企業ではまずない)
なんかもありますね

さておき、「1か月後末日」では何を計算したいのかわかりません。「締日」の月が変わるのは「請求日」と「締日」の関係からであって、「1か月」という情報は関係ありません。記述の仕方からすると「締日」に関する情報が不足のようにみえます
支払日を求めたいのであっても、上記のように「締日」の条件で月が変わるため情報不足です


いずれにせよhatenaさん指摘のようにデータベース上では計算しやすい数値としてフィールドに分けて保存するのが基本で、
締日日(末締めは0)
支払月間
支払日日(末日は0)
の3つのフィールドを持つといいでしょう

締日: DateSerial(Year([請求日]),Month([請求日])+IIf(Day([請求日])>[締日日],1,0),[締日日])
支払日: DateSerial(Year([締日]),Month([締日])+[支払月間]+IIf([支払日日]=0,1,0),[支払日日])

Trueの扱いについて
hatenaさんの式の-([締日日]=0)は面白いなぁと思います。hirotonの式では+IIf([支払日日]=0,1,0)と記述しました。どちらも同じ結果になるのでどちらでもいいです。ただし、ACCESSなら

こんぴゅうたぁのはなし になるのですが、ACCESSで適当なフォームを作り、テキストボックスを配置してコントロールソースを=Date()+Trueとします。つぎに、Excelを立ち上げて適当なセルに=TODAY()+TRUEとしてみます。結果はご覧あれ

テクニックとしてどこまで許容するかという話になるんですが、真偽値をそのまま計算に使うのは上記のようにそれなりの知識が必要になるのでオススメしません

2
トマト 2021/01/05 (火) 09:47:58 ef15c@e2de4 >> 1

大変参考になりました!ありがとうございます。

>蛇足ですが、こういう並び順はユーザーフレンドリーでないので

おっしゃる通りで、並び順自体スッキリしないなと、ずっと感じています。。
どなたか並び順のアイデアがあれば、ご教示いただけると非常に助かります。

1
hiroton 2021/01/05 (火) 08:50:08 dfd95@f966d

優先順のグループ分けを3通りにする

式: IIf([契約更新日]<DateAdd("m",2,Date()),1,IIf([契約状況]<>"契約中",2,3))

IIfのネストは見づらくなるのでSwitch 関数でもいいですね

式: Switch([契約更新日]<DateAdd("m",2,Date()),1,[契約状況]<>"契約中",2,True,3)

蛇足ですが、こういう並び順はユーザーフレンドリーでないので、フォーム上に並び順に関する注釈が欲しくなります

2
おもち 2021/01/04 (月) 10:08:19 9f0f1@e2de4

なるほど…!イメージがわきました。
作ってみて、またわからなければ質問させていただきます。
ありがとうございました!

5

インポートもテーブルをインポートする際、接続エラーがでて一部のテーブルしかインポート出来ません。

リンクテーブルでリンクできているなら、接続エラーにならずにインポートできると思います。
インポートがだめなら、リンクテーブルから追加クエリでローカルテーブルにデータ追加すればいいでしょう。

確実に動きそうなexcelにdaoでエクスポートを思い付きました。

daoで接続できるなら、エクスポート先はExcelでもAccessでも同じことでは?

4

テーブルは、恐らくオラクルとのリンクテーブルになっており多くの端末で共有していると思います。ですので一個人の為にテーブルデザインを変える事は出来ません。私は、会社のシステムを扱う部署にいない為詳しく分かりませんが、オラクルサーバーのテーブルそのものを全く違うテーブルに変更しています。タスクマネージャーでは、何か分からない大量のタスクが夕方から昼にかけて起動しています。office 2000 からoffice2016に代わり負荷が掛かってレスポンス低下を招いている事も一因です。インポートもテーブルをインポートする際、接続エラーがでて一部のテーブルしかインポート出来ません。今は、私の作ったマクロが動かない為、事務の方がexcelにクエリをコピペしてsumで集計しています。この状況を打開する為、確実に動きそうなexcelにdaoでエクスポートを思い付きました。
もっと簡単な方法が有れば良いのですが。

3

リンクを貼るのを忘れてました。前回の回答にリンクを追記しておきましたのでご参照ください。

ただし、この方法はテーブルに集計値格納用のフィールドを追加する方法ですので、共有しているファイルでテーブルデザインの編集ができる必要があります。

いままで、普通に使えていたのが、「会社のシステム変更」により著しく遅くなったとしたら、どのような変更をしたのか、それがどのように影響しているのか、の確認がまずは必要でしょう。

2

ネットワーク上で共有しています。プロパティにオンラインとなっていた為、オンラインなのかと思っていました。フォームのボタンに集計結果をダイアログボックスに表示するコードを入れてありこのコードを再利用したいと思っています。となると後者の方法でしょうか?また、更新クエリを使う場合の方法のリンク先を貼って下さると助かります。宜しくお願い致します。

1

締日定義を「1か月後末日」とすると、条件分岐が面倒です。(できないことはないですが)

下記のようにすれば、簡単に締め日を式で計算できます。

「会社情報テーブル」に下記のフィールドを持たせます。
締日日 数値型
締日月後 数値型

例えば、締め日が「1か月後20日」なら、
締日日: 20
締日月後: 1
と入力します。
「1か月後末日」なら、
締日日: 0
締日月後: 1
とします。

末日の場合は、締日日を0とします。

請求リストフォームのレコードソースのテーブルからクエリを作成して、フィールド欄に下記の式を設定すれば締日か表示されます。

締日: DateSerial(Year([請求日]),Month([請求日])+[締日月後]-([締日日]=0),[締日日])

このクエリをフォームのレコードソースにして、締め日のテキストボックスのコントロールソースを「締日」とすれば請求日を入力すれば締日が表示されます。

1
hatena 2021/01/03 (日) 11:56:55 修正

mdbファイルはオンラインですので、

オンラインとは具体的にどのようなことでしょうか。
イントラネット上にあるということでしょうか。

DSum, DCount は重たい処理ですので(特にネットワーク上で共有している場合)、別の方法を検討された方がいいでしょう。

例えば、下記のリンク先の方法で更新クエリで集計値をテーブルに格納しておくとか。

更新クエリで定義域集計関数を使わずに集計する - hatena chips

あるいは、必要なデータをローカルにテーブルとしてインポートして利用するとか。(わざわざエクセルにする必要はないでしょう。メリットは何もありません。)

1
hatena 2020/12/28 (月) 16:07:49 修正

たぶん、テーブル設計が間違っていると思います。データベースでは同じデータを複数個所に格納するということはしません。
関連性のあるデータは関連付けて簡単に引っ張ってくることができますので。

とりあえず、テーブルAとテーブルBの主なフィールド名、主キー設定を提示してもらえますか。

4
名前なし 2020/12/27 (日) 18:25:57 8b661@ce856

まさにその通りです!返信ありがとうございました!

3
おか。 2020/12/27 (日) 12:51:21 31438@cab8e

FileName = Left(CurrentDb.Name, InStrRev(CurrentDb.Name, "¥")) & "総務部¥物品要求書.xls"
赤文字のところを付け加えました。
これでいかかでしょうか?

2
鉄血 2020/12/27 (日) 11:57:02 43d60@ce856

連投失礼します。半角「\」が投稿時に「/」になってしまいました。


                   & "物品要求書.xls"

                   & "総務部¥物品要求書.xls"

1
鉄血 2020/12/27 (日) 11:55:04 43d60@ce856

自己解決しました!
以下の修正でできました。よく考えたらシンプルにパス記述を
考えるべきだったんですね。
お騒がせしました。


                   & "物品要求書.xls"

                   & "総務部\物品要求書.xls"

9
ゲッキョク駐車場 2020/12/26 (土) 08:35:51 cb55f@f6500

ありがとうございます。

とりあえず、通常通りの操作であれば問題なく動くようにした状態まで
もっていってから、フォームを分ける用に変えていきたいと思います。
(本格的に変えていくのは新年からとなると思いますが)

フォームの更新前処理の条件式や、フォーム構成なども見直す方向で
考えていきたいと思います。

本当にありがとうございます!

8
hiroton 2020/12/25 (金) 17:13:20 ca77e@f966d

ちなみに、>> 5が微妙な書き方なのは、このような処理を考えるとドツボにはまるからです。(本当にやりたいことは別なのに)BeforeUpdateCancel = Trueしたいがためだけに

閉じるときに更新前処理をキャンセルすると出るメッセージを変更(hatena chipsさん)

こんな処理考えるくらいなら

都合により、データの閲覧と編集を同じフォームで行っています。
(フォームを分けるという理解を得られていない為、これは変更できなさそうです)

これの要求を整理して、メニューに編集用、閲覧用2つボタン置く形じゃダメなの?とかの方向性を考えたほうがよっぽど建設的です

7
hiroton 2020/12/25 (金) 16:48:44 ca77e@f966d >> 6

理想の運用ならそれでいいと思いますが、フォームって予期せぬ閉じ方をされるんですよね
フォーム右上の×をクリックされたり(非表示にできるので何とかなる)、ACCESS本体の右上の×をクリックされたり(本体の表示をしない方法があるので何とかなる)、タスクバーから終了されたり、タスクマネージャーから強制終了されたり・・・

なので、実際にデータが決定されるタイミング(BeforeUpdate)で内容を決めましょう。という話です

Private Sub Form_BeforeUpdate(Cancel As Integer)
  If (保存しない条件) Then Cancel = True
End Sub

こうしておけば、どのような形でフォームが閉じられてもBeforeUpdateイベントを通るので保存内容の確認ができます

6
ゲッキョク駐車場 2020/12/25 (金) 16:07:41 修正 cb55f@f6500

毎度、手取り足取り本当にありがたいです。

Dirtyは、開いてないと使えないヨ、くらいしか知識が無かったので
Syscmdも有効活用していきたいと思います!
ありがとうございます…!
まだまだイベントのタイミングがうまくつかめていないので、
その部分についてももう一度勉強しなおしてみようと思います。

また、部品フォームのDirty部分なんですが、以下のような形にしました。

Private Sub 部品F閉ボタン_click()

  If Me.Dirty Then
    If MsgBox("データが変更されています。保存して終了しますか?", vbYesNo) = vbNo Then
      Exit Sub

    Else
      Me.BeforeUpdate = ""  'キャンセル無効
      DoCmd.RunCommand acCmdSaveRecord
      'DoCmd.RunCommand acCmdRefresh
      Me.BeforeUpdate = "[イベント プロシージャ]"  'キャンセル有効

      Call UserLog("MNFCT", "Update")
    End If
  End If

  DoCmd.Close
End Sub

メインフォームの方はこのように

Private Sub 終了ボタン_Click()
  On Error GoTo ErrHandler

  If SysCmd(acSysCmdGetObjectState, acForm, "F_部品") <> 0 Then
    Forms!F_部品.終了ボタン_Click
  End If

  If SysCmd(acSysCmdGetObjectState, acForm, "F_製品") <> 0 Then
    Forms!F_製品.終了ボタン_Click
  End If

  DoCmd.Quit acQuitPrompt
ErrHandler:
End Sub

SysCmdを用いた、hirotonさんの方法でなく、上記のようなものでも
今回の件については問題なく動きますでしょうか?

5
hiroton 2020/12/25 (金) 15:34:54 ca77e@f966d

とりあえず
フォームの状態を知るには?(T'sWareさん)

質問のコードを次のように変更すれば動作はすると思います

  DoCmd.OpenForm "F_部品"
↓
  If SysCmd(acSysCmdGetObjectState, acForm, "F_部品") <> 0 Then
(中略)
  End If

フォームが開いているかどうかをチェックし、開いているときに限りDirtyプロパティをチェックすれば良いということですね


根本的にデータ更新タイミングなどが間違っているということでしょうか

データの更新自体は様々なタイミングで発生します。フォームを閉じるというアクションを取った場合は、Closeイベントの前にBeforeUpdateイベントが発生し、BeforeUpdateイベントが終わると保存内容が決定されます
(実際にはもっと様々なイベントが発生します)

イベントは1つのアクションに対して連鎖的に複数発生する場合があるので、どのイベントで処理するか適切に判断する必要があります

Closeイベントの時点ではすでにデータが決定されてしまっているので、そこで保存するかどうかの確認や、再度データを変更・保存しなおすような処理はすべきではありません

「データの更新処理が済んでないうちはフォームを閉じる処理をしてはいけない」という意味で、修正しようとした内容よりも質問時点でのコードのほうが考え方が正しいです

4
ゲッキョク駐車場 2020/12/25 (金) 14:19:18 修正 cb55f@f6500 >> 3

ありがとうございます。

都合により、データの閲覧と編集を同じフォームで行っています。
(フォームを分けるという理解を得られていない為、これは変更できなさそうです)

データ編集ユーザ用に、保存ボタンや編集クリアボタン等を配置しています。
しかし、データを見るだけのつもりのユーザーが誤って一部のデータを変更し、
それに気が付かぬまま(=編集クリアボタン等を押さぬまま)フォームを
閉じようとする際(およびレコード移動する際)に、MSGBOXで警告するようにしています。

フォームはマスタテーブルをレコードソースとしており、フォーム内の
TXTBOXを変更した際に、すぐテーブル内容が書き換わってしまわないように、

Private Sub Form_BeforeUpdate(Cancel As Integer)
  Cancel = True
End Sub

としています。

根本的にデータ更新タイミングなどが間違っているということでしょうか…

3
hiroton 2020/12/25 (金) 13:35:17 ca77e@f966d

よくわからないんですが、編集(変更)したのに保存したくない場合があるんですか?

データの保存(する/しない)と、フォームを閉じるは、直接的には無関係です。変更中の内容をどうこうしたいなら更新前処理で制御すべきでしょう

2
nokonoko 2020/12/25 (金) 09:21:39 653a6@54883

ありがとうございます。
結構いじっているのに、理解できていないことが多いですね。
本年、一年お世話になりました。また来年よろしくお願いします。

2
ゲッキョク駐車場 2020/12/25 (金) 08:57:15 修正 cb55f@f6500 >> 1

お早いご返信、ありがとうございます。
前に1度、部品フォームを変えてから閉じて、メインフォームを閉じようとしたら閉じれなかった
と他の人から連絡を受けたため、このような形になっていました。
しかし、考えてみると、確かにご指摘通りへんてこりんですね…。
申し訳ありません。
MSGBOXの出現も、いろいろ試したところ、フォーム開きっぱなしの時だけでした。

部品フォームを閉じるときに、以下のようにすれば問題ないでしょうか…?

Private Sub Form_Close()

  If Me.Dirty Then
    If MsgBox("データが変更されています。保存して終了しますか?", vbYesNo) = vbNo Then
      Exit Sub

    Else
      Me.BeforeUpdate = ""  'キャンセル無効
      DoCmd.RunCommand acCmdSaveRecord
      'DoCmd.RunCommand acCmdRefresh
      Me.BeforeUpdate = "[イベント プロシージャ]"  'キャンセル有効

      Call UserLog("MNFCT", "Update")
    End If
  End If
End Sub

以上、よろしくお願いいたします。

1

これで、うっかりデータを変更しちゃってフォームを閉じちゃった際にも、
データ変更云々のメッセージを表示できるようになりました。

そもそも、これが勘違いではないでしょうか。
フォームを閉じる時に、もしレコードが更新されていたら、自動的に保存されて、Dirtyプロパティはリセットされます。
DoCmd.OpenForm "F_部品" で開いた直後、DirtyプロパティはFalseになっているはずです。

もし、「データ変更云々のメッセージを表示」のメッセージが出るなら、フォームを開く時、読み込み時、レコード移動時、、などで、レコードを更新する処理が記述されていることになります。

1
hatena 2020/12/24 (木) 22:16:12 修正

フォームBを閉じたタイミングで、フォームAの方でコードを実行したい、ということだとすると、
DoCmd.OpenForm の直後に実行したいコードを記述すればOKです。

フォームAのコマンド1のクリックでフォームBを開くとして、

Private Sub コマンド1_Click()
    DoCmd.OpenForm "フォームB", windowmode:=acDialog

    'ここにやりたい処理を書けばよい
    '例えばメッセージを表示させるなら
    MsgBox "フォームBを閉じました"

End Sub
17

元の質問は解決済みで、別の質問になると思いますので、新規に質問しなおしてください。

そのときに、何をどのように合算するのか具体的に説明するようにしてください。

3
nokonoko 2020/12/24 (木) 10:35:02 653a6@54883

最初はこんな感じでした。
[T_商品]

商品ID(キー)属性ID商品名
1  1商品45リンゴジャム
21商品3 5小女子の佃煮
33資材NullNull 丸瓶(短)
43資材NullNull丸瓶(中)
53資材NullNull丸瓶(蓋)
62原料NullNull砂糖

参照整合や連鎖更新をあきらめれば、機能します。
テーブルを分割して運用する方法がイメージがつかないです。

2
nokonoko 2020/12/24 (木) 09:44:11 653a6@54883

[T_商品]

商品ID(キー)属性IDパッケージID商品名
1  1商品2リンゴジャム
21商品1  小女子の佃煮
33資材Null丸瓶(短)
43資材Null丸瓶(中)
53資材Null丸瓶(蓋)
62原料Null砂糖

[T_パッケージ]

パッケージID(キー)パッケージ名資材ID1資材ID2
1  丸瓶(短セット)35
2丸瓶(中セット)4  5

-

T_商品テーブルという、ごちゃまぜのテーブルを作ってほうが
データ入力時にすべて同じテーブルを呼び出すだけで簡単かと思ったのですが、
属性ごとに別のテーブルを用意したほうが今になってよかったのかと思っています。

16

合算して抽出する方法ご教示お願いいたします